Вопрос или проблема
Я сталкиваюсь с очень раздражающей проблемой и хотел бы узнать, встречал ли кто-то с этим ранее.
Я использую PIC18F26K42, MPLAB 6.20, XC8 v2.50.
Проблема в том, что код работает, но иногда я добавляю строку, и он начинает вести себя странно. Он перестает работать.
Чтобы дать вам представление, вот код, который работает:
void exeCMD(void){
if(!serial.flags.endCmd) return;
serial.flags.endCmd = 0;
serial.flags.startCmd = 0;
switch(serial.cmd){
case CMD_STATUS: //----------------------------------------------
if(serial.request == REQ_WRITE){
}
else if(serial.request == REQ_READ){
serial.value = (ulong)((uint)status.cfg.value + (((uint)status.op.value) << 8));
sendCMD(serial.cmd,serial.value);
}
break;
case CMD_GET_TIME: //----------------------------------------------
if(serial.request == REQ_READ) {
serial.value = getSysTick(); // Неправильно...
sendCMD(serial.cmd,serial.value);
}
else serial.value = 0;
break;
case CMD_GET_FREQ: //----------------------------------------------
if(serial.request == REQ_READ) {
getFreq();
serial.value = (ulong)freq.atual;
sendCMD(serial.cmd, serial.value);
}
else
serial.value = 0;
break;
А вот этот код перестает работать, когда я добавляю некоторые строки:
ulong delayTime[2];
void exeCMD(void){
if(!serial.flags.endCmd) return;
serial.flags.endCmd = 0;
serial.flags.startCmd = 0;
switch(serial.cmd){
case CMD_STATUS: //----------------------------------------------
if(serial.request == REQ_WRITE){
}
else if(serial.request == REQ_READ){
serial.value = (ulong)((uint)status.cfg.value + (((uint)status.op.value) << 8));
sendCMD(serial.cmd,serial.value);
}
break;
case CMD_GET_TIME: //----------------------------------------------
if(serial.request == REQ_READ) {
serial.value = getSysTick(); // Неправильно...
sendCMD(serial.cmd,serial.value);
}
else serial.value = 0;
break;
case CMD_GET_FREQ: //----------------------------------------------
if(serial.request == REQ_READ) {
delayTime[0] = getSysTick();
getFreq();
delayTime[1] = getSysTick();
serial.value = (ulong)freq.atual;
sendCMD(serial.cmd, serial.value);
delayTime[1] = delayTime[1] - delayTime[0];
printStrNum( "T:",delayTime[1]);
}
else
serial.value = 0;
break;
Я подчеркиваю, что функции реализованы в нескольких других частях кода и не являются проблемой.
Прерывания не вызывают другие функции и являются короткими и простыми кодами.
Полный код имеет много строк. Это часть, где у меня возникла эта проблема.
Однако это поведение не ограничивается этой областью. Много раз я извлекал работающий код, и после добавления строки он переставал работать.
Поведение меняется. Иногда оно изменяет значение переменной или записывает бессмысленные строки.
Я использовал printf, но поскольку столкнулся с этой проблемой, я подумал, что это причина.
Я также использовал C99, C90, C89… Все это приводит к одной и той же проблеме.
Я действительно не знаю, в чем проблема. Я думаю, что это либо компилятор XC2.50, либо MPLAB 6.20.
Поведение меняется. Иногда оно изменяет значение переменной или записывает бессмысленные строки.
Я использовал printf, но поскольку столкнулся с этой проблемой, я подумал, что это причина.
Я также использовал C99, C90, C89… Все это приводит к одной и той же проблеме.
Я действительно не знаю, в чем проблема. Я думаю, что это либо компилятор XC2.50, либо MPLAB 6.20.
Ответ или решение
К сожалению, проблема, с которой вы сталкиваетесь, достаточно распространена при разработке на микроконтроллерах, и может быть связана с несколькими факторами. Давайте рассмотрим возможные причины и пути их решения.
Возможные причины:
-
Переполнение стека:
- При добавлении новых строк кода, особенно если это связано с вызовами функций, вы можете превышать предел стека. Проверьте размер стека и, если необходимо, увеличьте его.
-
Инициализация переменных:
- Убедитесь, что все глобальные и статические переменные инициализированы перед использованием. Проблемы могут возникать из-за использования неинициализированных переменных.
-
Конфликт в выделении памяти:
- При изменениях в коде, вызывающих больше операций с памятью, вы можете столкнуться с утечками памяти или неправильным доступом к областям памяти. Проверьте, не пересекаются ли области памяти ваших переменных. Используйте инструменты для анализа памяти, если они доступны.
-
Ошибки в логике:
- Иногда добавление новых строк кода может повлиять на предшествующую логику. Проверьте, задействует ли новый код старые переменные ввода-вывода или переменные состояния, которые могут привести к несовместимости.
-
Проблемы с компилятором:
- Вы упоминали, что используете XC8 v2.50 и MPLAB 6.20. Возможно, стоит попробовать обновить версии компилятора и IDE до более новых, так как у них могут быть исправления ошибок и улучшения, которые решают вашу проблему.
-
Оптимизация компилятора:
- Попробуйте отключить оптимизацию в настройках компиляции. Иногда оптимизирующий компилятор может неправильно интерпретировать ваш код, особенно если в нем есть нестандартные или неочевидные конструкции.
-
Проверка функций:
- Убедитесь, что функции, такие как
getSysTick()
иgetFreq()
, корректно работают и не вызывают побочных эффектов. Проверьте их реализацию на наличие нестабильных участков кода.
- Убедитесь, что функции, такие как
Рекомендации по исправлению:
-
Логирование:
Добавьте вывод значений переменных и состояний в критических точках кода для отслеживания течения выполнения программы и выявления точек, где возникают проблемы. -
Дебаг:
Используйте дебаггер для пошагового выполнения кода, чтобы понять, в какой момент возникают проблемы. -
Минимизация кода:
Упростите и минимизируйте код до тех пор, пока проблема не исчезнет. Это поможет определить тот участок кода, который вызывает проблему. -
Эксперименты:
Проверьте различные конфигурации компилятора и параметры настройки, чтобы увидеть, изменится ли поведение программы.
Если вы выполните все эти шаги и все равно не сможете выявить проблему, возможно, стоит рассмотреть возможность обращения на форумы или службу поддержки, предоставляющую инструменты, которые вы используете. Удачи вам в решении проблемы!