Easyelectronics.ru • Просмотр темы - зависания

Easyelectronics.ru

Электроника для всех
Текущее время: 15 авг 2018, 09:42

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 21 ] 
Автор Сообщение
 Заголовок сообщения: зависания
СообщениеДобавлено: 28 ноя 2017, 19:30 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
Проект на фриртосе, после очередного добавления кода, начались зависания, работает примерно несколько минут и виснет, поставил костыл в виде вачдога, но это проблему не решает. Подскажите, как определить из-за чего зависает?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 19:41 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Ну, тут много можно гадать, а наш штатный телепат уехал в командировку.
Вачдог, особенно при неграмотном использовании, от зависаний не спасет, поскольку он предохраняет от случайных процессов, а не от ошибки программиста.

Самое простое - спросить себя: "а что я добавил/изменил, после чего сломалось?".
На примере РТОС - нехватка стека задач, нехватка кучи, ошибки в приоритетах задач, приоритетах прерываний, ошибки в использовании ...FromISR-функций API, ошибки вообще в использовании API РТОС

Буквально несколько дней назад тут рядом была подобная тема с зависанием через некоторое время. Ознакомьтесь с ней.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 20:04 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
BusMaster писал(а):
Буквально несколько дней назад тут рядом была подобная тема с зависанием через некоторое время. Ознакомьтесь с ней.

если не сложно, как тема называлась?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 20:25 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
FreeRTOS STM32F4 и внешние прерывания


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 20:31 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
BusMaster - спасибо!!!! буду изучать, но по диагнозу, мой проект зависает похоже из-за ОЗУ, так как какое-то время работает, а потом зависает. Есть ли механизмы определить сколько ОЗУ нужно выделить задаче для работы?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 22:22 
Заглядывает иногда

Зарегистрирован: 25 апр 2011, 01:46
Сообщения: 130
Ну заняться отладкой да посмотреть что сколько ест. viewtopic.php?f=49&t=33320


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 28 ноя 2017, 23:23 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Посмотреть использование стека задачи очень просто:
- запускаем отладку. Доходим до строчек создания задачи, и когда выполнится ф-ция xTaskCreate интересующей нас задачи, смотрим на значение переменной дескриптора задачи. Это будет адрес блока TCB задачи.
- открываем браузер памяти, ищем этот самый адрес. Поблизости от него увидим ANSI-текст названия задачи, который мы вводили вторым параметром при её создании. Конец выделенного текстового поля означает конец блока TCB задачи. Выше блока TCB находится её стек, он "растет" вверх, в сторону уменьшения адресов.
- далее, ставим брекпоинт где-нить в конце цикла задачи и запускаем выполнение. Остановившись на брекпоинте, смотрим по изменению значений в стеке, докудава он дошел. Если не дошел до блока TCB предыдущей задачи, то все хорошо, стека вроде как пока что хватает.
На скрине - внизу зелено-голубой цвет - TCB исследуемой задачи (Processing), желтый цвет - её стек, красная линия - верхняя граница использования стека, зеленый цвет вверху - TCB предыдущей задачи.

Вложение:
Без-имени-4.png
Без-имени-4.png [ 51.34 Кб | Просмотров: 1389 ]


Если же стека задачи не хватит, то блок TCB предыдущей задачи будет безжалостно и без следа затерт, вы это увидите по исчезновению ASCII-текста названия задачи. После этого сразу операционка порушится и зависнет.

Стек задачи используют все переменные и массивы, объявленные внутри задачи (кроме static-переменных), а так же переменные всех функций, вызываемых из задачи. В моем примере на скрине - в стеке размещен массив переменных, а так же все переменные, создаваемые ф-цией printf и другими ф-циями.
Размер выделенного стека = 600 байт. При создании было указано - configMINIMAL_STACK_SIZE * 3, при configMINIMAL_STACK_SIZE = 50. Тут считается 4-байтными словами.
(50 * 4) * 3 = 600 байт
При configMINIMAL_STACK_SIZE * 2 - стека уже не хватает и система рушится


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 29 ноя 2017, 09:58 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2662
Можно хуки подключить, и посмотреть, что не так, скорее всего срыв стека.
У себя сделано примерно так:
Код:
void vApplicationMallocFailedHook( void )
{
   UsartDebugSendStringPoll((const uint8_t*)"\r\n\r\n[FREERTOS] MALLOC FAILED!\r\n\r\n");
   for( ;; );
}
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
   sprintf((char*)UsartDebugBuffer,"\r\n[FREERTOS]->\"%s\" STACK IS OVERFLOW!\r\n\r\n",   pcTaskName);
   UsartDebugSendStringPoll((const uint8_t*)UsartDebugBuffer);
   for( ;; );
}
void vApplicationIdleHook( void )
{
}


Не забыть включить
Код:
#define configCHECK_FOR_STACK_OVERFLOW      2
#define configUSE_MALLOC_FAILED_HOOK      1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 дек 2017, 15:45 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 60
Откуда: Омск
Volldemar писал(а):
Есть ли механизмы определить сколько ОЗУ нужно выделить задаче для работы?

Есть. FreeRTOS позволяет отслеживать сколько памяти в стэке использует поток.

1. Добавьте в FreeRTOSConfig.h
Код:
#define INCLUDE_uxTaskGetStackHighWaterMark 1

(Либо в свойствах проекта укажите дефайн со значением:
Код:
-DuxTaskGetStackHighWaterMark=1

2. Там же:
Код:
#define configGENERATE_RUN_TIME_STATS   1

Вроди бы, второй дефайн не требуется, но для чего-то мне была нужна информация во время выполнения. Для отладки удобно видеть потоки; для отладки без IDE - иметь консоль с возможностью вычисления состояния стэка.
3. При создании задач - сохраняйте их хэндлы:
Код:
TaskHandle_t Task_TTY0; (глобальная переменная)
xTaskCreate(vTaskTTY0, ( const char * ) "TTY0", 256, NULL, 2, &Task_TTY0);

4. Во время выполнения:
Код:
   Console("TTY0:\t\t");
   Console(utoa_builtin_div(uxTaskGetStackHighWaterMark(Task_TTY0), t));
   Console("/256\r\n");

Выводит в консоль (текстом) состояние стэка задачи.
Пример вывода:
Код:
>status
Current heap free 27376 bytes
Minimum heap free 27320 bytes
>mem
TTY0: 200/256


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 дек 2017, 20:30 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 3480
Откуда: Кемеровская область, Киселевск
Для начало проверить хватает ли памяти.

_________________
RADIOWOLF.RU


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 10 янв 2018, 14:47 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
Oxford писал(а):
Для начало проверить хватает ли памяти.

процессор STM32F411RCT6
памяти по идее должно хватать за глаза, в нём 120 кил ОЗУ
на кучу ртосы выделено:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 70 * 1024 ) )
на задачи:
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1024 )
при инициализации задач добавляю ещё каждой задаче по несколько килобайт, так как некоторые задачи оперируют с массиввами по 10 кил

в отладке вижу, что зависает постоянно на ф-ции:
PendSV_Handler() at port.c:436 0x8003682
регистр sp: 0x2001ffc0


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 12 янв 2018, 15:16 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
в отладчике:
Код:
sp   0x2001ffc0   
lr   -15   
pc   0x800bf70 <WWDG_IRQHandler>   


повторяется постоянно, каждый зависон с такими результатами.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 13 янв 2018, 15:04 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Оконный вачдог включен, чтоль? Тайм-аут у него закончился, вот и висит там. Суть вачдога то в том, чтобы через определенные промежутки времени программно перезагружать таймер вачдога. В условиях операционки логично, что эта перезагрузка таймера может не произойти, если она прописана внутри задачи и без запрета переключения задач. Причем, у оконного вачдога выделен довольно узкий диапазон - 64 отсчета - в течение которых таймер может быть перезапущен.
Применять вачдог следует аккуратно, точно осознавая что именно будет происходить. А происходит полный сброс МК с потерей текущего состояния. Для того и выделено прерывание у оконного вачдога, чтобы перед сбросом сохранить текущее состояние в бэкап-регистрах, а после ресета прочесть и восстановить хотя бы что-то.
Вачдог защищает от непредвиденных редких ошибок в приходящих извне условий, но не от ошибок программиста.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 15 янв 2018, 14:25 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2662
Volldemar писал(а):
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1024 )

Вот тут аккуратнее, это не байты, а слова по 4 байта. У вас под каждую задачу выделяется аж по 1024х4 - 4096 байт, зачем столько? Для простых задач хватает 512-1024 байта стека.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 16 янв 2018, 10:33 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 60
Откуда: Омск
WWDG_IRQHandler - указывает чаще на то, что было вызвано какое-то прерывание, которое не описано.
Попробуйте добавить заглушки для HardFault'а и прочих рядом с ними:
Код:
void BusFault_Handler_c(unsigned int * hardfault_args) {
  unsigned int stacked_r0;
  unsigned int stacked_r1;
  unsigned int stacked_r2;
  unsigned int stacked_r3;
  unsigned int stacked_r12;
  unsigned int stacked_lr;
  unsigned int stacked_pc;
  unsigned int stacked_psr;

  stacked_r0 = ((unsigned long) hardfault_args[0]);
  stacked_r1 = ((unsigned long) hardfault_args[1]);
  stacked_r2 = ((unsigned long) hardfault_args[2]);
  stacked_r3 = ((unsigned long) hardfault_args[3]);

  stacked_r12 = ((unsigned long) hardfault_args[4]);
  stacked_lr = ((unsigned long) hardfault_args[5]);
  stacked_pc = ((unsigned long) hardfault_args[6]);
  stacked_psr = ((unsigned long) hardfault_args[7]);
  while (1);
}

void HardFault_Handler(void) {
   while(1) {}
};
void MemManage_Handler(void) {
   while(1) {}
};
void UsageFault_Handler(void) {
   while(1) {}
};


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 16 янв 2018, 10:43 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
WWDG_IRQHandler - прерывание от оконного вачдога - Window WatchDoG. Оно, если разрешено, возникает за 64 отсчета до конца отсчета таймера, чтобы "сохраниться" перед перезагрузкой.
Неописанное прерывание - это Default Handler, который программно привязан к Reset Handler, потому что это прерывание описано всегда - это запуск МК.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 янв 2018, 11:10 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 60
Откуда: Омск
startup_stm32f745xx.s
Код:
// Секция, ответственная за обработчик сброса
    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler: 
  ldr   sp, =_estack      /* set stack pointer */

/* Copy the data segment initializers from flash to SRAM */ 
  movs  r1, #0
  b  LoopCopyDataInit
<...>

// Секция, ответственная за общий обработчик
    .section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler
<...>

// Таблица векторов
g_pfnVectors:
  .word  _estack
  .word  Reset_Handler

  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler
  .word  UsageFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  DebugMon_Handler
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler
 
  /* External Interrupts */
  .word     WWDG_IRQHandler                   /* Window WatchDog              */                                       
  .word     PVD_IRQHandler                    /* PVD through EXTI Line detection */                       
  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */           
<...>


Смотрим в файл инициализации.
Есть секция сброса, где будет расположен обработчик события сброса. Есть секция общего обработчика, ссылка на которую будет вставлена в таблицу прерываний, если пользователем не был объявлен соответствующий обработчик.
И собственно, сами функции.

Ради эксперимента дизассемблируем собраный файл:
arm-none-eabi-objdump -DS ./debug/Tester.elf
Адрес / Инструкция или данные / Дизассемблированая команда (нужно игнорировать для таблицы прерываний)
Выставленые последний бит в адресе (в таблице) означает переход на инструкцию, которую нужно интерпретировать как thumb, а не ARM код.
Код:
20000000 <g_pfnVectors>:
20000000:       20050000        // Stack
20000004:       20003401        // Reset
20000008:       20003451        // NMI_Handler
2000000c:       20001c09        // HardFault_Handler
20000010:       20001c19        // MemManage_Handler
20000014:       20001a25        // BusFault_Handler
20000018:       20001c29        // UsageFault_Handler
        ... // Дизассемблер сократил нули
2000002c:       20003451        // SVC_Handler
20000030:       20003451        // DebugMon_Handler
20000034:       00000000       
20000038:       20003451        // PendSV_Handler
20000040:       20003451        // WWDG_IRQHandler
20000044:       20003451        // PVD_IRQHandler
20000048:       20003451        // TAMP_STAMP_IRQHandler
2000004c:       20003451        // RTC_WKUP_IRQHandler

<...>
20003400 <Reset_Handler>:

    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler: 
  ldr   sp, =_estack      /* set stack pointer */
20003400:       f8df d034       ldr.w   sp, [pc, #52]   ; 20003438 <LoopFillZerobss+0x14>

/* Copy the data segment initializers from flash to SRAM */ 
  movs  r1, #0

<...>
    .section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
20003450:       e7fe            b.n     20003450 <ADC_IRQHandler>


Соответственно, Default_Handler был назначен на все неописаные прерывания.

Таким образом, отладчик может может вывести имя ЛЮБОГО прерывания из неописаных в качестве Default'ного.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 янв 2018, 12:19 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Тогда так и пишите, что это Default Handler, который ведет у участок кода с зацикливанием.
В вашем случае это вот сюда:
Default_Handler:
Infinite_Loop:
b Infinite_Loop
Но не обязательно в обработчики HardFault. Тогда наоборот, чтобы поймать его, надо писать полезный в секцию Default Handler.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 янв 2018, 13:52 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 320
выяснил из за чего зависон, проблема в обработчике юсарт6 предложения NMEA0183, если есть у кого опыт, просмотрите плиз код, может где ошибка в алгоритме, ну в не вижу, где ошибка:
Код:
//=============================================================================
typedef enum
{
   NMEA0183_WAIT_TAIL = 0,
   NO_MESS
} usart_state_t;

volatile usart_state_t usart6_state = NO_MESS;
uint8_t USART6_Buf [ 128 ];
volatile uint8_t USART6_Idx = 0;
/* Create Rx/Tx Queues */
   usart6_RxQueue = xQueueCreate ( 128, sizeof( uint8_t ) );
   usart6_TxQueue = xQueueCreate ( 128, sizeof( uint8_t ) );

/* Enable the USART2 Interrupt */
   NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY+1
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init ( &NVIC_InitStructure );

void USART6_IRQHandler ( void )
{
   portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
   uint8_t ISR6cCharRX;
   uint8_t ISR6cCharTX;

//=============================================================================
   if ( USART_GetITStatus ( USART6, USART_IT_TXE ) == SET )
   {
      if ( xQueueReceiveFromISR ( usart6_TxQueue, &ISR6cCharTX, &xHigherPriorityTaskWoken ) == pdTRUE )
      {
         USART_SendData ( USART6, ISR6cCharTX );
      }
      else
      {
         USART_ITConfig ( USART6, USART_IT_TXE, DISABLE );
      }
   }
//обработчик nmea0183
        if ( USART_GetITStatus ( USART6, USART_IT_RXNE ) == SET )
   {
      ISR6cCharRX = (uint8_t) ( USART_ReceiveData ( USART6 ) );

         switch ( usart6_state )
         {
            case NO_MESS:
            {
               if ( ISR6cCharRX == '$' )
               {
                  USART6_Idx = 0;
                  memset ( USART6_Buf, 0, USART6_SIZE );
                  USART6_Buf[USART6_Idx++] = ISR6cCharRX;
                  xTimerStartFromISR ( xIntervalTimer_NMEA, &xHigherPriorityTaskWoken );
                  usart6_state = NMEA0183_WAIT_TAIL;
               }
            } break;

            case NMEA0183_WAIT_TAIL:
            {
               if ( ( USART6_Buf[USART6_Idx-1] == 0x0D ) && (ISR6cCharRX == 0x0A) &&\
                     ( USART6_Idx > 0) && ( USART6_Idx <= MAX_len_NMEA0183) )
               {
                  USART6_Buf[USART6_Idx++] = ISR6cCharRX;

                  xTimerStopFromISR ( xIntervalTimer_NMEA, &xHigherPriorityTaskWoken );

                  usart6_state = NO_MESS;
                  xSemaphoreGiveFromISR ( xSemaphore_usart6, &xHigherPriorityTaskWoken );
               }
               else if ( USART6_Idx <= USART6_SIZE )
               {
                  USART6_Buf[USART6_Idx++] = ISR6cCharRX;
                  xTimerResetFromISR ( xIntervalTimer_NMEA, &xHigherPriorityTaskWoken );
                  usart6_state = NMEA0183_WAIT_TAIL;
               }
               else
               {
                  USART6_Idx = 0;
                  memset ( USART6_Buf, 0, USART6_SIZE );
                  usart6_state = NO_MESS;
                  xTimerStopFromISR ( xIntervalTimer_NMEA, &xHigherPriorityTaskWoken );
               }
            } break;

            default:
            {
               USART6_Idx = 0;
               memset ( USART6_Buf, 0, USART6_SIZE );
               usart6_state = NO_MESS;
               xTimerStopFromISR ( xIntervalTimer_NMEA, &xHigherPriorityTaskWoken );
            }
         }
      }
// выход из обработчика прерывания
   portEND_SWITCHING_ISR ( xHigherPriorityTaskWoken );
}

ну и в задаче уже разбор предложения:
Код:
void Task_usart6 ( void *pvParameters )
{
   uint8_t Buf_local [ SIZE_buf ];
   uint8_t Buf_local_idx = 0;

   for ( ;; )
   {
      xSemaphoreTake ( xSemaphore_usart6, portMAX_DELAY );

// обнуляем локальный буфер
      memset ( Buf_local, 0, SIZE_buf );
      Buf_local_idx = 0;

// копируем в Buf_local полностью принятую строку NMEA0183
      Buf_local_idx = USART6_Idx;
      memcpy ( Buf_local, USART6_Buf, Buf_local_idx );

      usart2_Put ( Buf_local, Buf_local_idx,  xNoBlock ); // для теста что принимается

// разбираем строку из Buf_local, если строка не соответствует NMEA0183, обнуляем локальный массив
      if ( ( nmea_parser ( Buf_local )) == -1 )
      {
         memset ( Buf_local, 0, SIZE_buf );
         Buf_local_idx = 0;
         usart6_state = NO_MESS;
      }
      else
      {
/*                разбор и обработка*/
                 }

xIntervalTimer_NMEA - это защитный програмный таймер, если вдруг предложение оборвётся и не будет получено полностью, что бы сбросить приёмный массив в нули:
Код:
//=============================================================================
// Функция защитного интервального таймера.
//=============================================================================
void IntervalFunction_NMEA_2s ( TimerHandle_t xIntervalTimer_NMEA_2s )
{
   xIntervalTimer_NMEA_2s = 0;

   USART6_Idx = 0;
   memset ( USART6_Buf, 0, USART6_SIZE );

   usart6_state = NO_MESS;

   xTimerStop ( xIntervalTimer_NMEA, 0 );

   return;
}/*end IntervalFunction_NMEA_2s*/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 янв 2018, 21:47 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 60
Откуда: Омск
BusMaster писал(а):
Тогда так и пишите, что это Default Handler, который ведет у участок кода с зацикливанием.
В вашем случае это вот сюда:
Default_Handler:
Infinite_Loop:
b Infinite_Loop
Но не обязательно в обработчики HardFault. Тогда наоборот, чтобы поймать его, надо писать полезный в секцию Default Handler.

Я это к тому, что любые неописаные (не замещёные пользовательскими заголовками) обработчики прерываний будут ссылаться на одно и то же место, которое в отладчике запросто будет названо WWDG_IRQHandler'ом.

Сам не раз на эти грабли наступал, потому чтобы найти точную причину - пришлось делать заглушки на все прерывания.

Volldemar писал(а):
выяснил из за чего зависон, проблема в обработчике юсарт6 предложения NMEA0183, если есть у кого опыт, просмотрите плиз код, может где ошибка в алгоритме, ну в не вижу, где ошибка

Проверьте, что в момент прерывания у Вас уже созданы ВСЕ объекты - в частности семафоры, таймеры и очереди. При обращении и попытке разыменовывания нулевого указателя - HardFault - обеспечен.

Попробуйте в прерывании пройтись отладкой по шагам и точнее определить место выпадения.

По возможности используйте DMA для приёма сообщений.
Как понимаю, строка передаётся потоком, а не по символу (с паузами). Если это действительно так - то все данные сразу (целую строку) можно получить при помощи DMA и прерывания по IDLE на линии приёмника. Ядро будет выполнять в это время какие-то другие действия.

Чему равна константа USART6_SIZE ? Может ли быть выход за границы массива и затирание стэка?
Осторожнее с memset - ошибки входных данных эта функция не прощает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: зависания
СообщениеДобавлено: 17 янв 2018, 22:16 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 1371
Определите где зависает - в прерывании или в обработчике.
Ну и логику надо подтянуть немного.
Диаграмму нарисуйте что ли для лучшего понимания.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 21 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB