Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту


 
Опции темы

Программа уходит в HardFault (STM32)

Непрочитано 21.05.2013, 17:02  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Программа уходит в HardFault (STM32)

Добрый день.
Прошу помощи по следующей проблеме.
Контроллер STM32F207
Программа крутится на freeRTOS. Используются очереди.
И периодически контроллер уходит на HardFault.

Обработчик прерывания таймер захвата, настроен на захват обеих фронтов, получает 2 значения вычисляет разницу между ними, записывает в очередь
PHP код:
void TimerSystemSensorIRQ(void)
{ 
  __IO uint32_t   ch_flag[Q_CH] = {0,0,0,0};
  __IO uint32_t   i;
  static uint32_t ICReadValue[Q_CH][2];
  portBASE_TYPE   res = 0;

  if(TIM4-›SR & TIM_IT_CC1) 
  {
    TIM4-›SR = (uint16_t)~TIM_IT_CC1; //Clear flag interrupt
    ICReadValue[CH11][CaptureNumber[CH11]] = TIM4-›CCR1;
    ch_flag[CH11] = 1;
    
    if(!CaptureNumber[0]) //первое измерение
    {
      CaptureNumber[0] = 1;
      CapturePWValue[0] = 0;
    }
    else
    {
      CaptureNumber[0] = 0;
      if(ICReadValue[CH11][1] ›= ICReadValue[CH11][0])
        CapturePWValue[CH11] = ICReadValue[CH11][1] - ICReadValue[CH11][0];
      else
        CapturePWValue[CH11] = ((MAX_TIMER_VALUE - ICReadValue[CH11][0]) + ICReadValue[CH11][1]);
      res = xQueueSendFromISR(CaptPWQueue[CH11], &CapturePWValue[CH11], 0);// send queue
    }
  }
  TIM4-›SR = 0;
} 
Задача читает значения из очереди пишет их в структуру генерирует события
PHP код:
void SSReadPW(LOOP_TypeDef ch, TYPE_SS_DEV type, unsigned char addr)
{
    unsigned char i;
  uint32_t      event = 0; 
  uint32_t      read_pw_val;
  portBASE_TYPE time_end;
    
  Ctrl_5V_On(ch);            //switch On  5V
  CaptureNumber[ch] = 0; //сброс количества замеров
  TimerCaptureEnDis(ch, ENABLE); //start capture timer
  for(i = 0; i ‹ Q_PW; i++)
  {
    Ctrl_24V_Off(ch);        //switch off 24V
    time_end = xQueueReceive(CaptPWQueue[ch], &read_pw_val, TIME_WAIT_QUEUE_CAPT); // interrupt queue

    if(time_end == pdPASS)
    {
      if(read_pw_val › 0)
      {
          SS_Sensor[LOOP1][addr].PW[i]       =  read_pw_val;    //write in struct cur PW value
          SS_Sensor[LOOP1][addr].PW_Level[i] = (read_pw_val * 10) / SS_Sensor[LOOP1][addr].PW[0];
        HandlePWs(ch, type, addr);// обработать полученные данные
      }
    }
    else if(time_end == errQUEUE_FULL)
    {
      SS_Sensor[LOOP1][addr].OldState = SS_Sensor[LOOP1][addr].State;
      break;
    }
    else
    {
      Ctrl_24V_On(ch);
    }  
   vTaskDelay(DELAY_500_US);              //delay 250 us
   Ctrl_24V_On(ch);                      //switch on 24V
   vTaskDelay(DELAY_250_US);              //delay 250 us
  }
  vTaskDelay(DELAY_250_US);                //delay 250 us
  TimerCaptureEnDis(ch, DISABLE);     //stop capture timer
  vTaskDelay(TIME_WAIT_SOFT_RESET);      //soft reset sensor
} 
После запуска через случайное время вылетает в HardFault
если закомментировать вот эти строки
else if(time_end == errQUEUE_FULL)
{
SS_Sensor[LOOP1][addr].OldState = SS_Sensor[LOOP1][addr].State;
break;
}
else
{
Ctrl_24V_On(ch);
}
то все идет нормально.

Пробовал увеличивать размер стэка, приоритет задачи, приоритет прерывания ничего не помогает.
Обшарил все сайты что может быть?
Реклама:
valic вне форума  
Непрочитано 23.05.2013, 14:58  
InsolentS
Прохожий
 
Регистрация: 05.11.2006
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
InsolentS на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

1) Если в прерывании используете сервисы ОС, в конце обработчика вызывайте portEND_SWITCHING_ISR. Пример:
Код:
void SERIAL_UsartIRQ(SUsart *_usart)
{
  long xHigherPriorityTaskWoken = pdFALSE;
  ...
    xSemaphoreGiveFromISR(_usart-›TxSemaphore, &xHigherPriorityTaskWoken);  
  ...
    xQueueSendFromISR(_usart-›RxQueue, (void*) &byte, &xHigherPriorityTaskWoken);  
  ...
    xSemaphoreGiveFromISR(_usart-›RxSemaphore, &xHigherPriorityTaskWoken);
  ...
  portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
2) Внимательно проверьте приоритеты прерываний. Приоритет пользовательского прерывания, которое использует сервисы ОС, должен быть ниже приоритета configMAX_SYSCALL_INTERRUPT_PRIORITY.
http://www.freertos.org/a00110.html#kernel_priority
3) Надеюсь, Вы не забыли включить
Код:
VIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
при старте системы
InsolentS вне форума  
Сказали "Спасибо" InsolentS
valic (23.05.2013)
Непрочитано 23.05.2013, 15:09  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,821
Сказал спасибо: 919
Сказали Спасибо 4,289 раз(а) в 2,570 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

За такой обработчик прерывания нужно бы наказывать как-то. Hard fault подойдет.
Easyrider83 вне форума  
Непрочитано 23.05.2013, 17:00  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

2InsolentS

1 Добавил portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); не помогло
2 configMAX_SYSCALL_INTERRUPT_PRIORITY = 191
мое прерывание только Tim4_IRQ:
добавил:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
перед:
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

Попробовал предложенные Вами решения. Не помогло. Курю дальше.


2Easyrider83

Переписал обрботчик прерываний:
PHP код:
void TimerSystemSensorIRQ(void)
{ 
  portBASE_TYPE   res = 0;
  long                  xHigherPriorityTaskWoken = pdFALSE;

  if(TIM4-›SR & TIM_IT_CC1) 
  {
      TIM4-›SR = (uint16_t)~TIM_IT_CC1; //Clear flag interrupt
      if(CaptEnable[CH11])
     {
        xQueueSendFromISR(CaptPWQueue[CH11], &CaptPWValue[CH11], &xHigherPriorityTaskWoken);// send queue
     }
  }
   portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} 

Последний раз редактировалось valic; 23.05.2013 в 17:01. Причина: исправление ошибок
valic вне форума  
Непрочитано 24.05.2013, 08:53  
InsolentS
Прохожий
 
Регистрация: 05.11.2006
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
InsolentS на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Сообщение от valic Посмотреть сообщение
Код:
2 configMAX_SYSCALL_INTERRUPT_PRIORITY = 191
...
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori  ty = 0;
191 это decimal? это 0xBF hex - т.е. 13-ый приоритет, очень низкий.
А вот у таймера приоритет 0 - т.е. самый высокий.

Сделайте
Код:
configMAX_SYSCALL_INTERRUPT_PRIORITY = 0x10 или 0x20
...
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori  ty = 3 .. 13;
InsolentS вне форума  
Непрочитано 25.05.2013, 17:23  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Более подробное изучение вывело на место где происходит исключение.
При записи значения в очередь (при помощи FreeRTOS внутри обработчкиа prvCopyDataToQueue) вызывается функция memcpy, которая пытается писать данные в ячейки больше чем 0x20020000. У STM32F207 это конец оперативной памяти, поэтому возникает исключение BUS Fault, а так как оно не разрешено, вызывается HARD Fault.
Может есть какие-то настройки у FreeRTOS чтобы указать границы памяти?
По логике они указаны в stm32f2xx.h и она должна брать их оттуда.
Почему пытается писать данные за пределы?
valic вне форума  
Непрочитано 25.05.2013, 17:53  
dosikus
Гуру портала
 
Аватар для dosikus
 
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
dosikus на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Сообщение от valic Посмотреть сообщение
По логике они указаны в stm32f2xx.h и она должна брать их оттуда.
Вообще то это указывается в опциях линкера . Что за компиль ?
__________________
Осторожно , злой кот
dosikus вне форума  
Непрочитано 25.05.2013, 18:02  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Компилятор Keil, да в линкере указано
IRAM start - 0x20000000 size - 0x20000
Миниатюры:
Нажмите на изображение для увеличения
Название: 1.GIF
Просмотров: 113
Размер:	20.5 Кб
ID:	47180  
valic вне форума  
Непрочитано 25.05.2013, 23:35  
InsolentS
Прохожий
 
Регистрация: 05.11.2006
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
InsolentS на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Сообщение от valic Посмотреть сообщение
вызывается функция memcpy, которая пытается писать данные в ячейки больше чем 0x20020000.
У вас портится стек и отсюда ложные указатели. Вы сделали то, что я написал в сообщении #5 ?
InsolentS вне форума  
Непрочитано 26.05.2013, 09:15  
valic
Временная регистрация
 
Аватар для valic
 
Регистрация: 04.05.2008
Адрес: Ставрополь
Сообщений: 63
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 17 сообщении(ях)
valic на пути к лучшему
По умолчанию Re: Программа уходит в HardFault (STM32)

Да, сделал. Менял приоритеты, пробовал разные варианты, из указанных Вами.
Еще заметил такую особенность, в ОЗУ часть ячеек (около 500) заполнена одинаковыми данными 0xA5. и при остановке программы в некоторый момент времени я вижу эти значения регистрах общего назначения.
valic вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изучаем STM32 Cortex M3 EugVor ARM 6171 20.05.2025 20:16
Проблема с ST-LINK +KEIL + STM32 LionRJ Микроконтроллеры, АЦП, память и т.д 5 06.03.2012 17:21
Что такое программа и методика измерений и чем отличается программа от методики tumanovalex Измерительное оборудование 12 22.12.2009 20:40


Часовой пояс GMT +4, время: 08:06.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.