i tried to condensate the issue in the title. A little background:
I have an application running on a dsPIC33CK64MP502 (dsPIC33CK core, 64k Flash, 8k RAM)
The FreeRTOS port is the v9.0.0 present on the microchip Github: GitHub - MicrochipTech/freeRTOS-PIC24-dsPIC-PIC32MM: This repository contains the freeRTOS demos for Microchip device families like PIC24, dsPIC33E, dsPIC33F , dsPIC33C and PIC32MM.
I should mention that i do not use the Heap, all kernel objects are allocated statically and all interrupts that deal with kernel objects have the same priority as the kernel timer interrupt.
The application uses CANBus for communication and in order to test its robustness i began flooding the bus with frames that have an ID that would be accepted by the application.
The sequence of operations is
CAN Interrupt happens.
If RX Interrupt check which FIFO has data available, read the data into a CAN Frame structure (declared as a local variable inside the interrupt) then put the frame inside a queue (using the ISR version of the call).
End of CAN Interrupt.
There are multiple queues, the number of the FIFO decides which queue will be filled.
There are other tasks that await data from the queues.
I’ve noticed that when the bus traffic is reasonable (occasional bursts, spaced some tens of ms) the Can Frame variable inside the ISR is always allocated at the same address (and it seems to be inside the IDLE Task stack)
when there bus is being flooded by a constant stream of frames every 1ms the can frame variable is placed at an higher address.
Up to some point (doesn’t happen sistematically) until an Address error trap is generated.
Unfortunately i can’t investigate the trap as the stack pointer is corrupted (shows 0x04 instead of a valid address, greater than 0x1000) and i haven’t been able to find the exact moment when the stack is corrupted.
I assume the problem lies somewhere in the CAN interrupt and in the context switching.
Here are the questions:
1)Am i correct in my assumptions that the interrupt uses the IDLE Task Stack?
2)If so, can i change the stack to the “CAN Task”?
3)I am wondering why the address of the Can Frame variable in the ISR changes depending on the Interrupt rate, what could be a reason for it? because i think i might be overflowing the IDLE Task stack even though the kernel doesn’t detect the overflow
My freeRTOSConfig.h file:
#define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 #define configTICK_RATE_HZ ((TickType_t)1000) #define configCPU_CLOCK_HZ ((unsigned long)4000000) //Fosc/2 #define configMAX_PRIORITIES (4) #define configMINIMAL_STACK_SIZE (300) //#define configTOTAL_HEAP_SIZE ((size_t)5000) #define configMAX_TASK_NAME_LEN (16) #define configQUEUE_REGISTRY_SIZE (16) #define configUSE_16_BIT_TICKS 1 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 13 #define configTIMER_QUEUE_LENGTH 4 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE #define configUSE_CO_ROUTINES 0 /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xSemaphoreGetMutexHolder 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define configKERNEL_INTERRUPT_PRIORITY 0x01 #define pdMS_TO_TICKS(xTimeInMs) ((TickType_t)(((TickType_t)(xTimeInMs))) * (((TickType_t)configTICK_RATE_HZ)/(TickType_t)1000)) #define configCHECK_FOR_STACK_OVERFLOW 2 #define configASSERT( x ) __conditional_software_breakpoint( x ) //Priorities #define appPRIORITY_IDLE 1 #define appPRIORITY_LOW 2 #define appPRIORITY_MID 2 #define appPRIORITY_HIGH 3