Hello.
I just tried to implement a basic synchronization mechanism.
In the main.c I have
static void prvTermTest (void *pvParameters );
static void prvTaskFeeder (void *pvParameters);
xSemaphoreHandle periodSemaHndl;
void main (void)
{
InitializeRTCC();
vSemaphoreCreateBinary(periodSemaHndl);
xSemaphoreTake(periodSemaHndl, 0);
myresult = xTaskCreate( prvTermTest, "Terminal", 500, NULL, tskIDLE_PRIORITY, &task3);
myresult = xTaskCreate( prvTaskFeeder, "TermFeeder", 200, NULL, tskIDLE_PRIORITY, &task2);
vTaskStartScheduler();
}
void InitializeRTCC (void)
{
RtccInit();
//wait for the SOSC to be actually running and RTCC to have its clock source
while(RtccGetClkStat()!=RTCC_CLK_ON);
//RTCC interrupt config
mRtccSetIntPriority(2, 3);
mRtccEnableInt();
//we created a global TIME variable at the beginning of the main.c
//here we set it to some value, doesn't have to mean a specific time
mytime.hour = 0x0;
mytime.min = 0x0;
mytime.sec = 0x0;
//we do the same for the global DATE variable
mydate.wday=0x1;
mydate.mday=0x1;
mydate.mon=0x1;
mydate.year=0x11;
//we assign the values to the RTCC
RtccSetTimeDate(mytime.l,mydate.l);
mytime.hour = 0x0;
mytime.min = 0x0;
mytime.sec = 0x1;
mydate.wday=0x1;
mydate.mday=0x1;
mydate.mon=0x1;
mydate.year=0x11;
//here we call the alarm setting macro with our values
RtccSetAlarmTimeDate(mytime.l,mydate.l);
//this is a usefull debug point: put a breakpoint here and watch if the values are what you expected them to be
RtccGetAlarmTimeDate(&mytime,&mydate);
//one alarm will do
RtccSetAlarmRpt(RTCC_RPT_HALF_SEC);
//enable the alarm
RtccAlarmEnable();
}
//RTCC interrupt service routine
void __ISR(_RTCC_VECTOR, ipl2) __RTCCInterrupt(void)
{
//this is just for testing: if you place a breakpoint here you can have a look at the passing time
//redundant, should already be set
//RtccAlarmDisable();
xHigherPriorityTaskWoken = pdFALSE;
// be sure to clear RTCC interrupt flag
mRTCCClearIntFlag();
RtccAlarmEnable();
//let the main cycles restart
if (tick==0)
{
tick=1;
xSemaphoreGiveFromISR(periodSemaHndl, xHigherPriorityTaskWoken);
}
else
tick=0;
if (xHigherPriorityTaskWoken != pdFALSE)
{
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
//this is the sleep flag, you may take actions based on its value
//meaning that the RTC may have risen an interrupt but the device may or
//may not have been sleeping, this tells you which
//RCONbits.SLEEP = 0;
//clear the sleeping led
//mPORTGSetBits(BIT_9);
}
static void prvTermTest(void* pvParameters)
{
term_Init(3);
while(1)
term_blink();
vTaskSuspend(task3);
}
static void prvTaskFeeder (void *pvParameters)
{
UINT8 counter = 0;
while(1)
{
xSemaphoreTake(periodSemaHndl, portMAX_DELAY);
MPL_LOGD("Counter %d",counter);
counter++;
}
}
What happens is that inside the call to xSemaphoreGiveFromISR, the code reaches line 855 of queue.c
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
traceQUEUE_SEND_FROM_ISR( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
/* If the queue is locked we do not alter the event list. This will
be done when the queue is unlocked later. */
if( pxQueue->xTxLock == queueUNLOCKED )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
contextswitch is required. */
==>*pxHigherPriorityTaskWoken = pdTRUE;
At this point execution jumps to the exception handler, with exception code 1C (which is outside the enumerated values) and this line corresponds to line 9D005130 reported below
852: {
853: /* The task waiting has a higher priority so record that a
854: contextswitch is required. */
855: *pxHigherPriorityTaskWoken = pdTRUE;
9D005128 8FC20028 LW V0, 40(S8)
9D00512C 24030001 ADDIU V1, ZERO, 1
9D005130 AC430000 SW V1, 0(V0)
9D005134 0B401454 J 0x9D005150
9D005138 00000000 NOP
I'm clueless to what is happening here.
The max priority in the FreeRTOSConfig.h is 5.
Without the semaphoregive inside the interrupt, the code runs fine (in fact this is the beginning of another project where I reused code working surely in another project).
I'm open to any suggestion.
I forgot: at the beginning of the main.c there is also (obviously, it wouldn't even compile otherwise)
static signed portBASE_TYPE xHigherPriorityTaskWoken;
I also tried putting the above line inside the RTCC ISR as per the examples, didn't change anything.
Ok I was missing the leading & in both xSemaphoreGive and portEND_SWITCHING_ISR.
Now it still crashes but on a different line.
void vListRemove( xListItem *pxItemToRemove )
{
xList * pxList;
==>pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
Am still trying to catch what exactly is causing this.
The currentTCB is already gibberish, so I'm having difficulties figuring what task caused the crash and why.
Ok it was just a memory problem: too less assigned to the task and it crashed.
Thank you anyway.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.