|
STM32L151 + SDIO + FreeRTOS, BusFault после выхода из прерывания SDIO |
|
|
|
Feb 26 2015, 15:55
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Коллеги, добрый день. Подскажите что-нибудь ! После выхода из обработчика прерывания SDIO программа оказывается в BusFault_Handler. Глюк происходит изредка и нерегулярно. В окне Callstuck картина каждый раз одинаковая, глюк где-то в коде ядра ОС Если установку эвентов в прерывании заменить на глобальную переменную, а ожидание эвентов на проверку этой переменной в цикле while , то глюка не происходит. Приоритет прерывания 12. FreeRTOS настроена так : Код #define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for(;; ); } /*проходит не ругается */ Обработчик прерывания Код void SDIO_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken; static unsigned int SDIO_STA_MASK;
xHigherPriorityTaskWoken = pdFALSE; SDIO_STA_MASK=SDIO->STA & 0x00ffffff; //т.к. в EventGroup можно передавать только 24 бита xEventGroupSetBitsFromISR(x_SDIO_Transmit_EventGroup, SDIO_STA_MASK ,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken == pdTRUE);
SDIO->ICR= SDIO_STA_MASK; //сбрасываем флаги прерывания //
xxxx=123; //Глобальная переменная для поиска места глюка }
Эскизы прикрепленных изображений
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Feb 27 2015, 00:15
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
CFSR = 0x00008200 (во всех случаях) То есть, стоят биты 15 BFARVALID BFAR holds a valid fault address. 9 PRECISERR Precise data bus error . A data bus error has occurred, and the PC value stacked for the exception return points to the instruction that caused the fault. BFAR=0xE000ED00 или 0xC0008830 Что по этим адресам, показано на картинках. Мне не приходит в голову, что со всем этим делать. Ещё, заметил, что глюк происходит не в одном месте, а в двух: а)во время ожидания эвента из прерывания(чаще) , и б) во время ожидания другого эвента просто из задачи. Т.е. вроде как и с прерыванием не связано, а связано только с эвентом. Множество других эвентов работают без проблем.
Эскизы прикрепленных изображений
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Feb 27 2015, 10:48
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Вот такой массив их эвентов и такое обращение к нему причиной проблемы быть не может ? Я что-то засомневался, ведь EventGroupHandle_t это указатель. Получается объявление аналогичное char *x[2]; Код #define SD_CARDS_COUNT 2 #define SD1 0 #define SD2 1
EventGroupHandle_t xSD_State_EventGroup[SD_CARDS_COUNT];
...............
xSD_State_EventGroup[SD1]=xEventGroupCreate(); xSD_State_EventGroup[SD2]=xEventGroupCreate();
..............
char sd_n = SD2; xEventGroupClearBits(xSD_State_EventGroup[sd_n], INIT_COMPLETE);
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Feb 27 2015, 19:43
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(MiklPolikov @ Feb 26 2015, 18:55)  ...Если установку эвентов в прерывании заменить... если мозговой штурм возможных вариантов болезни не поможет - то предлагаю тупо отключать куски кода методом комментирования, оставляя только функционал замеченный в траблах. тем самым вы сможете а) сделать рабочую рыбу для выкладывания на форум и детального ковыряния в нём с лупой в дальнейшем. б) наберёте большую статистику по отказам и бОльше инфы для анализа. муторно конечно же, но причину отроете обязательно в конце концов. можно конечно же сделать "ход конём" и полностью сэмулировать взаимодейтвие прерывания от карточки, оси и потоков. если рыба упадёт - то это уже гораздо меньше кода. если нет - идём уже от меньшего к большему - копируем околотемный функционал, пытаясь проявить бяку. ну и т.д...
|
|
|
|
|
Feb 27 2015, 20:12
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Цитата(kolobok0 @ Feb 27 2015, 22:43)  тупо отключать куски кода методом комментирования Уже двинулся по этому пути. Но проблема в том, что глюк уж больно хитрый, то он есть, то нет, и если убираешь одно стабильно-глючное место, то стабильно-глючным становится другое. Я-то надеялся, что мне сейчас скажут какую-нибудь хитрость про настройку FreeRTOS , которую я не знал, и проблема легко решится : )
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Feb 27 2015, 21:45
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Другой вопрос: Делаю xTimerResetFromISR , после этого программа попадает в функцию таймера, и в это время в окне Call Stack появляется prvTaskExitError . Откуда эта ошибка ? Она означает, что программа где-то вышла из бесконечного цикла внутри задачи, так ? Для чистоты эксперимента, никаких задачь нету. есть только функция таймера и прерывание (от кнопки). Код ///функция таймера void vTimerCallback_Buttons( TimerHandle_t x_Timer) { char result; result =1; // тут точка останова, на которой в Call Stack уже появились 2шт prvTaskExitError
}
//Прерывание от кнопки void EXTI9_5_IRQHandler (void) { static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; EXTI->PR|=(1<<7); EXTI->PR|=(1<<9); xTimerResetFromISR(x_Timer_Buttons, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken == pdTRUE); }
................... //так создаётся таймер x_Timer_Buttons=xTimerCreate("x_Timer_Buttons", 1000/portTICK_RATE_MS, pdFALSE , ( void * )1, vTimerCallback_Buttons);
Эскизы прикрепленных изображений
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Feb 27 2015, 23:24
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Цитата(aaarrr @ Feb 28 2015, 01:18)  Приоритеты прерываний настроены? Вроде бы да : #define configMAX_SYSCALL_INTERRUPT_PRIORITY 0xb0 Т.к. в STM32 для определения приоритета используются биты 7-4 , то это приоритет 0xB или 11. Стало быть, те прерывания, где есть функции API , должны иметь приоритеты ниже, т.е. 15-11 включительно. У меня так и сделано. Всё верно ?
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|