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

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

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

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

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

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


 
Опции темы
Непрочитано 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 chTYPE_SS_DEV typeunsigned 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(chENABLE); //start capture timer
  
for(0‹ Q_PWi++)
  {
    
Ctrl_24V_Off(ch);        //switch off 24V
    
time_end xQueueReceive(CaptPWQueue[ch], &read_pw_valTIME_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(chtypeaddr);// обработать полученные данные
      
}
    }
    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(chDISABLE);     //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,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
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_ISRxHigherPriorityTaskWoken );


Последний раз редактировалось 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
Сообщений: 10,018
Сказал спасибо: 936
Сказали Спасибо 2,270 раз(а) в 1,565 сообщении(ях)
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 6166 19.02.2024 18:22
Проблема с ST-LINK +KEIL + STM32 LionRJ Микроконтроллеры, АЦП, память и т.д 5 06.03.2012 17:21
Что такое программа и методика измерений и чем отличается программа от методики tumanovalex Измерительное оборудование 12 22.12.2009 20:40


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


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot