Проблемы с компилятором XC8 и PIC18: Софт перестает работать без видимой причины

Вопрос или проблема

Я сталкиваюсь с очень раздражающей проблемой и хотел бы узнать, встречал ли кто-то с этим ранее.

Я использую 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.

Ответ или решение

К сожалению, проблема, с которой вы сталкиваетесь, достаточно распространена при разработке на микроконтроллерах, и может быть связана с несколькими факторами. Давайте рассмотрим возможные причины и пути их решения.

Возможные причины:

  1. Переполнение стека:

    • При добавлении новых строк кода, особенно если это связано с вызовами функций, вы можете превышать предел стека. Проверьте размер стека и, если необходимо, увеличьте его.
  2. Инициализация переменных:

    • Убедитесь, что все глобальные и статические переменные инициализированы перед использованием. Проблемы могут возникать из-за использования неинициализированных переменных.
  3. Конфликт в выделении памяти:

    • При изменениях в коде, вызывающих больше операций с памятью, вы можете столкнуться с утечками памяти или неправильным доступом к областям памяти. Проверьте, не пересекаются ли области памяти ваших переменных. Используйте инструменты для анализа памяти, если они доступны.
  4. Ошибки в логике:

    • Иногда добавление новых строк кода может повлиять на предшествующую логику. Проверьте, задействует ли новый код старые переменные ввода-вывода или переменные состояния, которые могут привести к несовместимости.
  5. Проблемы с компилятором:

    • Вы упоминали, что используете XC8 v2.50 и MPLAB 6.20. Возможно, стоит попробовать обновить версии компилятора и IDE до более новых, так как у них могут быть исправления ошибок и улучшения, которые решают вашу проблему.
  6. Оптимизация компилятора:

    • Попробуйте отключить оптимизацию в настройках компиляции. Иногда оптимизирующий компилятор может неправильно интерпретировать ваш код, особенно если в нем есть нестандартные или неочевидные конструкции.
  7. Проверка функций:

    • Убедитесь, что функции, такие как getSysTick() и getFreq(), корректно работают и не вызывают побочных эффектов. Проверьте их реализацию на наличие нестабильных участков кода.

Рекомендации по исправлению:

  • Логирование:
    Добавьте вывод значений переменных и состояний в критических точках кода для отслеживания течения выполнения программы и выявления точек, где возникают проблемы.

  • Дебаг:
    Используйте дебаггер для пошагового выполнения кода, чтобы понять, в какой момент возникают проблемы.

  • Минимизация кода:
    Упростите и минимизируйте код до тех пор, пока проблема не исчезнет. Это поможет определить тот участок кода, который вызывает проблему.

  • Эксперименты:
    Проверьте различные конфигурации компилятора и параметры настройки, чтобы увидеть, изменится ли поведение программы.

Если вы выполните все эти шаги и все равно не сможете выявить проблему, возможно, стоит рассмотреть возможность обращения на форумы или службу поддержки, предоставляющую инструменты, которые вы используете. Удачи вам в решении проблемы!

Оцените материал
Добавить комментарий

Капча загружается...