holyhope wrote on Monday, October 14, 2013:
Goodmorning to all.
there are some days that I try to fix a bug in my code with FreeRTOS.
I use MPLAB X V1.90 FreeRTOS without timers . (I try with another FreeRTOS version with timer and core-modified that I found on web, but the problem s the same)
uP: PIC32MX340F032H
I use one ModBus task and one ADC task to aquire a measure with an external ADC (on SPI)
Clock:
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_10, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config FCKSM = CSDCMD, FPBDIV = DIV_2, OSCIOFNC = OFF, POSCMOD = HS, IESO = OFF
#pragma config FSOSCEN = ON, FNOSC = PRIPLL, CP = OFF, BWP = ON
The code that I use to create the task and semaphore are:
void vCreateMBManageTask (void){ xTaskCreate( vMBProcess, "ModBusProcess", (configMINIMAL_STACK_SIZE)*3, NULL, tskIDLE_PRIORITY+2, NULL);} void vCreateMBManageSemaphore (void){ vSemaphoreCreateBinary ( xBinaryMBManage );} void vCreateADCManageTask (void){ xTaskCreate( vADCProcess, "ADCProcess", (configMINIMAL_STACK_SIZE)*3, NULL, tskIDLE_PRIORITY+1, NULL);} void vCreateADCManageSemaphore (void){ vSemaphoreCreateBinary ( xBinaryADCManage );}
the MB process is the same:
static void vMBProcess ( void *pvParameters ){ static portTickType TaskMBManageTick = DELAY_MSEC(95); static UCHAR *ucMBFrame; static UCHAR ucRcvAddress; static USHORT usLength; static UCHAR ucFunctionCode; static eMBException eException; UCHAR i; eMBEventType eEvent; eMBErrorCode eStatus = MB_ENOERR; xSemaphoreTake ( xBinaryMBManage, TaskMBManageTick ); for( ;; ) { if (xSemaphoreTake ( xBinaryMBManage, TaskMBManageTick ) == pdTRUE) { .....
the FreeRTOS config is that:
#define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) #define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000UL ) #define configPERIPHERAL_CLOCK_HZ ( ( unsigned long ) 25000000UL ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) #define configMINIMAL_STACK_SIZE ( 380 ) #define configISR_STACK_SIZE ( 400 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) 24000 )//( ( size_t ) 16000 ) #define configMAX_TASK_NAME_LEN ( 8 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 //#define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configQUEUE_REGISTRY_SIZE 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zeroto exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 /* The priority at which the tick interrupt runs. This should probably bekept at 1. */ #define configKERNEL_INTERRUPT_PRIORITY 0x01 /* The maximum interrupt priority from which FreeRTOS.org API functions canbe called. Only API functions that end in ...FromISR() can be used withininterrupts. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x03
The serial port is initialized in thi way: (RB14 is the direction for RS-485, ulBaudRate is 57600 Baud)
PORTSetPinsDigitalOut( IOPORT_B, BIT_14); PORTClearBits( IOPORT_B, BIT_14); // Resto configurazione UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY ); UARTSetFifoMode(UART2, UART_INTERRUPT_ON_TX_DONE | UART_INTERRUPT_ON_RX_NOT_EMPTY); UARTSetLineControl(UART2, mode); UARTSetDataRate(UART2, 25000000ul, ulBaudRate); UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); INTClearFlag(INT_SOURCE_UART_RX(UART2)); INTClearFlag(INT_SOURCE_UART_TX(UART2)); INTSetVectorPriority(INT_VECTOR_UART(UART2), INT_PRIORITY_LEVEL_5); INTSetVectorSubPriority(INT_VECTOR_UART(UART2), INT_SUB_PRIORITY_LEVEL_0); // Configure UART2 RX Interrupt INTEnable(INT_SOURCE_UART_RX(UART2), INT_ENABLED);
The UART interrupt: (I try with the wrapper with assembly code and this version, direct in the ISR )
//void __attribute__( (interrupt(ipl5), vector(_UART_2_VECTOR))) vMBInterruptWrapper( void ); void __ISR(_UART_2_VECTOR, ipl5) vMBInterruptHandler(void)[/code]
I debug the program and 2 or 3 times per second I send a packet ModBus with a dedicated C#-program.
My code responde to the packet until excpetion appears
What it happen is that, after some time, the code give exception with this value:
Expeption #7 (load/store exception)
EPC: 0x9D009528
At that program counter the code assemply is this:
175: pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 9D009504 8FC20010 LW V0, 16(S8) 9D009508 8C420008 LW V0, 8(V0) 9D00950C 8FC30010 LW V1, 16(S8) 9D009510 8C630004 LW V1, 4(V1) 9D009514 AC430004 SW V1, 4(V0) 176: 177: /* The list item knows which list it is in. Obtain the list from the list178: item. */ 179: pxList = ( xList * ) pxItemToRemove->pvContainer; 9D009518 8FC20010 LW V0, 16(S8) 9D00951C 8C420010 LW V0, 16(V0) 9D009520 AFC20000 SW V0, 0(S8) 180: 181: /* Make sure the index is left pointing to a valid item. */ 182: if( pxList->pxIndex == pxItemToRemove ) 9D009524 8FC20000 LW V0, 0(S8) 9D009528 8C430004 LW V1, 4(V0) 9D00952C 8FC20010 LW V0, 16(S8) 9D009530 14620005 BNE V1, V0, 0x9D009548 9D009534 00000000 NOP183: { 184: pxList->pxIndex = pxItemToRemove->pxPrevious; 9D009538 8FC20010 LW V0, 16(S8) 9D00953C 8C430008 LW V1, 8(V0) 9D009540 8FC20000 LW V0, 0(S8) 9D009544 AC430004 SW V1, 4(V0) 185: }
that is the C code corrisponding to the FreeRTOS internal code:
void vListRemove( xListItem *pxItemToRemove ){xList * pxList; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; /* The list item knows which list it is in. Obtain the list from the list item. */ pxList = ( xList * ) pxItemToRemove->pvContainer; /* Make sure the index is left pointing to a valid item. */ if( pxList->pxIndex == pxItemToRemove ) { pxList->pxIndex = pxItemToRemove->pxPrevious; } pxItemToRemove->pvContainer = NULL; ( pxList->uxNumberOfItems )--; }
the timer for timeout modbus (timeout for PKT recived) is this:
void __ISR(_TIMER_2_VECTOR, ipl5) Timer2Handler(void){ // every 100us (= 0.1msec) if (TickTimeoutMB_msecX10>0){ TickTimeoutMB_msecX10--; if(TickTimeoutMB_msecX10==0) {vMBTimerInterruptHandler();} }
timer defined here: (TIMER2_PERIOD= 2500)
OpenTimer2(T2_ON , TIMER2_PERIOD); INTEnable(INT_T2, INT_ENABLED); INTSetVectorPriority(INT_TIMER_2_VECTOR, INT_PRIORITY_LEVEL_5); INTSetVectorSubPriority(INT_TIMER_2_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
and routine called during timer 2 ISR on timeout:
BOOL xMBRTUTimerT35Expired( void ) { BOOL xNeedPoll = FALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdTRUE; switch ( eRcvState ) { -…….. } xSemaphoreGiveFromISR(xBinaryMBManage,&xHigherPriorityTaskWoken); return xNeedPoll; }
Conclusion:
I debug the program and 2 or 3 times per second I send a packet ModBus .
My code responde to the packet until excpetion appears
Expeption #7 (load/store exception)
EPC: 0x9D009528
Try:
I try to comment the task creation of the ADC process but there are no change on the behavior of the code.
If I try to modified the time of semaphoreGive to MB process the exception do not change but occurs before or after. If I use 1msec in few then one minute the exception appears If I use 95msec very much time. (I left uP all week end operate and yestorday eavening the exception occurs).
I can’t expand time to infinity… There is something wrong that I can’t find!
Help that I need! :
Some one have advice… please tell me! I do not know what else do…
If you want some other part of code or information please tell me and I will answer in a few than a hour!
Many thanks!
Massimiliano