реклама на сайте
подробности

 
 
> Сбой системы при использовании вложенных прерываний
grv
сообщение Jan 14 2016, 17:46
Сообщение #1


Частый гость
**

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



Есть довольно увесистый проект stm32f207+freertos 8.0.1+Keil 4.6
Вылетает в bus fault. Причем только после того как начинаю включать вложенные прерывания. Пока все прерывания сидят в
приоритете 15(Тик ртоса и мои таймера/уарты) работает нормально. Как только любому из моих прерываний даю приоритет 14(вывел на джампер GPIOE->IDR & Key_K1) либо всем, сразу валится в эксепшин, причем не сразу а через 5-10 мин как "звезды станут в ряд"

Дошел до следующего, в процедуре xPortPendSVHandler в pxCurrentTCB после переключения контекста попадает NULL,
далее подтягивается с нулевого адреса начальное значение стека MSP вместо стека задачи, и при попытке восстановить стек задачи
с адреса 0x20020000 валится в BUS FAULT (это я спецом под стек выделил все оставшееся ОЗУ, до этого валилось в USAGE FAULT
когда восстанавливало стек из неиспользуемого места ОЗУ)

Код
__asm void xPortPendSVHandler( void )
{
    extern uxCriticalNesting;
    extern pxCurrentTCB;
    extern vTaskSwitchContext;

    PRESERVE8

    mrs r0, psp
    isb

    ldr    r3, =pxCurrentTCB        /* Get the location of the current TCB. */
    ldr    r2, [r3]

    stmdb r0!, {r4-r11}            /* Save the remaining registers. */
    str r0, [r2]                /* Save the new top of stack into the first member of the TCB. */

    stmdb sp!, {r3, r14}
    mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
    msr basepri, r0
    bl vTaskSwitchContext
    mov r0, #0
    msr basepri, r0
    ldmia sp!, {r3, r14}

    ldr r1, [r3]
; ***************my start
    cmp R1,#0
    bne l22
    nop;-------------------------------------------------------- Здесь поставил бреакпоинт
    nop
l22    

; ***************my finish
    
    ldr r0, [r1]                /* The first item in pxCurrentTCB is the task top of stack. */
;----------------Вылетает при  следующей команде
; R0=0x20020000  - следующий адрес за  внутренним ОЗУ
    ldmia r0!, {r4-r11}            /* Pop the registers and the critical nesting count. */
    msr psp, r0
    isb
    bx r14
    nop
}



Настройка прерываний


При старте до старта ртоса
Код
   RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 4 preeptive  4 subpriority


Код
#define configKERNEL_INTERRUPT_PRIORITY         255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     191 /* equivalent to 0xb0, or priority 11. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY    15


Конфигурация таймера(ов) Используются как внешние прерывания по уровню.
Код
void Tim9_IT_init (void)
{
    
    TIM_TimeBaseInitTypeDef timStruct;
    TIM_ICInitTypeDef timicStruct;
    NVIC_InitTypeDef nvicStructure;
    
    // Alternative function
    GPIOE->AFR[0] &= ~(GPIO_AFRL_AFRL6  );
    GPIOE->AFR[0] |= ((GPIO_AFRL_AFRL6 & 0x33333333) ); // PE6 - AF3
    
    GPIOE->MODER&=~GPIO_MODER_MODER6;
    GPIOE->MODER|=GPIO_MODER_MODER6_1;
    
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
    timStruct.TIM_Prescaler=0;
    timStruct.TIM_CounterMode=TIM_CounterMode_Up;
    timStruct.TIM_Period=10;
    timStruct.TIM_ClockDivision=TIM_CKD_DIV1;
    timStruct.TIM_RepetitionCounter=0; // doesn't matter
    TIM_TimeBaseInit(TIM9, &timStruct);
    
    
        // Gated mode
    //timicStruct.TIM_Channel=TIM_Channel_1;
    timicStruct.TIM_Channel=TIM_Channel_2;
    timicStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;
    timicStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
    timicStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
    timicStruct.TIM_ICFilter=0;
    TIM_ICInit(TIM9,&timicStruct);
    
    
    //TIM_SelectInputTrigger(TIM9,TIM_TS_TI1FP1);
    TIM_SelectInputTrigger(TIM9,TIM_TS_TI2FP2);
    TIM_SelectSlaveMode(TIM9,TIM_SlaveMode_Gated);
    
       //5. Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update)
    
//    TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
//    TIM_ITConfig(TIM4, TIM_IT_Update,ENABLE);
    
    // interrupt
    
       //4. Enable the NVIC if you need to generate the update interrupt.
            
    nvicStructure.NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn;
        if (GPIOE->IDR & Key_K1)    
        {
            nvicStructure.NVIC_IRQChannelPreemptionPriority = 15;
        }
        else
        {
            nvicStructure.NVIC_IRQChannelPreemptionPriority = 14;
        }
    nvicStructure.NVIC_IRQChannelSubPriority = 0;
    nvicStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicStructure);
            
       //6. Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
            
  TIM_Cmd(TIM9,ENABLE);
    
}


Стеки задач с запасом где то минимум на 50 байт (видно по статистике когда нет вложенных прерываний, проект живет сутками)
Стек MSP вообще сейчас вся оставшаяся память - 7кб
Куча стартапа - 1кб, но я так понимаю она используется только при либовских Malloc которую я не использую. Вместо них я
использую ртосовскую, там где то свободных 10кб.


Собственно вопрос , что теперь с этим делать и куда рыть ? Каким образом в pxCurrentTCB может попасть 0 ? В моем понимании
если даже все мои задачи в ожидании , должна крутиться Idle ?

Сообщение отредактировал grv - Jan 14 2016, 17:46
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SMaster
сообщение Jan 15 2016, 02:38
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 9-03-06
Пользователь №: 15 099



Я думаю, что с этим у вас все правильно, но все же на всякий случай: все обработчики прерываний, вызывающие API-шные функции операционки, используют специализированные функции с окончанием FromISR()? Все такие функции имеют приоритет 11 и выше (численно)?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.0137 секунд с 7
ELECTRONIX ©2004-2016