void measureRunFunction(void *dataptr) { static tBoolean onFirstRun = true; static int rate; MeasureData *mData = (MeasureData *) dataptr; if (onFirstRun) { initializeMeasureTask(); rate = *(int*) cbGet(mData->pulseRateRaw); onFirstRun = false; } // capture pulse rate if (IS_PULSE_CYCLE) { // Divide by two so raw pulse rate matches frequency rate = pulseRate/2; pulseRate = 0; } // only run on major cycle short measureSelect = *(mData->measureSelect); if(measureSelect == 0 || measureSelect == 1) { setTemp(mData->temperatureRaw); } if(measureSelect == 0 || measureSelect == 2) { setBloodPress(mData->systolicPressRaw, mData->diastolicPressRaw); } if(measureSelect == 0 || measureSelect == 3) { int prev = *(int*) cbGet(mData->pulseRateRaw); // Only save if +- 15% if (rate < prev*0.85 || rate > prev*1.15) { cbAdd(mData->pulseRateRaw, (void *)&rate); } } if(measureSelect == 0 || measureSelect == 4) { vTaskResume(ekgCaptureHandle); } else { vTaskSuspend(ekgCaptureHandle); } vTaskResume(computeHandle); // run the compute task #if DEBUG_MEASURE char num[30]; int temp = *(int *)cbGet(mData->temperatureRaw); int sys = *(int *)cbGet(mData->systolicPressRaw); int dia = *(int *)cbGet(mData->diastolicPressRaw); int pulse = *(int *)cbGet(mData->pulseRateRaw); int batt = global.batteryState; usnprintf(num, 30, "<-- MEASURE DEBUG -->"); RIT128x96x4StringDraw(num, 0, 0, 15); usnprintf(num, 30, "Raw temp: %d ", temp); RIT128x96x4StringDraw(num, 0, 10, 15); usnprintf(num, 30, "Raw Syst: %d ", sys); RIT128x96x4StringDraw(num, 0, 20, 15); usnprintf(num, 30, "Raw Dia: %d ", dia); RIT128x96x4StringDraw(num, 0, 30, 15); usnprintf(num, 30, "Raw Pulse: %d ", pulse); RIT128x96x4StringDraw(num, 0, 40, 15); usnprintf(num, 30, "Raw Batt: %d ", batt); RIT128x96x4StringDraw(num, 0, 50, 15); #endif }
static void prvLowPriorityPeekTask( void *pvParameters ) { xQueueHandle xQueue = ( xQueueHandle ) pvParameters; unsigned portLONG ulValue; for( ;; ) { /* Write some data to the queue. This should unblock the highest priority task that is waiting to peek data from the queue. */ ulValue = 0x11223344; if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) { /* We were expecting the queue to be empty so we should not of had a problem writing to the queue. */ xErrorDetected = pdTRUE; } /* By the time we get here the data should have been removed from the queue. */ if( uxQueueMessagesWaiting( xQueue ) != 0 ) { xErrorDetected = pdTRUE; } /* Write another value to the queue, again waking the highest priority task that is blocked on the queue. */ ulValue = 0x01234567; if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) { /* We were expecting the queue to be empty so we should not of had a problem writing to the queue. */ xErrorDetected = pdTRUE; } /* All the other tasks should now have successfully peeked the data. The data is still in the queue so we should be able to receive it. */ ulValue = 0; if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) { /* We expected to receive the data. */ xErrorDetected = pdTRUE; } if( ulValue != 0x01234567 ) { /* We did not receive the expected value. */ } /* Lets just delay a while as this is an intensive test as we don't want to starve other tests of processing time. */ vTaskDelay( qpeekSHORT_DELAY ); /* Unsuspend the other tasks so we can repeat the test - this time however not all the other tasks will peek the data as the high priority task is actually going to remove it from the queue. Send to front is used just to be different. As the queue is empty it makes no difference to the result. */ vTaskResume( xMediumPriorityTask ); vTaskResume( xHighPriorityTask ); vTaskResume( xHighestPriorityTask ); ulValue = 0xaabbaabb; if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) { /* We were expecting the queue to be empty so we should not of had a problem writing to the queue. */ xErrorDetected = pdTRUE; } /* This time we should find that the queue is empty. The high priority task actually removed the data rather than just peeking it. */ if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY ) { /* We expected to receive the data. */ xErrorDetected = pdTRUE; } /* Unsuspend the highest and high priority tasks so we can go back and repeat the whole thing. The medium priority task should not be suspended as it was not able to peek the data in this last case. */ vTaskResume( xHighPriorityTask ); vTaskResume( xHighestPriorityTask ); /* Lets just delay a while as this is an intensive test as we don't want to starve other tests of processing time. */ vTaskDelay( qpeekSHORT_DELAY ); } }
/* * Controller task as described above. */ static portTASK_FUNCTION( vCounterControlTask, pvParameters ) { uint32_t ulLastCounter; short sLoops; short sError = pdFALSE; /* Just to stop warning messages. */ ( void ) pvParameters; for( ;; ) { /* Start with the counter at zero. */ ulCounter = ( uint32_t ) 0; /* First section : */ /* Check the continuous count task is running. */ for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) { /* Suspend the continuous count task so we can take a mirror of the shared variable without risk of corruption. This is not really needed as the other task raises its priority above this task's priority. */ vTaskSuspend( xContinuousIncrementHandle ); { #if( INCLUDE_eTaskGetState == 1 ) { configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended ); } #endif /* INCLUDE_eTaskGetState */ ulLastCounter = ulCounter; } vTaskResume( xContinuousIncrementHandle ); #if( configUSE_PREEMPTION == 0 ) taskYIELD(); #endif #if( INCLUDE_eTaskGetState == 1 ) { configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); } #endif /* INCLUDE_eTaskGetState */ /* Now delay to ensure the other task has processor time. */ vTaskDelay( priSLEEP_TIME ); /* Check the shared variable again. This time to ensure mutual exclusion the whole scheduler will be locked. This is just for demo purposes! */ vTaskSuspendAll(); { if( ulLastCounter == ulCounter ) { /* The shared variable has not changed. There is a problem with the continuous count task so flag an error. */ sError = pdTRUE; } } xTaskResumeAll(); } /* Second section: */ /* Suspend the continuous counter task so it stops accessing the shared variable. */ vTaskSuspend( xContinuousIncrementHandle ); /* Reset the variable. */ ulCounter = ( uint32_t ) 0; #if( INCLUDE_eTaskGetState == 1 ) { configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); } #endif /* INCLUDE_eTaskGetState */ /* Resume the limited count task which has a higher priority than us. We should therefore not return from this call until the limited count task has suspended itself with a known value in the counter variable. */ vTaskResume( xLimitedIncrementHandle ); #if( configUSE_PREEMPTION == 0 ) taskYIELD(); #endif /* This task should not run again until xLimitedIncrementHandle has suspended itself. */ #if( INCLUDE_eTaskGetState == 1 ) { configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); } #endif /* INCLUDE_eTaskGetState */ /* Does the counter variable have the expected value? */ if( ulCounter != priMAX_COUNT ) { sError = pdTRUE; } if( sError == pdFALSE ) { /* If no errors have occurred then increment the check variable. */ portENTER_CRITICAL(); usCheckVariable++; portEXIT_CRITICAL(); } /* Resume the continuous count task and do it all again. */ vTaskResume( xContinuousIncrementHandle ); #if( configUSE_PREEMPTION == 0 ) taskYIELD(); #endif } }
static void vPrimaryBlockTimeTestTask( void *pvParameters ) { portBASE_TYPE xItem, xData; TickType_t xTimeWhenBlocking; TickType_t xTimeToBlock, xBlockedTime; ( void ) pvParameters; for( ;; ) { /********************************************************************* Test 1 Simple block time wakeup test on queue receives. */ for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { /* The queue is empty. Attempt to read from the queue using a block time. When we wake, ensure the delta in time is as expected. */ xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); xTimeWhenBlocking = xTaskGetTickCount(); /* We should unblock after xTimeToBlock having not received anything on the queue. */ if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) { xErrorOccurred = pdTRUE; } /* How long were we blocked for? */ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; if( xBlockedTime < xTimeToBlock ) { /* Should not have blocked for less than we requested. */ xErrorOccurred = pdTRUE; } if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) { /* Should not have blocked for longer than we requested, although we would not necessarily run as soon as we were unblocked so a margin is allowed. */ xErrorOccurred = pdTRUE; } } /********************************************************************* Test 2 Simple block time wakeup test on queue sends. First fill the queue. It should be empty so all sends should pass. */ for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } #if configUSE_PREEMPTION == 0 taskYIELD(); #endif } for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { /* The queue is full. Attempt to write to the queue using a block time. When we wake, ensure the delta in time is as expected. */ xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); xTimeWhenBlocking = xTaskGetTickCount(); /* We should unblock after xTimeToBlock having not received anything on the queue. */ if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) { xErrorOccurred = pdTRUE; } /* How long were we blocked for? */ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; if( xBlockedTime < xTimeToBlock ) { /* Should not have blocked for less than we requested. */ xErrorOccurred = pdTRUE; } if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) { /* Should not have blocked for longer than we requested, although we would not necessarily run as soon as we were unblocked so a margin is allowed. */ xErrorOccurred = pdTRUE; } } /********************************************************************* Test 3 Wake the other task, it will block attempting to post to the queue. When we read from the queue the other task will wake, but before it can run we will post to the queue again. When the other task runs it will find the queue still full, even though it was woken. It should recognise that its block time has not expired and return to block for the remains of its block time. Wake the other task so it blocks attempting to post to the already full queue. */ xRunIndicator = 0; vTaskResume( xSecondary ); /* We need to wait a little to ensure the other task executes. */ while( xRunIndicator != bktRUN_INDICATOR ) { /* The other task has not yet executed. */ vTaskDelay( bktSHORT_WAIT ); } /* Make sure the other task is blocked on the queue. */ vTaskDelay( bktSHORT_WAIT ); xRunIndicator = 0; for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { /* Now when we make space on the queue the other task should wake but not execute as this task has higher priority. */ if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } /* Now fill the queue again before the other task gets a chance to execute. If the other task had executed we would find the queue full ourselves, and the other task have set xRunIndicator. */ if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } if( xRunIndicator == bktRUN_INDICATOR ) { /* The other task should not have executed. */ xErrorOccurred = pdTRUE; } /* Raise the priority of the other task so it executes and blocks on the queue again. */ vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); /* The other task should now have re-blocked without exiting the queue function. */ if( xRunIndicator == bktRUN_INDICATOR ) { /* The other task should not have executed outside of the queue function. */ xErrorOccurred = pdTRUE; } /* Set the priority back down. */ vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); } /* Let the other task timeout. When it unblockes it will check that it unblocked at the correct time, then suspend itself. */ while( xRunIndicator != bktRUN_INDICATOR ) { vTaskDelay( bktSHORT_WAIT ); } vTaskDelay( bktSHORT_WAIT ); xRunIndicator = 0; /********************************************************************* Test 4 As per test 3 - but with the send and receive the other way around. The other task blocks attempting to read from the queue. Empty the queue. We should find that it is full. */ for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } } /* Wake the other task so it blocks attempting to read from the already empty queue. */ vTaskResume( xSecondary ); /* We need to wait a little to ensure the other task executes. */ while( xRunIndicator != bktRUN_INDICATOR ) { vTaskDelay( bktSHORT_WAIT ); } vTaskDelay( bktSHORT_WAIT ); xRunIndicator = 0; for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) { /* Now when we place an item on the queue the other task should wake but not execute as this task has higher priority. */ if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } /* Now empty the queue again before the other task gets a chance to execute. If the other task had executed we would find the queue empty ourselves, and the other task would be suspended. */ if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) { xErrorOccurred = pdTRUE; } if( xRunIndicator == bktRUN_INDICATOR ) { /* The other task should not have executed. */ xErrorOccurred = pdTRUE; } /* Raise the priority of the other task so it executes and blocks on the queue again. */ vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); /* The other task should now have re-blocked without exiting the queue function. */ if( xRunIndicator == bktRUN_INDICATOR ) { /* The other task should not have executed outside of the queue function. */ xErrorOccurred = pdTRUE; } vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); } /* Let the other task timeout. When it unblockes it will check that it unblocked at the correct time, then suspend itself. */ while( xRunIndicator != bktRUN_INDICATOR ) { vTaskDelay( bktSHORT_WAIT ); } vTaskDelay( bktSHORT_WAIT ); xPrimaryCycles++; } }
static BaseType_t prvSelectiveBitsTestMasterFunction( void ) { BaseType_t xError = pdFALSE; EventBits_t uxBit; /* Used in a test that blocks two tasks on various different bits within an event group - then sets each bit in turn and checks that the correct tasks unblock at the correct times. The two other tasks (xSyncTask1 and xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in this test. Both other tasks should start in the suspended state. */ if( eTaskGetState( xSyncTask1 ) != eSuspended ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eSuspended ) { xError = pdTRUE; } /* Test each bit in the byte individually. */ for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 ) { /* Resume both tasks. */ vTaskResume( xSyncTask1 ); vTaskResume( xSyncTask2 ); /* Now both tasks should be blocked on the event group. */ if( eTaskGetState( xSyncTask1 ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eBlocked ) { xError = pdTRUE; } /* Set one bit. */ xEventGroupSetBits( xEventGroup, uxBit ); /* Is the bit set in the first set of selective bits? If so the first sync task should have unblocked and returned to the suspended state. */ if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 ) { /* Task should not have unblocked. */ if( eTaskGetState( xSyncTask1 ) != eBlocked ) { xError = pdTRUE; } } else { /* Task should have unblocked and returned to the suspended state. */ if( eTaskGetState( xSyncTask1 ) != eSuspended ) { xError = pdTRUE; } } /* Same checks for the second sync task. */ if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 ) { /* Task should not have unblocked. */ if( eTaskGetState( xSyncTask2 ) != eBlocked ) { xError = pdTRUE; } } else { /* Task should have unblocked and returned to the suspended state. */ if( eTaskGetState( xSyncTask2 ) != eSuspended ) { xError = pdTRUE; } } } /* Ensure both tasks are blocked on the event group again, then delete the event group so the other tasks leave this portion of the test. */ vTaskResume( xSyncTask1 ); vTaskResume( xSyncTask2 ); /* Deleting the event group is the signal that the two other tasks should leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main part of their functionality. */ vEventGroupDelete( xEventGroup ); return xError; }
void correction_task() { ErrorStatus sensor_correct = ERROR; while (system.status == SYSTEM_UNINITIALIZED); while (sensor_correct == ERROR) { while (SensorMode != Mode_Algorithm) { uint8_t IMU_Buf[20] = {0}; static uint8_t BaroCnt = 0; /* 500Hz, Read Sensor ( Accelerometer, Gyroscope, Magnetometer ) */ MPU9150_Read(IMU_Buf); #ifdef Use_Barometer /* 100Hz, Read Barometer */ BaroCnt++; if (BaroCnt == SampleRateFreg / 100) { MS5611_Read(&Baro, MS5611_D1_OSR_4096); BaroCnt = 0; } #endif Acc.X = (s16)((IMU_Buf[0] << 8) | IMU_Buf[1]); Acc.Y = (s16)((IMU_Buf[2] << 8) | IMU_Buf[3]); Acc.Z = (s16)((IMU_Buf[4] << 8) | IMU_Buf[5]); Temp.T = (s16)((IMU_Buf[6] << 8) | IMU_Buf[7]); Gyr.X = (s16)((IMU_Buf[8] << 8) | IMU_Buf[9]); Gyr.Y = (s16)((IMU_Buf[10] << 8) | IMU_Buf[11]); Gyr.Z = (s16)((IMU_Buf[12] << 8) | IMU_Buf[13]); Mag.X = (s16)((IMU_Buf[15] << 8) | IMU_Buf[14]); Mag.Y = (s16)((IMU_Buf[17] << 8) | IMU_Buf[16]); Mag.Z = (s16)((IMU_Buf[19] << 8) | IMU_Buf[18]); /* Offset */ Acc.X -= Acc.OffsetX; Acc.Y -= Acc.OffsetY; Acc.Z -= Acc.OffsetZ; Gyr.X -= Gyr.OffsetX; Gyr.Y -= Gyr.OffsetY; Gyr.Z -= Gyr.OffsetZ; Mag.X *= Mag.AdjustX; Mag.Y *= Mag.AdjustY; Mag.Z *= Mag.AdjustZ; correct_sensor(); vTaskDelay(2); } if ((AngE.Roll < 0.1) && (AngE.Pitch < 0.1) && (NumQ.q0 < 1) && (NumQ.q1 < 1) && (NumQ.q2 < 1) && (NumQ.q3 < 1)) { sensor_correct = SUCCESS ; } else { SensorMode = Mode_GyrCorrect; sensor_correct = ERROR ; } LED_Toggle(LED_G); vTaskDelay(200); } SetLED(LED_G, DISABLE); vTaskResume(FlightControl_Handle); vTaskDelete(NULL); }
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ) { /* Take the mutex. It should be available now. */ if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) { xErrorDetected = pdTRUE; } /* Set the guarded variable to a known start value. */ ulGuardedVariable = 0; /* This task's priority should be as per that assigned when the task was created. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) { xErrorDetected = pdTRUE; } /* Now unsuspend the high priority task. This will attempt to take the mutex, and block when it finds it cannot obtain it. */ vTaskResume( xHighPriorityMutexTask ); #if configUSE_PREEMPTION == 0 taskYIELD(); #endif /* Ensure the task is reporting its priority as blocked and not suspended (as it would have done in versions up to V7.5.3). */ #if( INCLUDE_eTaskGetState == 1 ) { configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked ); } #endif /* INCLUDE_eTaskGetState */ /* The priority of the high priority task should now have been inherited as by now it will have attempted to get the mutex. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) { xErrorDetected = pdTRUE; } /* Now unsuspend the medium priority task. This should not run as the inherited priority of this task is above that of the medium priority task. */ vTaskResume( xMediumPriorityMutexTask ); /* If the medium priority task did run then it will have incremented the guarded variable. */ if( ulGuardedVariable != 0 ) { xErrorDetected = pdTRUE; } /* Take the local mutex too, so two mutexes are now held. */ if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS ) { xErrorDetected = pdTRUE; } /* When the local semaphore is given back the priority of this task should not yet be disinherited because the shared mutex is still held. This is a simplification to allow FreeRTOS to be integrated with middleware that attempts to hold multiple mutexes without bloating the code with complex algorithms. It is possible that the high priority mutex task will execute as it shares a priority with this task. */ if( xSemaphoreGive( xLocalMutex ) != pdPASS ) { xErrorDetected = pdTRUE; } #if configUSE_PREEMPTION == 0 taskYIELD(); #endif /* The guarded variable is only incremented by the medium priority task, which still should not have executed as this task should remain at the higher priority, ensure this is the case. */ if( ulGuardedVariable != 0 ) { xErrorDetected = pdTRUE; } if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) { xErrorDetected = pdTRUE; } /* Now also give back the shared mutex, taking the held count back to 0. This time the priority of this task should be disinherited back to the priority at which it was created. This means the medium priority task should execute and increment the guarded variable. When this task next runs both the high and medium priority tasks will have been suspended again. */ if( xSemaphoreGive( xMutex ) != pdPASS ) { xErrorDetected = pdTRUE; } #if configUSE_PREEMPTION == 0 taskYIELD(); #endif /* Check the guarded variable did indeed increment... */ if( ulGuardedVariable != 1 ) { xErrorDetected = pdTRUE; } /* ... and that the priority of this task has been disinherited to genqMUTEX_LOW_PRIORITY. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) { xErrorDetected = pdTRUE; } }
static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) { EventBits_t uxBits; /* The three tasks that take part in the synchronisation (rendezvous) are expected to be in the suspended state at the start of the test. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eSuspended ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eSuspended ) { xError = pdTRUE; } /* Try a synch with no other tasks involved. First set all the bits other than this task's bit. */ xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); /* Then wait on just one bit - the bit that is being set. */ uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */ portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ /* A sync with a max delay should only exit when all the synchronise bits are set...check that is the case. In this case there is only one sync bit anyway. */ if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT ) { xError = pdTRUE; } /* ...but now the sync bits should be clear again, leaving all the other bits set (as only one bit was being waited for). */ if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ) { xError = pdTRUE; } /* Clear all the bits to zero again. */ xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); if( xEventGroupGetBits( xEventGroup ) != 0 ) { xError = pdTRUE; } /* Unsuspend the other tasks then check they have executed up to the synchronisation point. */ vTaskResume( xTestSlaveTaskHandle ); vTaskResume( xSyncTask1 ); vTaskResume( xSyncTask2 ); if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eBlocked ) { xError = pdTRUE; } /* Set this task's sync bit. */ uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */ portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ /* A sync with a max delay should only exit when all the synchronise bits are set...check that is the case. */ if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) { xError = pdTRUE; } /* ...but now the sync bits should be clear again. */ if( xEventGroupGetBits( xEventGroup ) != 0 ) { xError = pdTRUE; } /* The other tasks should now all be suspended again, ready for the next synchronisation. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eSuspended ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eSuspended ) { xError = pdTRUE; } /* Sync again - but this time set the last necessary bit as the highest priority task, rather than the lowest priority task. Unsuspend the other tasks then check they have executed up to the synchronisation point. */ vTaskResume( xTestSlaveTaskHandle ); vTaskResume( xSyncTask1 ); vTaskResume( xSyncTask2 ); if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eBlocked ) { xError = pdTRUE; } /* Raise the priority of this task above that of the other tasks. */ vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 ); /* Set this task's sync bit. */ uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); /* A sync with a max delay should only exit when all the synchronisation bits are set... */ if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) { xError = pdTRUE; } /* ...but now the sync bits should be clear again. */ if( xEventGroupGetBits( xEventGroup ) != 0 ) { xError = pdTRUE; } /* The other tasks should now all be in the ready state again, but not executed yet as this task still has a higher relative priority. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eReady ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eReady ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eReady ) { xError = pdTRUE; } /* Reset the priority of this task back to its original value. */ vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY ); /* Now all the other tasks should have reblocked on the event bits to test the behaviour when the event bits are deleted. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask1 ) != eBlocked ) { xError = pdTRUE; } if( eTaskGetState( xSyncTask2 ) != eBlocked ) { xError = pdTRUE; } return xError; }
void os_resumeTask(xTaskHandle xHandle) { vTaskResume(xHandle); }
/*--------------------------------------------------------------------------------------- Name: osal_task_resume Purpose: resumes a suspended task Parameters: task_handle Handle to the task being readied. returns: OSAL_ERROR if error OSAL_SUCCESS if success ---------------------------------------------------------------------------------------*/ void osal_task_resume( void **task_handle ) { vTaskResume( task_handle ); }
void task_Resume(int idx){ vTaskResume(RTOStasks[idx].handle); }
void Task::resume() { vTaskResume(_hnd); }
static void prvRecursiveMutexPollingTask( void *pvParameters ) { /* Just to remove compiler warning. */ ( void ) pvParameters; for( ;; ) { /* Keep attempting to obtain the mutex. We should only obtain it when the blocking task has suspended itself, which in turn should only happen when the controlling task is also suspended. */ if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS ) { /* Is the blocking task suspended? */ if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) ) { xErrorOccurred = pdTRUE; } else { /* Keep count of the number of cycles this task has performed so a stall can be detected. */ uxPollingCycles++; /* We can resume the other tasks here even though they have a higher priority than the polling task. When they execute they will attempt to obtain the mutex but fail because the polling task is still the mutex holder. The polling task (this task) will then inherit the higher priority. The Blocking task will block indefinitely when it attempts to obtain the mutex, the Controlling task will only block for a fixed period and an error will be latched if the polling task has not returned the mutex by the time this fixed period has expired. */ vTaskResume( xBlockingTaskHandle ); #if configUSE_PREEMPTION == 0 taskYIELD(); #endif vTaskResume( xControllingTaskHandle ); #if configUSE_PREEMPTION == 0 taskYIELD(); #endif /* The other two tasks should now have executed and no longer be suspended. */ if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) ) { xErrorOccurred = pdTRUE; } /* Release the mutex, disinheriting the higher priority again. */ if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) { xErrorOccurred = pdTRUE; } #if configUSE_PREEMPTION == 0 taskYIELD(); #endif } } #if configUSE_PREEMPTION == 0 { taskYIELD(); } #endif } }
static void prvLowPriorityMutexTask( void *pvParameters ) { xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; #ifdef USE_STDIO void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); const portCHAR * const pcTaskStartMsg = "Fast mutex with priority inheritance test started.\r\n"; /* Queue a message for printing to say the task has started. */ vPrintDisplayMessage( &pcTaskStartMsg ); #endif ( void ) pvParameters; for( ;; ) { /* Take the mutex. It should be available now. */ if( xSemaphoreAltTake( xMutex, genqNO_BLOCK ) != pdPASS ) { xErrorDetected = pdTRUE; } /* Set our guarded variable to a known start value. */ ulGuardedVariable = 0; /* Our priority should be as per that assigned when the task was created. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) { xErrorDetected = pdTRUE; } /* Now unsuspend the high priority task. This will attempt to take the mutex, and block when it finds it cannot obtain it. */ vTaskResume( xHighPriorityMutexTask ); /* We should now have inherited the prioritoy of the high priority task, as by now it will have attempted to get the mutex. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) { xErrorDetected = pdTRUE; } /* We can attempt to set our priority to the test priority - between the idle priority and the medium/high test priorities, but our actual prioroity should remain at the high priority. */ vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) { xErrorDetected = pdTRUE; } /* Now unsuspend the medium priority task. This should not run as our inherited priority is above that of the medium priority task. */ vTaskResume( xMediumPriorityMutexTask ); /* If the did run then it will have incremented our guarded variable. */ if( ulGuardedVariable != 0 ) { xErrorDetected = pdTRUE; } /* When we give back the semaphore our priority should be disinherited back to the priority to which we attempted to set ourselves. This means that when the high priority task next blocks, the medium priority task should execute and increment the guarded variable. When we next run both the high and medium priority tasks will have been suspended again. */ if( xSemaphoreAltGive( xMutex ) != pdPASS ) { xErrorDetected = pdTRUE; } /* Check that the guarded variable did indeed increment... */ if( ulGuardedVariable != 1 ) { xErrorDetected = pdTRUE; } /* ... and that our priority has been disinherited to genqMUTEX_TEST_PRIORITY. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) { xErrorDetected = pdTRUE; } /* Set our priority back to our original priority ready for the next loop around this test. */ vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); /* Just to show we are still running. */ ulLoopCounter2++; #if configUSE_PREEMPTION == 0 taskYIELD(); #endif } }
// use this function to resume the task void SEQ_TASK_PatternResume(void) { vTaskResume(xPatternHandle); }
static void prvEventControllerTask( void *pvParameters ) { const char * const pcTaskStartMsg = "Multi event controller task started.\r\n"; portBASE_TYPE xDummy = 0; /* Just to stop warnings. */ ( void ) pvParameters; vPrintDisplayMessage( &pcTaskStartMsg ); for( ;; ) { /* All tasks are blocked on the queue. When a message is posted one of the two tasks that share the highest priority should unblock to read the queue. The next message written should unblock the other task with the same high priority, and so on in order. No other task should unblock to read data as they have lower priorities. */ prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); /* For the rest of these tests we don't need the second 'highest' priority task - so it is suspended. */ vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); /* Now suspend the other highest priority task. The medium priority task will then be the task with the highest priority that remains blocked on the queue. */ vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); /* This time, when we post onto the queue we will expect the medium priority task to unblock and preempt us. */ prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); /* Now try resuming the highest priority task while the scheduler is suspended. The task should start executing as soon as the scheduler is resumed - therefore when we post to the queue again, the highest priority task should again preempt us. */ vTaskSuspendAll(); vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); xTaskResumeAll(); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); /* Now we are going to suspend the high and medium priority tasks. The low priority task should then preempt us. Again the task suspension is done with the whole scheduler suspended just for test purposes. */ vTaskSuspendAll(); vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); xTaskResumeAll(); prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); /* Do the same basic test another few times - selectively suspending and resuming tasks and each time calling prvCheckTaskCounters() passing to the function the number of the task we expected to be unblocked by the post. */ vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); vTaskSuspendAll(); /* Just for test. */ vTaskSuspendAll(); /* Just for test. */ vTaskSuspendAll(); /* Just for even more test. */ vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); xTaskResumeAll(); xTaskResumeAll(); xTaskResumeAll(); prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); /* Now a slight change, first suspend all tasks. */ vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); /* Now when we resume the low priority task and write to the queue 3 times. We expect the low priority task to service the queue three times. */ vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH ); /* Again suspend all tasks (only the low priority task is not suspended already). */ vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); /* This time we are going to suspend the scheduler, resume the low priority task, then resume the high priority task. In this state we will write to the queue three times. When the scheduler is resumed we expect the high priority task to service all three messages. */ vTaskSuspendAll(); { vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ ) { if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) { xHealthStatus = pdFAIL; } } /* The queue should not have been serviced yet!. The scheduler is still suspended. */ if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) { xHealthStatus = pdFAIL; } } xTaskResumeAll(); /* We should have been preempted by resuming the scheduler - so by the time we are running again we expect the high priority task to have removed three items from the queue. */ xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH; if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) { xHealthStatus = pdFAIL; } /* The medium priority and second high priority tasks are still suspended. Make sure to resume them before starting again. */ vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); /* Just keep incrementing to show the task is still executing. */ xCheckVariable++; } }
/* * Controller task as described above. */ static void vCounterControlTask( void * pvParameters ) { unsigned long ulLastCounter; short sLoops; short sError = pdFALSE; const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n"; const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n"; /* Just to stop warning messages. */ ( void ) pvParameters; /* Queue a message for printing to say the task has started. */ vPrintDisplayMessage( &pcTaskStartMsg ); for( ;; ) { /* Start with the counter at zero. */ ulCounter = ( unsigned long ) 0; /* First section : */ /* Check the continuous count task is running. */ for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) { /* Suspend the continuous count task so we can take a mirror of the shared variable without risk of corruption. */ vTaskSuspend( xContinuousIncrementHandle ); ulLastCounter = ulCounter; vTaskResume( xContinuousIncrementHandle ); /* Now delay to ensure the other task has processor time. */ vTaskDelay( priSLEEP_TIME ); /* Check the shared variable again. This time to ensure mutual exclusion the whole scheduler will be locked. This is just for demo purposes! */ vTaskSuspendAll(); { if( ulLastCounter == ulCounter ) { /* The shared variable has not changed. There is a problem with the continuous count task so flag an error. */ sError = pdTRUE; xTaskResumeAll(); vPrintDisplayMessage( &pcTaskFailMsg ); vTaskSuspendAll(); } } xTaskResumeAll(); } /* Second section: */ /* Suspend the continuous counter task so it stops accessing the shared variable. */ vTaskSuspend( xContinuousIncrementHandle ); /* Reset the variable. */ ulCounter = ( unsigned long ) 0; /* Resume the limited count task which has a higher priority than us. We should therefore not return from this call until the limited count task has suspended itself with a known value in the counter variable. The scheduler suspension is not necessary but is included for test purposes. */ vTaskSuspendAll(); vTaskResume( xLimitedIncrementHandle ); xTaskResumeAll(); /* Does the counter variable have the expected value? */ if( ulCounter != priMAX_COUNT ) { sError = pdTRUE; vPrintDisplayMessage( &pcTaskFailMsg ); } if( sError == pdFALSE ) { /* If no errors have occurred then increment the check variable. */ portENTER_CRITICAL(); usCheckVariable++; portEXIT_CRITICAL(); } #if configUSE_PREEMPTION == 0 taskYIELD(); #endif /* Resume the continuous count task and do it all again. */ vTaskResume( xContinuousIncrementHandle ); } }
static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) { EventBits_t uxBits; /* Resume the other task. It will block, pending a single bit from within ebCOMBINED_BITS. */ vTaskResume( xTestSlaveTaskHandle ); /* Ensure the other task is blocked on the task. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only blocked waiting for one of them. */ xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS ); /* The 'test slave' task should now have executed, clearing ebBIT_1 (the bit it was blocked on), then re-entered the Blocked state to wait for all the other bits in ebCOMBINED_BITS to be set again. First check ebBIT_1 is clear. */ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) ) { xError = pdTRUE; } /* Ensure the other task is still in the blocked state. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } /* Set all the bits other than ebBIT_1 - which is the bit that must be set before the other task unblocks. */ xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 ); /* Ensure all the expected bits are still set. */ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) ) { xError = pdTRUE; } /* Ensure the other task is still in the blocked state. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } /* Now also set ebBIT_1, which should unblock the other task, which will then suspend itself. */ xEventGroupSetBits( xEventGroup, ebBIT_1 ); /* Ensure the other task is suspended. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) { xError = pdTRUE; } /* The other task should not have cleared the bits - so all the bits should still be set. */ if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS ) { xError = pdTRUE; } /* Clear ebBIT_1 again. */ if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS ) { xError = pdTRUE; } /* Resume the other task - which will wait on all the ebCOMBINED_BITS again - this time clearing the bits when it is unblocked. */ vTaskResume( xTestSlaveTaskHandle ); /* Ensure the other task is blocked once again. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) { xError = pdTRUE; } /* Set the bit the other task is waiting for. */ xEventGroupSetBits( xEventGroup, ebBIT_1 ); /* Ensure the other task is suspended once again. */ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) { xError = pdTRUE; } /* The other task should have cleared the bits in ebCOMBINED_BITS. Clear the remaining bits. */ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) { xError = pdTRUE; } /* Clear all bits ready for the sync with the other three tasks. The value returned is the value prior to the bits being cleared. */ if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) { xError = pdTRUE; } /* The bits should be clear now. */ if( xEventGroupGetBits( xEventGroup ) != 0x00 ) { xError = pdTRUE; } return xError; }
static void prvChangePriorityWhenSuspendedTask( void *pvParameters ) { const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n"; const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n"; /* Just to stop warning messages. */ ( void ) pvParameters; /* Queue a message for printing to say the task has started. */ vPrintDisplayMessage( &pcTaskStartMsg ); for( ;; ) { /* Start with the counter at 0 so we know what the counter should be when we check it next. */ ulPrioritySetCounter = ( unsigned long ) 0; /* Resume the helper task. At this time it has a priority lower than ours so no context switch should occur. */ vTaskResume( xChangePriorityWhenSuspendedHandle ); /* Check to ensure the task just resumed has not executed. */ portENTER_CRITICAL(); { if( ulPrioritySetCounter != ( unsigned long ) 0 ) { xPriorityRaiseWhenSuspendedError = pdTRUE; vPrintDisplayMessage( &pcTaskFailMsg ); } } portEXIT_CRITICAL(); /* Now try raising the priority while the scheduler is suspended. */ vTaskSuspendAll(); { vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) ); /* Again, even though the helper task has a priority greater than ours, it should not have executed yet because the scheduler is suspended. */ portENTER_CRITICAL(); { if( ulPrioritySetCounter != ( unsigned long ) 0 ) { xPriorityRaiseWhenSuspendedError = pdTRUE; vPrintDisplayMessage( &pcTaskFailMsg ); } } portEXIT_CRITICAL(); } xTaskResumeAll(); /* Now the scheduler has been resumed the helper task should immediately preempt us and execute. When it executes it will increment the ulPrioritySetCounter exactly once before suspending itself. We should now always find the counter set to 1. */ portENTER_CRITICAL(); { if( ulPrioritySetCounter != ( unsigned long ) 1 ) { xPriorityRaiseWhenSuspendedError = pdTRUE; vPrintDisplayMessage( &pcTaskFailMsg ); } } portEXIT_CRITICAL(); /* Delay until we try this again. */ vTaskDelay( priSLEEP_TIME * 2 ); /* Set the priority of the helper task back ready for the next execution of this task. */ vTaskSuspendAll(); vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY ); xTaskResumeAll(); } }
extern int pso_resume (void) { if (_pso_task) vTaskResume (_pso_task); return 0; }
static void prvSetupTest( void ) { BaseType_t x; uint32_t ulValueToSend = 0; /* Ensure the queues are created and the queue set configured before the sending task is unsuspended. First Create the queue set such that it will be able to hold a message for every space in every queue in the set. */ xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ); for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) { /* Create the queue and add it to the set. The queue is just holding uint32_t value. */ xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( uint32_t ) ); configASSERT( xQueues[ x ] ); if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS ) { xQueueSetTasksStatus = pdFAIL; } else { /* The queue has now been added to the queue set and cannot be added to another. */ if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL ) { xQueueSetTasksStatus = pdFAIL; } } } /* Attempt to remove a queue from a queue set it does not belong to (NULL being passed as the queue set in this case). */ if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL ) { /* It is not possible to successfully remove a queue from a queue set it does not belong to. */ xQueueSetTasksStatus = pdFAIL; } /* Attempt to remove a queue from the queue set it does belong to. */ if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) { /* It should be possible to remove the queue from the queue set it does belong to. */ xQueueSetTasksStatus = pdFAIL; } /* Add an item to the queue before attempting to add it back into the set. */ xQueueSend( xQueues[ 0 ], ( void * ) &ulValueToSend, 0 ); if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdFAIL ) { /* Should not be able to add a non-empty queue to a set. */ xQueueSetTasksStatus = pdFAIL; } /* Remove the item from the queue before adding the queue back into the set so the dynamic tests can begin. */ xQueueReceive( xQueues[ 0 ], &ulValueToSend, 0 ); if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) { /* If the queue was successfully removed from the queue set then it should be possible to add it back in again. */ xQueueSetTasksStatus = pdFAIL; } /* The task that sends to the queues is not running yet, so attempting to read from the queue set should fail. */ if( xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY ) != NULL ) { xQueueSetTasksStatus = pdFAIL; } /* Resume the task that writes to the queues. */ vTaskResume( xQueueSetSendingTask ); /* Let the ISR access the queues also. */ xSetupComplete = pdTRUE; }