Neo_Matrix 0 17 февраля, 2016 Опубликовано 17 февраля, 2016 (изменено) · Жалоба Имеется плата на 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. Изменено 17 февраля, 2016 пользователем Neo_Matrix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gazpar 1 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Странно, что работает: 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 ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Странно, что работает: Т.к. функиции возвращают указатели. И нулевой указатель в отдельных случаях. Так что код вполне рабочий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Когда то с таким сталкивался и проблема была в размере СТОК\ХЕАП. В данном случае пробовал менять их размер и в FreeRTOS и в Стартап файле, но как узнать какой размер куда прописывать? Для этого надо вдумчиво прочитать документацию и провести эксперименты. Похоже разобрался. Поставил во FreeRTOS вместо heap4 тип heap1. Маловероятно. Скорее всего, проблема где-то глубже. Кроме того, heap1 очень ущербный - там в принципе нет free(). С ним можно работать, если у Вас задачи-массивы-проч создаются один раз, статически. Если же пользоваться malloc()/free() при работе, операционка довольно быстро повиснет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 (изменено) · Жалоба 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. Маалоков нет. Динамические только очереди и пару задач временами убиваются/создаются. Изменено 18 февраля, 2016 пользователем Neo_Matrix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gazpar 1 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Ок. Neo_Matrix, Вы используете прерывания? Если да, то при настройке оных, какой устанавливаете NVIC_PriorityGroup: 0, 1, 2, 3 или 4? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Глубже копать уже просто некуда(ну или я не вижу). Ну, если Вы можете чётко сказать "в задаче А столько-то свободного стека, в задаче Б - столько-то, хипа используется столько-то", в эту сторону копать не стоит. А пока "я не знаю, переполняется что-то или нет", копать есть куда. И много... Остановился на heap_2. Маалоков нет. Динамические только очереди и пару задач временами убиваются/создаются. Ну так создание/удаление очередей-задач - это чистейший маллок/фрии. А heap_2 - это плохо. Оно нормально работает только при выделении/удалении элементов одинакового размера. Ну и было б неплохо вместо "проц виснет" описать "вываливается в hardfault, link-register указывает на функцию ааа(), там у меня происходит ...". Начинать читать здесь: http://www.freertos.org/Debugging-Hard-Fau...ontrollers.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба gazpar Настройка прерываний следущая HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); HAL_NVIC_SetPriority(USART3_IRQn, 5, 0); esaulenka Я увеличивал стек и кучу в 2 раза, это нечего не меняло. Ну так создание/удаление очередей-задач - это чистейший маллок/фрии. Тут полностью согласен, но у меня размер очередей одинаков, так что должно работать. Ну и было б неплохо вместо "проц виснет" описать "вываливается в hardfault, link-register указывает на функцию ааа().... Я не могу понять где оно валится в хардфолт, отладка как то странно работает под РТОС, попробую еще с отладкой разобраться(РТОС первый раз использую). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gazpar 1 18 февраля, 2016 Опубликовано 18 февраля, 2016 (изменено) · Жалоба В этой РТОС есть специальные службы для определения, что где ломается 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); } Изменено 18 февраля, 2016 пользователем gazpar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Немного добавлю по отладке. Есть задача, которая в цикле запускает вышеуказанную функцию. Собственно вот: 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) более трех. В этой РТОС есть специальные службы для определения, что где ломается О, теперь понятно!!! Спасибо! Еще добавлю, на сайте РТОС есть такое: 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. Может как то связано..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба Немного добавлю по отладке. Есть задача, которая в цикле запускает вышеуказанную функцию. Собственно вот: 1) Хорошим тоном является наличие не обычного флажка, а семафора. Или очереди. В этом случае задача не будет крутиться впустую. 2) Также хорошим тоном (а в случае "где-то у меня память течёт" - необходимым средством) является использование snprintf() вместо sprintf(). sprintf() легко и непринуждённо портит память, лежащую сразу после выходного буфера (сколько раз сам на это наступал...). Как видно в начале происходит проверка на новые данные if(uart3_not_empty), и даже если условие if не выполнено, все равно все висло. Ну отлично просто. Но пока мы не увидим, где и что конкретно повисло, результаты разглядывания кофейной гущи будут точнее, чем разглядывание кода. О, теперь понятно!!! Спасибо! Т.е. ссылка в 4-м сообщении - непонятная, а ссылка в 9-м - понятная? Удивительное дело, ведь ведут они в конечном итоге в одно и то же место. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба 1) Хорошим тоном является наличие не обычного флажка, а семафора. Или очереди. В этом случае задача не будет крутиться впустую. 2) Также хорошим тоном (а в случае "где-то у меня память течёт" - необходимым средством) является использование snprintf() вместо sprintf(). sprintf() легко и непринуждённо портит память, лежащую сразу после выходного буфера (сколько раз сам на это наступал...). Как можно заметить задача именуется vTemp. Это временное решение, созданное для вывода отладки в ЮАРТ. Этой задачи вовсе не должно было быть. Потому с семафорами я не заморачивался. Ну отлично просто. Но пока мы не увидим, где и что конкретно повисло, результаты разглядывания кофейной гущи будут точнее, чем разглядывание кода. Если бы я видел, где повисло уже и сам бы решал проблему. Вечером буду пробовать по добавлять отладки в код РТОСа. Т.е. ссылка в 4-м сообщении - непонятная, а ссылка в 9-м - понятная? Удивительное дело, ведь ведут они в конечном итоге в одно и то же место. Дело вовсе не в ссылке, а в примере который там показан. esaulenka не нужно так агрессивно относится к заданным вопросам, не все так хорошо знакомы с РТОСом, как Вы. После всего прочитанного, мне стало ясно как отлаживать РТОСом, возможно скоро я и найду причину беды, если нет - перепишу с нуля обработчик прерывания и ф-кцию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба esaulenka не нужно так агрессивно Ок. Извините. У Вас проблема в том, что полностью отсутствуют средства диагностики. Настоятельно рекомендую разобраться, что такое hardfault, в какие регистры надо при этом смотреть (для начала - скопировать обработчик с сайта freertos, погуглить "hardfault cortex site:electronix.ru -redirect"). Также при работе с RTOS необходимо знание, сколько куда памяти уходит. Во фриртос это почти что встроенная штука (почему-то в heap'е нет диагностики, но это легко поправить). Без диагностики можно долго "исправлять" методом тыка, и оно опять развалится в самый неподходящий момент... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neo_Matrix 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба 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 виноват... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Слово "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 повторюсь. Не зная, как и что ломалось, гарантировать "вот теперь-то точно всё будет хорошо" нельзя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться