|
STM32 зависание при добавлении любой функции |
|
|
|
Feb 17 2016, 21:33
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Имеется плата на stm32f407 камне. Пытаюсь написать функцию парсинга ответов от модема, но при добавлении любой строки в функцию - получаю полное зависание проца. Как отлаживать не могу понять, так как присутствует FreeRTOS. Собственно сама функция выглядит так: Код uint8_t modemresponse(char * data, uint16_t leng) { if(iblanks(Uart3RXBuf, leng)) { return 0; } else if(memchr(data, '+', leng) && memchr(data, ':', leng)) { return 1; } else if(strstr(data,"ERROR") != NULL) { return 2; } else { return 3; } } Если сделать как ниже, то все работает. Тоесть достаточно закоментировать любой из else if или даже else. Если закоментировать один вариант выбора и вместо него в конец функции подставить хотя бы Код HAL_UART_Transmit(&huart6,(uint8_t *)"Zavislo\r",8,100); или все что угодно - опять висяк. Код uint8_t modemresponse(char * data, uint16_t leng) { if(iblanks(Uart3RXBuf, leng)) { return 0; } else if(memchr(data, '+', leng) && memchr(data, ':', leng)) { return 1; } //else if(strstr(data,"ERROR") != NULL) //{ // return 2; //} else { return 3; } } Когда то с таким сталкивался и проблема была в размере СТОК\ХЕАП. В данном случае пробовал менять их размер и в FreeRTOS и в Стартап файле, но как узнать какой размер куда прописывать? Похоже разобрался. Поставил во FreeRTOS вместо heap4 тип heap1.
Сообщение отредактировал Neo_Matrix - Feb 17 2016, 21:34
|
|
|
|
|
Feb 18 2016, 01:08
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 9-01-14
Пользователь №: 79 952

|
Странно, что работает: Код const void * memchr ( const void * ptr, int value, size_t num ); void * memchr ( void * ptr, int value, size_t num );
const char * strstr ( const char * str1, const char * str2 ); char * strstr ( char * str1, const char * str2 ); Т.к. функиции возвращают указатели. А сравнение уже нужно производить другими функциями. Типа: Код int strncmp ( const char * str1, const char * str2, size_t num );
|
|
|
|
|
Feb 18 2016, 07:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Neo_Matrix @ Feb 18 2016, 00:33)  Когда то с таким сталкивался и проблема была в размере СТОК\ХЕАП. В данном случае пробовал менять их размер и в FreeRTOS и в Стартап файле, но как узнать какой размер куда прописывать? Для этого надо вдумчиво прочитать документацию и провести эксперименты. Цитата(Neo_Matrix @ Feb 18 2016, 00:33)  Похоже разобрался. Поставил во FreeRTOS вместо heap4 тип heap1. Маловероятно. Скорее всего, проблема где-то глубже. Кроме того, heap1 очень ущербный - там в принципе нет free(). С ним можно работать, если у Вас задачи-массивы-проч создаются один раз, статически. Если же пользоваться malloc()/free() при работе, операционка довольно быстро повиснет.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 18 2016, 08:30
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
gazpar Странно, что работает:
void *memchr(const void *buffer, int ch, size_t count); Эта функция возвращает указатель на первый из символов ch, входящих в массив buffer, или нулевой указатель, если символ ch не найден.
Сама реализация вполне рабочая. И совершенно не важно, что там идет после if (if else), можно хоть сравнение добавить uint8_t a=1; if(a==1); все равно функция виснет.
esaulenka Глубже копать уже просто некуда(ну или я не вижу). В конечном счете выяснил, что при всех вариантах heap,кроме heap_4 все работает. Даже на heap_5 работает, а он почти тот же heap_4. Остановился на heap_2. Маалоков нет. Динамические только очереди и пару задач временами убиваются/создаются.
Сообщение отредактировал Neo_Matrix - Feb 18 2016, 08:33
|
|
|
|
|
Feb 18 2016, 09:13
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Neo_Matrix @ Feb 18 2016, 11:30)  Глубже копать уже просто некуда(ну или я не вижу). Ну, если Вы можете чётко сказать "в задаче А столько-то свободного стека, в задаче Б - столько-то, хипа используется столько-то", в эту сторону копать не стоит. А пока "я не знаю, переполняется что-то или нет", копать есть куда. И много... Цитата(Neo_Matrix @ Feb 18 2016, 11:30)  Остановился на heap_2. Маалоков нет. Динамические только очереди и пару задач временами убиваются/создаются. Ну так создание/удаление очередей-задач - это чистейший маллок/фрии. А heap_2 - это плохо. Оно нормально работает только при выделении/удалении элементов одинакового размера. Ну и было б неплохо вместо "проц виснет" описать "вываливается в hardfault, link-register указывает на функцию ааа(), там у меня происходит ...". Начинать читать здесь: http://www.freertos.org/Debugging-Hard-Fau...ontrollers.html
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 18 2016, 10:37
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
gazparНастройка прерываний следущая HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); HAL_NVIC_SetPriority(USART3_IRQn, 5, 0); esaulenkaЯ увеличивал стек и кучу в 2 раза, это нечего не меняло. Цитата Ну так создание/удаление очередей-задач - это чистейший маллок/фрии. Тут полностью согласен, но у меня размер очередей одинаков, так что должно работать. Цитата Ну и было б неплохо вместо "проц виснет" описать "вываливается в hardfault, link-register указывает на функцию ааа().... Я не могу понять где оно валится в хардфолт, отладка как то странно работает под РТОС, попробую еще с отладкой разобраться(РТОС первый раз использую).
|
|
|
|
|
Feb 18 2016, 10:56
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 9-01-14
Пользователь №: 79 952

|
В этой РТОС есть специальные службы для определения, что где ломается HooksВ обработчики hook'ов можно добавить отладочные сообщения(зажечь какой-то led(или выдать какую-либо последовательность мигания), отправить сообщение в usart и т.п.) Используется примерно так: Код void vApplicationStackOverflowHook( xTaskHandle pxTask,char *pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; printf("\r\n\r\nStack overflowed by \"%10s\" task\r\n\r\n",pcTaskName); }
Сообщение отредактировал gazpar - Feb 18 2016, 11:10
|
|
|
|
|
Feb 18 2016, 11:41
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Немного добавлю по отладке. Есть задача, которая в цикле запускает вышеуказанную функцию. Собственно вот: Код void vTemp(void const * argument) { for(;;) { uint16_t leng; //Длина строки до знака \n uint8_t resp; //Собственно сам ответ 0,1,2,3..... if(uart3_not_empty) //Обработчик прерывания устанавливает флаг 1\0 { leng = uart3_readline(); //вычисляем длину строки вместе с \r\n sprintf(debug_buff, "leng: %d, line: %s", len, Uart3RXBuf); //формировка данных в соседний порт для отладки(длина строки и сама строка) USART_STR(USART6, debug_buff); //просто отправка данных в соседний порт для отладки resp = process_response(uart3_fifo_line,len); // тут вызов глючной функции sprintf(debug_buff, "resp: %d \r\n", resp); //формовка TM_USART_Puts(USART6, debug_buff); //отправка для отладки } } } Как видно в начале происходит проверка на новые данные if(uart3_not_empty), и даже если условие if не выполнено, все равно все висло. uart3_not_empty инициализируется 0-лем, в прерывании флаг ставится в 1. Зависон просходил даже при условии отсутствия данных на ком порте, но только при условии, что в функции process_response вариантов if(if else) более трех. Цитата(gazpar @ Feb 18 2016, 12:56)  В этой РТОС есть специальные службы для определения, что где ломается О, теперь понятно!!! Спасибо! Еще добавлю, на сайте РТОС есть такое: Known Issues with the Current Version Heap_4.c cannot be used on 8-bit devices (FreeRTOS V8.2.1) A typo in the calculation of xHeapStructSize means heap_4.c cannot be used to provide the heap when FreeRTOS is being built for an 8-bit microcontroller. Software timers and FreeRTOS-MPU The software timer API is not yet included in the official distribution of FreeRTOS/source/include/mpu_wrappers.h. Может как то связано.....
|
|
|
|
|
Feb 18 2016, 13:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Neo_Matrix @ Feb 18 2016, 14:41)  Немного добавлю по отладке. Есть задача, которая в цикле запускает вышеуказанную функцию. Собственно вот: 1) Хорошим тоном является наличие не обычного флажка, а семафора. Или очереди. В этом случае задача не будет крутиться впустую. 2) Также хорошим тоном (а в случае "где-то у меня память течёт" - необходимым средством) является использование snprintf() вместо sprintf(). sprintf() легко и непринуждённо портит память, лежащую сразу после выходного буфера (сколько раз сам на это наступал...). Цитата(Neo_Matrix @ Feb 18 2016, 14:41)  Как видно в начале происходит проверка на новые данные if(uart3_not_empty), и даже если условие if не выполнено, все равно все висло. Ну отлично просто. Но пока мы не увидим, где и что конкретно повисло, результаты разглядывания кофейной гущи будут точнее, чем разглядывание кода. Цитата(Neo_Matrix @ Feb 18 2016, 14:41)  О, теперь понятно!!! Спасибо! Т.е. ссылка в 4-м сообщении - непонятная, а ссылка в 9-м - понятная? Удивительное дело, ведь ведут они в конечном итоге в одно и то же место.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 18 2016, 14:45
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Цитата(esaulenka @ Feb 18 2016, 15:09)  1) Хорошим тоном является наличие не обычного флажка, а семафора. Или очереди. В этом случае задача не будет крутиться впустую. 2) Также хорошим тоном (а в случае "где-то у меня память течёт" - необходимым средством) является использование snprintf() вместо sprintf(). sprintf() легко и непринуждённо портит память, лежащую сразу после выходного буфера (сколько раз сам на это наступал...). Как можно заметить задача именуется vTemp. Это временное решение, созданное для вывода отладки в ЮАРТ. Этой задачи вовсе не должно было быть. Потому с семафорами я не заморачивался. Цитата(esaulenka @ Feb 18 2016, 15:09)  Ну отлично просто. Но пока мы не увидим, где и что конкретно повисло, результаты разглядывания кофейной гущи будут точнее, чем разглядывание кода. Если бы я видел, где повисло уже и сам бы решал проблему. Вечером буду пробовать по добавлять отладки в код РТОСа. Цитата(esaulenka @ Feb 18 2016, 15:09)  Т.е. ссылка в 4-м сообщении - непонятная, а ссылка в 9-м - понятная? Удивительное дело, ведь ведут они в конечном итоге в одно и то же место. Дело вовсе не в ссылке, а в примере который там показан. esaulenka не нужно так агрессивно относится к заданным вопросам, не все так хорошо знакомы с РТОСом, как Вы. После всего прочитанного, мне стало ясно как отлаживать РТОСом, возможно скоро я и найду причину беды, если нет - перепишу с нуля обработчик прерывания и ф-кцию.
|
|
|
|
|
Feb 18 2016, 15:52
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Neo_Matrix @ Feb 18 2016, 17:45)  esaulenka не нужно так агрессивно Ок. Извините. У Вас проблема в том, что полностью отсутствуют средства диагностики. Настоятельно рекомендую разобраться, что такое hardfault, в какие регистры надо при этом смотреть (для начала - скопировать обработчик с сайта freertos, погуглить "hardfault cortex site:electronix.ru -redirect"). Также при работе с RTOS необходимо знание, сколько куда памяти уходит. Во фриртос это почти что встроенная штука (почему-то в heap'е нет диагностики, но это легко поправить). Без диагностики можно долго "исправлять" методом тыка, и оно опять развалится в самый неподходящий момент...
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 18 2016, 21:56
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
esaulenka, gazparСпасибо за помощь. Уже немного разобрался в отладке..... Зло было найдено, это была соседняя функция которая в этот момент слала данные в тот же USART TX. Было так: Код HAL_UART_Transmit (&huart3,(uint8_t *)"AT\r",3,100); т.е. прерывания не было. А так все нормально: Код HAL_UART_Transmit_IT(&huart3,(uint8_t *)"AT\r",3); В цикле отправка без прерывания, а прием по прерываниям работает, под РТОС почему то нет. Или это HAL виноват...
|
|
|
|
|
Feb 19 2016, 07:17
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Слово "HAL" я пропустил. Вас ждёт масса удивительных открытий. Например, отсутствие нормальных семафоров: Код #if (USE_RTOS == 1) #error " USE_RTOS should be 0 in the current HAL release " #else #define __HAL_LOCK(__HANDLE__) \ do{ \ if((__HANDLE__)->Lock == HAL_LOCKED) \ { \ return HAL_BUSY; \ } \ else \ { \ (__HANDLE__)->Lock = HAL_LOCKED; \ } \ }while (0)
#define __HAL_UNLOCK(__HANDLE__) \ do{ \ (__HANDLE__)->Lock = HAL_UNLOCKED; \ }while (0) #endif /* USE_RTOS */ В особо неудачном случае оно действительно может повиснуть. Правда, это старая версия, возможно, за год что-то поменялось... Код * @file stm32f1xx_hal_def.h * @author MCD Application Team * @version V1.0.0 * @date 15-December-2014 PS повторюсь. Не зная, как и что ломалось, гарантировать "вот теперь-то точно всё будет хорошо" нельзя.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|