cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault from HAL_DMA_ABORT_IT function

baydı.1
Associate III

Hello ,

I am trying to making a BLE application with triggering external interrupts that came from camera sensor. Normally my interrupt handlers worked just fine, however when I try to add BLE function, code getting hard fault.  Following lines in the function cause this fault. 

 HAL_DMA_Abort_IT(htim2.hdma[TIM_DMA_ID_UPDATE]);
__HAL_TIM_DISABLE_DMA(&htim2, TIM_DMA_UPDATE);

Is There a way to  abort DMA another way or how can I fix the this error? 

void EXTI2_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_IRQn 2 */

if((__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_2))&&(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2)==GPIO_PIN_SET))
{
__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_2);

HAL_DMA_Start_IT(htim2.hdma[TIM_DMA_ID_UPDATE], (uint32_t)&GPIOA->IDR, (uint32_t)&sRAM_frame_buffer[hsyncCount][640],640);

    __HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_UPDATE);
    if(hsyncCount<240)

    {

    hsyncCount++;
    }

    else

    {
//     APP_DBG_MSG("hsyncCount:%d \n",hsyncCount);
 //   HAL_NVIC_DisableIRQ(EXTI1_IRQn);
 //   HAL_NVIC_DisableIRQ(EXTI2_IRQn);
    hsyncCount=0;
    ble_flag=0;
    UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_DATA, CFG_SCH_PRIO_0);

    }

}

else if((__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_2))&&(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2)==GPIO_PIN_RESET))

{

__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_2);
HAL_DMA_Abort_IT(htim2.hdma[TIM_DMA_ID_UPDATE]);
__HAL_TIM_DISABLE_DMA(&htim2, TIM_DMA_UPDATE);


}
  /* USER CODE END EXTI2_IRQn 1 */

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

OK, so we are back to "debug the hard fault".  It can't be 2 lines that cause the hard fault.  It will be exactly 1 assembly instruction, associated with one of those lines.  See what it is, and what data it was accessing and what data was corrupted.  Is it only that one structure member that was corrupted, or multiple members?

Are you doing things with TIM2 outside the interrupt?  Maybe you have a conflict between main code and IRQ code.

Check stack size (RTOS? then stack sizes for each task), and heap size if you do malloc/free.  If you are using an RTOS AND doing mallc/free make sure there are mutexes/locks in heap access (this was broken in various CubeMX/IDE releases).

View solution in original post

8 REPLIES 8
Bob S
Principal

The answer to this is like the answer to all "why do I get this hard fault" questions: debug the hard fault and see WHY you are getting it.  For example, is it possible you are trying to abort a timer DMA that has not been started?  Or before the htim2 instance has been initialized?

Thank you for advice, htim2 is initialized properly and I am quite sure that DMA has been started before abort it. Also the code structure was working before opening Bluetooth middleware. 

Bob S
Principal

OK, so we are back to "debug the hard fault".  It can't be 2 lines that cause the hard fault.  It will be exactly 1 assembly instruction, associated with one of those lines.  See what it is, and what data it was accessing and what data was corrupted.  Is it only that one structure member that was corrupted, or multiple members?

Are you doing things with TIM2 outside the interrupt?  Maybe you have a conflict between main code and IRQ code.

Check stack size (RTOS? then stack sizes for each task), and heap size if you do malloc/free.  If you are using an RTOS AND doing mallc/free make sure there are mutexes/locks in heap access (this was broken in various CubeMX/IDE releases).

Hello Bob , 

           Thanks for your great reply. I reviewed my interrupts and data initilization. As a result DMA and TIM2 working properly. However, I still have a problem related to sequencer.   Here is my EXTI callback function that is used for sycronization with camera and taking data to write memory. 

void APP_BLE_RISING_FV_Action(void){
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
}

void APP_BLE_FALLING_FV_Action(void){
HAL_NVIC_DisableIRQ(EXTI2_IRQn);
HAL_NVIC_DisableIRQ(EXTI3_IRQn);
}

void APP_BLE_RISING_LV_Action(void){
DMA_Enable();
if(hsyncCount<240)
{
hsyncCount++;
}
else {

// uart_flag =1;
hsyncCount=0;
HAL_NVIC_DisableIRQ(EXTI0_IRQn);
HAL_NVIC_DisableIRQ(EXTI1_IRQn);
HAL_NVIC_DisableIRQ(EXTI2_IRQn);
HAL_NVIC_DisableIRQ(EXTI3_IRQn);
frame_complete=0;
UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_DATA, CFG_SCH_PRIO_0);

}
}

void APP_BLE_FALLING_LV_Action(void){
DMA_Disable();
}

 

After running this part once, I cannot add new task or run task in sequenecer. Indeed, until

" UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_DATA, CFG_SCH_PRIO_0);" line everthing working fine. Do you have any idea what I am missing?

Notes: "Are you doing things with TIM2 outside the interrupt?"  : no

"Check stack size (RTOS? then stack sizes for each task), and heap size if you do malloc/free" no RTOS 

void DMA_Enable(){

HAL_DMA_Start_IT(htim2.hdma[TIM_DMA_ID_UPDATE], (uint32_t)&GPIOA->IDR, (uint32_t)&sRAM_frame_buffer[hsyncCount][maxVSYNCArr],640);

__HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_UPDATE);




}




void DMA_Disable(){




HAL_DMA_Abort_IT(htim2.hdma[TIM_DMA_ID_UPDATE]);

__HAL_TIM_DISABLE_DMA(&htim2, TIM_DMA_UPDATE);




}
Bob S
Principal

> After running this part once, I cannot add new task or run task in sequenecer.

I am not sure what you mean.  Do you mean you cannot create new FreeRTOS tasks?  Do you mean no other existing FreeRTOS tasks execute?  Or is "sequencer" something other than the FreeRTOS scheduler?

> Indeed, until " UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_DATA, CFG_SCH_PRIO_0);" line
> everthing working fine. Do you have any idea what I am missing?

Then it would seem that UTIL_SEQ_SetTask() is the problem, no?  What does that function do?

baydı.1
Associate III

Sequencer is an optimized while loop. It takes tasks and then run it based on their priority one by one . I am not using FreeRTOS. 

>Then it would seem that UTIL_SEQ_SetTask() is the problem, no?  What does that function do? 

Yes but it works fine when I am disabling EXTI interrupts that process camera datas.After taking one image  , I am disabling those interrupts and try to set another task for execution. Somehow, It doesn't set this function, even I cannot connect the BLE device anymore from mobile phone. 

Bob S
Principal

> Somehow, it doesn't set this function

"Somehow"????? You've got a debugger, trace its execution and find out why.

Are the APP_BLE_RISING_FV_Action(), APP_BLE_FALLING_FV_Action(), APP_BLE_RISING_LV_Action() functions called from the interrupt handler(s)?  If so, whatever variables UTIL_SEQ_SetTask() is manipulating need to be declared "volatile" or the compiler may optimize them out of your sequencer loop.

Or you may be clobbering/overwriting data somewhere.  Again, use the debugger as much as possible.  If the code breaks when single-stepping due to IRQ timing, you may need to add some kind of logging in the interrupt functions (NOT printf) to trace execution.  See what UTIL_SEQ_SetTask() does, then see what your sequencer loop "sees".

Also, for EXTI interrupts I usually leave them enabled in the NVIC and enable/disable them in the EXTI peripheral via HAL_LL_EXTI_DisableIT_0_31() and HAL_LL_EXTI_EnableIT_0_31(), which just write to the EXTI->IMR.  Make sure you clear any pending interrupt before enabling.

Hello Bob, 

   The problem was related to writting image data to Sram properly. Instead of writing 640 line to buffer,I was writing 641 line and that was cause the hardfault. 

Many thanks for your great contriubitions.

(uint32_t)&sRAM_frame_buffer[hsyncCount][maxVSYNCArr]