/** * @brief Clean up th ethernet services and free resources * @param None * @retval None */ static void ETHERNET_Cleanup(void) { EthernetSettings.DistantControlEnabled = 0; EthernetSettings.BackgroundEnabled = 0; EthernetSettings.InitDone = 0; ETH_Stop(); vTaskPrioritySet(Task_Handle, (configMAX_PRIORITIES - 1)); if(ETH_Task_Handle != NULL) { vTaskDelete(ETH_Task_Handle); ETH_Task_Handle = NULL; } vQueueDelete( Ethernet_xSemaphore ); Ethernet_xSemaphore = NULL; if(TCPIP_Task_Handle != NULL) { vTaskSuspend(TCPIP_Task_Handle); } if(HTTP_Task_Handle != NULL) { vTaskDelete(HTTP_Task_Handle); HTTP_Task_Handle = NULL; } if(DHCP_Task_Handle != NULL) { vTaskDelete(DHCP_Task_Handle); DHCP_Task_Handle = NULL; } netif_remove(&xnetif); }
void MPU_vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) { portBASE_TYPE xRunningPrivileged = prvRaisePrivilege(); vTaskPrioritySet( pxTask, uxNewPriority ); portRESET_PRIVILEGE( xRunningPrivileged ); }
void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) { BaseType_t xRunningPrivileged = xPortRaisePrivilege(); vTaskPrioritySet( pxTask, uxNewPriority ); vPortResetPrivilege( xRunningPrivileged ); }
void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) { BaseType_t xRunningPrivileged = prvRaisePrivilege(); vTaskPrioritySet( pxTask, uxNewPriority ); portRESET_PRIVILEGE( xRunningPrivileged ); }
THandle OsThreadCreate(const char* aName, uint32_t aPriority, uint32_t aStackBytes, ThreadEntryPoint aEntryPoint, void* aArg) { portBASE_TYPE result; xTaskHandle task; /* The task application tag is used to hold a pointer to the containing Thread object. If the child task is higher priority than it's parent, it'll run before the tag is set. Bad. So we set the initial priority as slightly lower than parent thread, set the tag, then promote the child task to it's rightful priority. */ result = xTaskCreate( aEntryPoint, // pdTASK_CODE pvTaskCode, (const signed char * const) aName, // const portCHAR * const pcName, (aStackBytes != 0 ? aStackBytes : 1024 * 32) / sizeof( portSTACK_TYPE ), // unsigned portSHORT usStackDepth, aArg, // void *pvParameters, uxTaskPriorityGet(NULL) - 1, // unsigned portBASE_TYPE uxPriority, &task // xTaskHandle *pvCreatedTask ); if ( result != pdPASS ) return kHandleNull; vTaskSetApplicationTaskTag(task, aArg); vTaskPrioritySet(task, aPriority); return (THandle) task; }
void vTask2(void* pvParameters) { UBaseType_t uxPriority; // Task 1will always run before this task as Task 1 is created with the // higher priority. Neither Task 1 nor Task 2 ever block so will always be // in either the Running or the Ready state. // Query the priority at which this task is running - passing in NULL means // "return my priority". uxPriority = uxTaskPriorityGet(NULL); for (;;) { // For this task to reach this point Task 1 must have already run and // set the priority of this task higher than its own. // Print out the name of this task. printf("Task2 is running\n"); fflush(stdout); // Set our priority back down to its original value. Passing in NULL // as the task handle means "change my priority". Setting the priority // below that of Task 1 will cause Task 1 to immediately start running // again - pre-empting this task. printf("About to lower the Task 2 priority\n"); fflush(stdout); vTaskPrioritySet(NULL, uxPriority-2); } }
void vStartupLEDTask ( void *pvParameters ) { vLEDSet(D2_PORT, D2_PIN, ON); vLEDSet(D3_PORT, D3_PIN, ON); vLEDSet(D4_PORT, D4_PIN, ON); vTaskDelay(500/portTICK_RATE_MS); vLEDSet(D2_PORT, D2_PIN, OFF); vLEDSet(D3_PORT, D3_PIN, OFF); vLEDSet(D4_PORT, D4_PIN, OFF); xTaskCreate( vLEDFlashTask, ( signed portCHAR * ) "LEDf", configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY+2, NULL); // printf("LEDStartup HWM = %d1\r\n", uxTaskGetStackHighWaterMark(NULL)); vTaskDelete(NULL); for (;;) { //Should never get here vTaskPrioritySet(NULL, tskIDLE_PRIORITY); // printf("LcdStartup Still Running\r\n"); } }
void vTask1(void* pvParameters) { UBaseType_t uxPriority; // This task will always run before Task2 as it is created with the higher // priority. Neither Task1 nor Task2 ever block so both will always be // in either the Running or the Ready state. // Query the priority at which this task is running - passing in NULL means // "return my priority". uxPriority = uxTaskPriorityGet(NULL); for (;;) { // Print out the name of this task. vTaskSuspendAll(); printf("Task 1 is running\n"); fflush(stdout); xTaskResumeAll(); // Setting the Task 2 priority above the Task 1 priority will cause // Task2 to immediately start running (as then Task 2 will have the // higher priority of the two created tasks). Note the use of the handle // to task 2 (xTask2Handle) in the call to vTaskPrioritySet(). // main() shows how the handle was obtained. printf("About to raise the Task 2 priority\n"); fflush(stdout); vTaskPrioritySet(xTask2Handle, uxPriority+1); // Task 1 will only run when it has a priority higher than Task 2. // Therefore, for this task to reach this point Task2 must already // have executed and set its priority back down to below the priority // of this task. } }
/** * \brief In this function, the hardware should be initialized. * Called from ethernetif_init(). * * \param netif the already initialized lwip network interface structure * for this ethernetif */ static void low_level_init(struct netif *netif) { #ifdef FREERTOS_USED unsigned portBASE_TYPE uxPriority; #endif /* Set MAC hardware address length */ netif->hwaddr_len = sizeof(gs_uc_mac_address); /* Set MAC hardware address */ netif->hwaddr[0] = gs_uc_mac_address[0]; netif->hwaddr[1] = gs_uc_mac_address[1]; netif->hwaddr[2] = gs_uc_mac_address[2]; netif->hwaddr[3] = gs_uc_mac_address[3]; netif->hwaddr[4] = gs_uc_mac_address[4]; netif->hwaddr[5] = gs_uc_mac_address[5]; /* Maximum transfer unit */ netif->mtu = NET_MTU; /* Configure EMAC pins */ // ethPinsInit(); /* gpio_configure_pin(PIN_EEMAC_EREFCK, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETX0, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETX1, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETXEN, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ECRSDV, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERX0, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERX1, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERXER, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_EMDC, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_EMDIO, PIN_EMAC_FLAGS); */ /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP #if defined(DHCP_USED) | NETIF_FLAG_DHCP #endif ; netif->flags |= NETIF_FLAG_LINK_UP; //the link is up? //printf("netif->flags %X \n", netif->flags); #ifdef FREERTOS_USED /* * NOTE: This routine contains code that polls status bits. If the Ethernet * cable is not plugged in then this can take a considerable time. To prevent * this from starving lower priority tasks of processing time we lower our * priority prior to the call, then raise it back again once the initialization * is complete. */ /* Read the priority of the current task. */ uxPriority = uxTaskPriorityGet( NULL ); /* Set the priority of the current task to the lowest possible. */ vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); #endif }
/** * In this function, the hardware should be initialized. * Called from ethernetif_init(). * * @param netif the already initialized lwip network interface structure * for this ethernetif */ static void low_level_init(struct netif *netif) { unsigned portBASE_TYPE uxPriority; /* set MAC hardware address length */ netif->hwaddr_len = ETHARP_HWADDR_LEN; /* set MAC hardware address */ netif->hwaddr[0] = ETHERNET_CONF_ETHADDR0; netif->hwaddr[1] = ETHERNET_CONF_ETHADDR1; netif->hwaddr[2] = ETHERNET_CONF_ETHADDR2; netif->hwaddr[3] = ETHERNET_CONF_ETHADDR3; netif->hwaddr[4] = ETHERNET_CONF_ETHADDR4; netif->hwaddr[5] = ETHERNET_CONF_ETHADDR5; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; /* Do whatever else is needed to initialize interface. */ /* Initialise the MACB. */ // NOTE: This routine contains code that polls status bits. If the Ethernet // cable is not plugged in then this can take a considerable time. To prevent // this from starving lower priority tasks of processing time we lower our // priority prior to the call, then raise it back again once the initialization // is complete. // Read the priority of the current task. uxPriority = uxTaskPriorityGet( NULL ); // Set the priority of the current task to the lowest possible. vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); // Init the MACB interface. while( xMACBInit(&AVR32_MACB) == FALSE ) { __asm__ __volatile__ ( "nop" ); } // Restore the priority of the current task. vTaskPrioritySet( NULL, uxPriority ); /* Create the task that handles the MACB input packets. */ sys_thread_new( "ETHINT", ethernetif_input, netif, netifINTERFACE_TASK_STACK_SIZE, netifINTERFACE_TASK_PRIORITY ); }
static void prvChangeRelativePriorities( void ) { static unsigned portBASE_TYPE ulLoops = 0; static eRelativePriorities ePriorities = eEqualPriority; /* Occasionally change the task priority relative to the priority of the receiving task. */ ulLoops++; if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS ) { ulLoops = 0; switch( ePriorities ) { case eEqualPriority: /* Both tasks are running with medium priority. Now lower the priority of the receiving task so the Tx task has the higher relative priority. */ vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY ); ePriorities = eTxHigherPriority; break; case eTxHigherPriority: /* The Tx task is running with a higher priority than the Rx task. Switch the priorities around so the Rx task has the higher relative priority. */ vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY ); vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY ); ePriorities = eTxLowerPriority; break; case eTxLowerPriority: /* The Tx task is running with a lower priority than the Rx task. Make the priorities equal again. */ vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY ); ePriorities = eEqualPriority; /* When both tasks are using a non-idle priority the queue set tasks will starve idle priority tasks of execution time - so relax a bit before the next iteration to minimise the impact. */ vTaskDelay( queuesetTX_LOOP_DELAY ); break; } } }
/** * @brief Change priority of an active thread. * @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. * @param priority new priority value for the thread function. * @retval status code that indicates the execution status of the function. * @note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. */ osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { #if (INCLUDE_vTaskPrioritySet == 1) vTaskPrioritySet(thread_id, makeFreeRtosPriority(priority)); return osOK; #else return osErrorOS; #endif }
static void prvBasicDelayTests( void ) { TickType_t xPreTime, xPostTime, x, xLastUnblockTime, xExpectedUnblockTime; const TickType_t xPeriod = 75, xCycles = 5, xAllowableMargin = ( bktALLOWABLE_MARGIN >> 1 ); /* Temporarily increase priority so the timing is more accurate, but not so high as to disrupt the timer tests. */ vTaskPrioritySet( NULL, configTIMER_TASK_PRIORITY - 1 ); /* Crude check to too that vTaskDelay() blocks for the expected period. */ xPreTime = xTaskGetTickCount(); vTaskDelay( bktTIME_TO_BLOCK ); xPostTime = xTaskGetTickCount(); /* The priority is higher, so the allowable margin is halved when compared to the other tests in this file. */ if( ( xPostTime - xPreTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) ) { xErrorOccurred = pdTRUE; } /* Now crude tests to check the vTaskDelayUntil() functionality. */ xPostTime = xTaskGetTickCount(); xLastUnblockTime = xPostTime; for( x = 0; x < xCycles; x++ ) { /* Calculate the next expected unblock time from the time taken before this loop was entered. */ xExpectedUnblockTime = xPostTime + ( x * xPeriod ); vTaskDelayUntil( &xLastUnblockTime, xPeriod ); if( ( xTaskGetTickCount() - xExpectedUnblockTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) ) { xErrorOccurred = pdTRUE; } xPrimaryCycles++; } /* Reset to the original task priority ready for the other tests. */ vTaskPrioritySet( NULL, bktPRIMARY_PRIORITY ); }
static void prvQueueSetSendingTask( void *pvParameters ) { unsigned long ulTaskTxValue = 0; portBASE_TYPE xQueueToWriteTo; xQueueHandle xQueueInUse; unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0; /* Remove compiler warning about the unused parameter. */ ( void ) pvParameters; srand( ( unsigned int ) &ulTaskTxValue ); for( ;; ) { /* Generate the index for the queue to which a value is to be sent. */ xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET; xQueueInUse = xQueues[ xQueueToWriteTo ]; /* Note which index is being written to to ensure all the queues are used. */ ( ulQueueUsedCounter[ xQueueToWriteTo ] )++; /* Send to the queue to unblock the task that is waiting for data to arrive on a queue within the queue set to which this queue belongs. */ if( xQueueSendToBack( xQueueInUse, &ulTaskTxValue, portMAX_DELAY ) != pdPASS ) { /* The send should always pass as an infinite block time was used. */ xQueueSetTasksStatus = pdFAIL; } ulTaskTxValue++; /* If the Tx value has reached the range used by the ISR then set it back to 0. */ if( ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE ) { ulTaskTxValue = 0; } /* Occasionally change the task priority relative to the priority of the receiving task. */ ulLoops++; if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS ) { ulLoops = 0; uxPriority++; if( uxPriority > queuesetHIGH_PRIORITY ) { uxPriority = queuesetLOW_PRIORITY; } vTaskPrioritySet( NULL, uxPriority ); } } }
static int SC_check_and_show_connection_info(void) { rtw_wifi_setting_t setting; int ret = -1; /* If not rise priority, LwIP DHCP may timeout */ vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 3); /* Start DHCP Client */ ret = LwIP_DHCP(0, DHCP_START); vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 1); wifi_get_setting(WLAN0_NAME, &setting); wifi_show_setting(WLAN0_NAME, &setting); if (ret == DHCP_ADDRESS_ASSIGNED) return SC_SUCCESS; else return SC_DHCP_FAIL; }
static void low_level_init( struct netif *netif ) { unsigned portBASE_TYPE uxPriority; /* set MAC hardware address length */ netif->hwaddr_len = 6; /* set MAC hardware address */ netif->hwaddr[0] = emacETHADDR0; netif->hwaddr[1] = emacETHADDR1; netif->hwaddr[2] = emacETHADDR2; netif->hwaddr[3] = emacETHADDR3; netif->hwaddr[4] = emacETHADDR4; netif->hwaddr[5] = emacETHADDR5; /* maximum transfer unit */ netif->mtu = netifMTU; /* broadcast capability */ netif->flags = NETIF_FLAG_BROADCAST; xNetIf = netif; /* Initialise the EMAC. This routine contains code that polls status bits. If the Ethernet cable is not plugged in then this can take a considerable time. To prevent this starving lower priority tasks of processing time we lower our priority prior to the call, then raise it back again once the initialisation is complete. */ uxPriority = uxTaskPriorityGet( NULL ); vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); while( xEMACInit() == NULL ) { __asm( "NOP" ); } vTaskPrioritySet( NULL, uxPriority ); /* Create the task that handles the EMAC. */ xTaskCreate( ethernetif_input, "ETH_INT", netifINTERFACE_TASK_STACK_SIZE, NULL, netifINTERFACE_TASK_PRIORITY, NULL ); }
/* * Just keep counting the shared variable up. The control task will suspend * this task when it wants. */ static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters ) { unsigned long *pulCounter; unsigned portBASE_TYPE uxOurPriority; /* Take a pointer to the shared variable from the parameters passed into the task. */ pulCounter = ( unsigned long * ) pvParameters; /* Query our priority so we can raise it when exclusive access to the shared variable is required. */ uxOurPriority = uxTaskPriorityGet( NULL ); for( ;; ) { /* Raise our priority above the controller task to ensure a context switch does not occur while we are accessing this variable. */ vTaskPrioritySet( NULL, uxOurPriority + 1 ); ( *pulCounter )++; vTaskPrioritySet( NULL, uxOurPriority ); } }
void real_time(void * pvParameters) { int x=pvParameters; int i; while(1) { i=0; //if(x<6) printk(KERN_ALERT "REAL TIME TASK %d\n",x); while(i++<1000000); //do some computation that ends before deadline vTimerStop(NULL); vTaskPrioritySet(NULL,2); //go back to the scheduler } }
/* 프레임워크 계층의 스케쥴러 실행 함수입니다. FreeRTOS 계층의 vTaskStartScheduler()를 호출하는데, 그 전에 vTaskPrioritySet()를 이용해 각 태스크에 우선순위를 부여합니다. 큰 주기를 갖은 태스크는 낮은 우선 순위를 갖게 됩니다.*/ static void fInitTasks(void *arg) { UBaseType_t fIndex, fPriority; fIndex = ( UBaseType_t ) 0U; fPriority = fIndex + 1; fSort(); // debug_print_line_number(__func__,__LINE__); while(fNumberOfTasks > fIndex) { if(fIndex > 0) { if(fReadyTasks[fIndex-1].period != fReadyTasks[fIndex].period) { fPriority++; } } vTaskPrioritySet(fReadyTasks[fIndex].handler, tskIDLE_PRIORITY + fPriority); fIndex++; } vTaskDelete(NULL); }
/** * @brief Return the module main menu from Webserver page * @param None * @retval None */ static void return_from_webserver(void) { EthernetSettings.WebserverEnabled = 0; EthernetSettings.InitDone = 0; ETH_Stop(); vTaskPrioritySet(Task_Handle, (configMAX_PRIORITIES - 1)); if(ETH_Task_Handle != NULL) { vTaskDelete(ETH_Task_Handle); ETH_Task_Handle = NULL; } if (Ethernet_xSemaphore != NULL) { vQueueDelete( Ethernet_xSemaphore ); Ethernet_xSemaphore = NULL; } if(TCPIP_Task_Handle != NULL) { vTaskSuspend(TCPIP_Task_Handle); } if(HTTP_Task_Handle != NULL) { vTaskDelete(HTTP_Task_Handle); HTTP_Task_Handle = NULL; } if(DHCP_Task_Handle != NULL) { vTaskDelete(DHCP_Task_Handle); DHCP_Task_Handle = NULL; } DMA_Cmd(DMA2_Stream1, DISABLE); DCMI_Cmd(DISABLE); DCMI_CaptureCmd(DISABLE); netif_remove(&xnetif); ETHERNET_SwitchPage(EthernetWebServerPage, ETHERNET_MAIN_PAGE); EthernetWebServerPage = NULL; }
void messageTxTask(void *pvParameters) { SensorDataStruct sensorData; for (;;) { // Wait 25ms before we run another. vTaskDelay(25 / portTICK_PERIOD_MS); if (usbLinkStarted()) { if (xQueueReceive(gMessageTxQueue, &sensorData, portMAX_DELAY) == pdPASS) { switch (sensorData.sensorType) { case eRotaryEncoder: sendSensorValue(MotorMsg_Data_Param_Id_CUR_POS, MotorMsg_Unit_DEGREE, sensorData.sensorValue); break; default: break; } vTaskPrioritySet(gMessageTxTask, MESSAGE_TX_PRIORITY); } } } }
void Scheduler(void *pvParameters) //dont use printf/ printk in this function... extremely dangerous { static int count=0; int x; int task_id; while(1) { if(EXECUTED<10) //scheduler logic...dont put printk here...dangling pointers issue will arise and system will halt...uses a lot of internal work { x=getNextTime(); //printk(KERN_ALERT "Next timer expires in %d\n",getExpireTime()); //printf("Next timer expires for task %d\n",x); if(x!=80) //error code --- no active timers vTaskPrioritySet(handles[x],4); //else schedule EXECUTED++; //keep track of how many RT task scheduled } else { for(x=0;x<10;x++) vTaskSuspend(handles[x]); //suspend the tasks so that idle tasks get some execution time vTaskDelay(MAX_DELAY); //suspend till next time frame for(x=0;x<10;x++) //wake up RT tasks and reset their timers { vTimerReset(handles[x]); vTaskResume(handles[x]); } EXECUTED=0; //reset their status } } }
/*-----------------------------------------------------------------------------------*/ void vTaskTCPt(void *pvParameters) { for (;;) { // получаем количество элементов в очереди unsigned portBASE_TYPE count_com = uxQueueMessagesWaiting(qTCPt); for (int i=0; i<count_com; i++) { xQueueReceive(qTCPt, &uTCPt, 0); // считываем с удалением из очереди if (uTCPt.ucDATA[0] != 0) { netconn_write(newconn, uTCPt.ucDATA, uTCPt.ucLen, NETCONN_COPY); } } // снижаем приоритет vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); } // for (;;) }
bool ethernet_establish_link(void) { /* Auto Negotiate, work in RMII mode */ if (ethernet_phy_auto_negotiate(EMAC, BOARD_EMAC_PHY_ADDR) != EMAC_OK) { return false; } /* Establish ethernet link */ if (ethernet_phy_set_link(EMAC, BOARD_EMAC_PHY_ADDR, 1) != EMAC_OK) { LWIP_DEBUGF(LWIP_DBG_TRACE,("Set link ERROR!\r")); return false; } #ifdef FREERTOS_USED /* Restore the priority of the current task. */ vTaskPrioritySet( NULL, uxPriority ); /* Create the task that handles the EMAC input packets. */ sys_thread_new( "ETHINT", ethernetif_input, netif, netifINTERFACE_TASK_STACK_SIZE, netifINTERFACE_TASK_PRIORITY ); #endif return true; }
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(); } }
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++; } }
/** * \brief In this function, the hardware should be initialized. * Called from ethernetif_init(). * * \param netif the already initialized lwip network interface structure * for this ethernetif */ static void low_level_init(struct netif *netif) { volatile uint32_t ul_dealy; emac_options_t emac_option; #ifdef FREERTOS_USED unsigned portBASE_TYPE uxPriority; #endif /* Set MAC hardware address length */ netif->hwaddr_len = sizeof(gs_uc_mac_address); /* Set MAC hardware address */ netif->hwaddr[0] = gs_uc_mac_address[0]; netif->hwaddr[1] = gs_uc_mac_address[1]; netif->hwaddr[2] = gs_uc_mac_address[2]; netif->hwaddr[3] = gs_uc_mac_address[3]; netif->hwaddr[4] = gs_uc_mac_address[4]; netif->hwaddr[5] = gs_uc_mac_address[5]; /* Maximum transfer unit */ netif->mtu = NET_MTU; /* Configure EMAC pins */ gpio_configure_pin(PIN_EEMAC_EREFCK, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETX0, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETX1, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ETXEN, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ECRSDV, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERX0, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERX1, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_ERXER, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_EMDC, PIN_EMAC_FLAGS); gpio_configure_pin(PIN_EMAC_EMDIO, PIN_EMAC_FLAGS); /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP #if defined(DHCP_USED) | NETIF_FLAG_DHCP #endif ; #ifdef FREERTOS_USED /* * NOTE: This routine contains code that polls status bits. If the Ethernet * cable is not plugged in then this can take a considerable time. To prevent * this from starving lower priority tasks of processing time we lower our * priority prior to the call, then raise it back again once the initialization * is complete. */ /* Read the priority of the current task. */ uxPriority = uxTaskPriorityGet( NULL ); /* Set the priority of the current task to the lowest possible. */ vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); #endif /* Reset PHY */ rstc_set_external_reset(RSTC, 13); /* (2^(13+1))/32768 */ rstc_reset_extern(RSTC); while (rstc_get_status(RSTC) & RSTC_SR_NRSTL) { } /* Wait for PHY to be ready (CAT811: Max400ms) */ ul_dealy = sysclk_get_cpu_hz() / 6; while (ul_dealy--) { } /* Enable EMAC clock */ pmc_enable_periph_clk(ID_EMAC); /* Fill in EMAC options */ emac_option.uc_copy_all_frame = 0; emac_option.uc_no_boardcast = 0; memcpy(emac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address)); gs_emac_dev.p_hw = EMAC; /* Init EMAC driver structure */ emac_dev_init(EMAC, &gs_emac_dev, &emac_option); /* Enable Interrupt */ NVIC_EnableIRQ(EMAC_IRQn); /* Init MAC PHY driver */ if (ethernet_phy_init(EMAC, BOARD_EMAC_PHY_ADDR, sysclk_get_cpu_hz()) != EMAC_OK) { LWIP_DEBUGF(LWIP_DBG_TRACE, "PHY Initialize ERROR!\r"); return; } /* Auto Negotiate, work in RMII mode */ if (ethernet_phy_auto_negotiate(EMAC, BOARD_EMAC_PHY_ADDR) != EMAC_OK) { LWIP_DEBUGF(LWIP_DBG_TRACE, "Auto Negotiate ERROR!\r"); return; } /* Establish ethernet link */ while (ethernet_phy_set_link(EMAC, BOARD_EMAC_PHY_ADDR, 1) != EMAC_OK) { LWIP_DEBUGF(LWIP_DBG_TRACE, "Set link ERROR!\r"); } #ifdef FREERTOS_USED /* Restore the priority of the current task. */ vTaskPrioritySet( NULL, uxPriority ); /* Create the task that handles the EMAC input packets. */ sys_thread_new( "ETHINT", ethernetif_input, netif, netifINTERFACE_TASK_STACK_SIZE, netifINTERFACE_TASK_PRIORITY ); #endif }
static void vInterruptCountingSemaphoreTask( void *pvParameters ) { BaseType_t xCount; const TickType_t xDelay = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) * ( intsemMAX_COUNT + 1 ); ( void ) pvParameters; for( ;; ) { /* Expect to start with the counting semaphore empty. */ if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 ) { xErrorDetected = pdTRUE; } /* Wait until it is expected that the interrupt will have filled the counting semaphore. */ xOkToGiveCountingSemaphore = pdTRUE; vTaskDelay( xDelay ); xOkToGiveCountingSemaphore = pdFALSE; /* Now it is expected that the counting semaphore is full. */ if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != intsemMAX_COUNT ) { xErrorDetected = pdTRUE; } if( uxQueueSpacesAvailable( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 ) { xErrorDetected = pdTRUE; } ulCountingSemaphoreLoops++; /* Expect to be able to take the counting semaphore intsemMAX_COUNT times. A block time of 0 is used as the semaphore should already be there. */ xCount = 0; while( xSemaphoreTake( xISRCountingSemaphore, 0 ) == pdPASS ) { xCount++; } if( xCount != intsemMAX_COUNT ) { xErrorDetected = pdTRUE; } /* Now raise the priority of this task so it runs immediately that the semaphore is given from the interrupt. */ vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); /* Block to wait for the semaphore to be given from the interrupt. */ xOkToGiveCountingSemaphore = pdTRUE; xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY ); xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY ); xOkToGiveCountingSemaphore = pdFALSE; /* Reset the priority so as not to disturbe other tests too much. */ vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); ulCountingSemaphoreLoops++; } }
static void prvLowPriorityMutexTask( void *pvParameters ) { xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters; #ifdef USE_STDIO void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n"; /* Queue a message for printing to say the task has started. */ vPrintDisplayMessage( &pcTaskStartMsg ); #endif for( ;; ) { /* Take the mutex. It should be available now. */ if( xSemaphoreTake( 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( xSemaphoreGive( 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 } }
static void prvTakeTwoMutexesReturnInDifferentOrder( 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; } /* Attempt to set the priority of this task to the test priority - between the idle priority and the medium/high test priorities, but the actual priority 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 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 semaphore is given back the priority of this task should not yet be disinherited because the local 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( xMutex ) != 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 local mutex, taking the held count back to 0. This time the priority of this task should be disinherited back to the priority to which it was set while the mutex was held. 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( xLocalMutex ) != 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_TEST_PRIORITY. */ if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) { xErrorDetected = pdTRUE; } /* Set the priority of this task back to its original value, ready for the next loop around this test. */ vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); }