static void prvRecursiveMutexBlockingTask( void *pvParameters ) { /* Just to remove compiler warning. */ ( void ) pvParameters; for( ;; ) { /* Attempt to obtain the mutex. We should block until the controlling task has given up the mutex, and not actually execute past this call until the controlling task is suspended. */ if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS ) { if( xControllingIsSuspended != pdTRUE ) { /* Did not expect to execute until the controlling task was suspended. */ xErrorOccurred = pdTRUE; } else { /* Give the mutex back before suspending ourselves to allow the polling task to obtain the mutex. */ if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) { xErrorOccurred = pdTRUE; } xBlockingIsSuspended = pdTRUE; vTaskSuspend( NULL ); xBlockingIsSuspended = pdFALSE; } } else { /* We should not leave the xSemaphoreTakeRecursive() function until the mutex was obtained. */ xErrorOccurred = pdTRUE; } /* The controlling and blocking tasks should be in lock step. */ if( uxControllingCycles != ( uxBlockingCycles + 1 ) ) { xErrorOccurred = pdTRUE; } /* Keep count of the number of cycles this task has performed so a stall can be detected. */ uxBlockingCycles++; } }
/* * Just loops around incrementing the shared variable until the limit has been * reached. Once the limit has been reached it suspends itself. */ static void vLimitedIncrementTask( void * pvParameters ) { unsigned long *pulCounter; /* Take a pointer to the shared variable from the parameters passed into the task. */ pulCounter = ( unsigned long * ) pvParameters; /* This will run before the control task, so the first thing it does is suspend - the control task will resume it when ready. */ vTaskSuspend( NULL ); for( ;; ) { /* Just count up to a value then suspend. */ ( *pulCounter )++; if( *pulCounter >= priMAX_COUNT ) { vTaskSuspend( NULL ); } } }
void setup_Task(void *pvParameters) { setup(); xTaskCreate(main_Task, (signed portCHAR *) "main", mainLoopStackSize, NULL, mainLoopPriority, &xHandleLoop); #if INCLUDE_vTaskDelete vTaskDelete(xHandleSetup); #else while(true) vTaskSuspend(NULL); #endif }
void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks ) { short sLEDTask; if( ucIndex == configLEFT_DISPLAY ) { /* Suspend or resume the tasks that are toggling the segments of the left side display. */ for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask ) { if( xFlashTaskHandles[ sLEDTask ] != NULL ) { if( sSuspendTasks == pdTRUE ) { vTaskSuspend( xFlashTaskHandles[ sLEDTask ] ); } else { vTaskResume( xFlashTaskHandles[ sLEDTask ] ); } } } } else { /* Suspend or resume the task in which the co-routines are running. The co-routines toggle the segments of the right side display. */ if( sSuspendTasks == pdTRUE ) { vTaskSuspend( xCoroutineTask ); } else { vTaskResume( xCoroutineTask ); } } }
void spiTask(void *data) { TickType_t lastWakeUpTime = xTaskGetTickCount(); struct spi_slave **slave = data; for (;;) { printf("\n\n -- %lu -- \n\n", lastWakeUpTime); { uint16_t sendData[] = {(0x75 | BIT(7)), 0xFF}; uint16_t recvData[] = {0x4243, 0x4445}; int32_t ret; printf("MCU Test\n"); ret = spiSlave_transver(slave[0], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); ret = spiSlave_transver(slave[0], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); } /*vTaskDelayUntil(&lastWakeUpTime, 100 / portTICK_PERIOD_MS);*/ printf("\n\n -- %lu -- \n\n", lastWakeUpTime); { uint16_t sendData[] = {(0xf | BIT(7)), 0xFF}; uint16_t recvData[] = {0x4243, 0x4445}; int32_t ret; printf("LSM330DLC Test\n"); ret = spiSlave_transver(slave[1], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); ret = spiSlave_transver(slave[1], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); } printf("\n\n -- %lu -- \n\n", lastWakeUpTime); { uint16_t sendData[] = {(0xf | BIT(7)), 0xFF}; uint16_t recvData[] = {0x4243, 0x4445}; int32_t ret; printf("LSM330DLC 2 Test\n"); ret = spiSlave_transver(slave[2], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); ret = spiSlave_transver(slave[1], sendData, recvData, sizeof(sendData) / sizeof(uint16_t), 1000 / portTICK_PERIOD_MS); CONFIG_ASSERT(ret == 0); printf("recv: 0x%x 0x%x\n", recvData[0], recvData[1]); } vTaskDelayUntil(&lastWakeUpTime, 1000 / portTICK_PERIOD_MS); } vTaskSuspend(NULL); }
static void prvMediumPriorityMutexTask( void *pvParameters ) { ( void ) pvParameters; for( ;; ) { /* The medium priority task starts by suspending itself. The low priority task will unsuspend this task when required. */ vTaskSuspend( NULL ); /* When this task unsuspends all it does is increment the guarded variable, this is so the low priority task knows that it has executed. */ ulGuardedVariable++; } }
// TODO: the function header. static void prv_v_manage_user_action( void ) { unsigned portBASE_TYPE uxNbMsgsInQueue = 0; // Check if it is time to empty the xSUPERVISORQueue. uxNbMsgsInQueue = uxQueueMessagesWaiting( xSUPERVISORQueue ); if( 0 != uxNbMsgsInQueue ) { // Resume the User Action task. vTaskSuspend( xSupervisorUserActionHndl ); vTaskResume( xSupervisorUserActionHndl ); // WARNING: What would happen if we try to resume a task that is not suspended? // Is the FreeRTOS Kernel implementation safe on this one? To be sure, we issue // a suspend before a resume. } }
static void prvChangePriorityHelperTask( void *pvParameters ) { /* Just to stop warning messages. */ ( void ) pvParameters; for( ;; ) { /* This is the helper task for prvChangePriorityWhenSuspendedTask(). It has it's priority raised and lowered. When it runs it simply increments the counter then suspends itself again. This allows prvChangePriorityWhenSuspendedTask() to know how many times it has executed. */ ulPrioritySetCounter++; vTaskSuspend( NULL ); } }
/** * \brief About task * * This task prints a short text about the demo, with a simple zooming * animation. * * \param params Parameters for the task. (Not used.) */ static void about_task(void *params) { char c; gfx_coord_t x, y; uint8_t i, shift; char * text_to_use = (char *)&about_text; const uint8_t max_shift = 8; shift = 1; for (;;) { oled1_set_led_state(&oled1, OLED1_LED2_ID, true); xSemaphoreTake(display_mutex, portMAX_DELAY); // Print the about text in an expanding area for (i = 0; i < (sizeof(about_text) - 1); i++) { c = text_to_use[i]; x = (((i % TERMINAL_COLUMNS) * SYSFONT_WIDTH) * shift + (CANVAS_WIDTH / 2) * (max_shift - shift)) / max_shift; y = (((i / TERMINAL_COLUMNS) * SYSFONT_HEIGHT) * shift + (CANVAS_HEIGHT / 2) * (max_shift - shift)) / max_shift; gfx_mono_draw_char(c, x, y, &sysfont); } xSemaphoreGive(display_mutex); oled1_set_led_state(&oled1, OLED1_LED2_ID, false); // Repeat task until we're displaying the text in full size if (shift < max_shift) { shift++; vTaskDelay(ABOUT_TASK_DELAY); } else { shift = 0; vTaskSuspend(NULL); if (tickless_enable) { text_to_use = (char *)&about_text; } else { text_to_use = (char *)&about_text_tickless; } tickless_enable = !tickless_enable; } } }
void recue_tim_func(TimerHandle_t timer) { configASSERT(timer); if(jar_status != FULL) { TIM_Cmd(TIM17, DISABLE); TIM_CtrlPWMOutputs(TIM17, DISABLE); GPIO_ResetBits(GPIOA, (GPIO_Pin_9)); GPIO_SetBits(GPIOA, GPIO_Pin_10); xTimerStop(recue_tim_handler, 0); vTaskSuspend(blink_handler); jar_status = FULL; } }
static void RECORDER_Startup (void) { vTaskSuspend(Core_Time_Task_Handle); Recorder_UsedStorage = 0xFF; if (AudioPlayerSettings.BackgroundEnabled == 0) { /* Switch to the recorder page */ RECORDER_SwitchPage(GL_HomePage, RECORDER_MAIN_PAGE); } else { /* Switch to the error page */ RECORDER_SwitchPage(GL_HomePage, RECORDER_ERROR_PAGE); } }
void vStartQueueSetTasks( void ) { xTaskHandle xQueueSetSendingTask; /* Create the two queues. The handle of the sending task is passed into the receiving task using the task parameter. The receiving task uses the handle to resume the sending task after it has created the queues. */ xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask ); xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL ); /* It is important that the sending task does not attempt to write to a queue before the queue has been created. It is therefore placed into the suspended state before the scheduler has started. It is resumed by the receiving task after the receiving task has created the queues and added the queues to the queue set. */ vTaskSuspend( xQueueSetSendingTask ); }
/** * @brief Handle the Module startup action and display the main menu * @param None * @retval None */ static void ETHERNET_Startup (void) { vTaskSuspend(Core_Time_Task_Handle); if(EthernetSettings.BackgroundEnabled) { ETHERNET_SwitchPage(GL_HomePage, ETHERNET_WARNING_PAGE); } else { EthernetSettings.BackgroundEnabled = 0; EthernetSettings.DistantControlEnabled = 0; EthernetSettings.WebserverEnabled = 0; EthernetSettings.InitDone = 0; ETHERNET_SwitchPage(GL_HomePage, ETHERNET_MAIN_PAGE); } }
void vButtonTask(void* pvParameters){ xSemaphoreTake(xButtonSemaphore,buttonNO_BLOCK); for(;;){ xSemaphoreTake(xButtonSemaphore, portMAX_DELAY); ulButtonPressCount++; xSemaphoreGive(xStatusSemaphore); if(eTaskGetState(xLedTaskHandle)== eBlocked || eTaskGetState(xLedTaskHandle)== eRunning ){ vTaskSuspend(xLedTaskHandle); } else if(eTaskGetState(xLedTaskHandle)==eSuspended){ vTaskResume(xLedTaskHandle); } vTaskDelay(500); } }
void key_scan(void *pvParameters) { //unsigned int delay = 1000; asm("FIQ ON"); // To initialize the input pins for key. while(1) { //vTaskDelay( delay / portTICK_RATE_MS ); // To scan key if audio playing or just weak-up by key changed // else vTaskSuspend( 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; }
static void readPowTemp ( void *pvParameters ){ portTickType xLastExecutionTime = xTaskGetTickCount(); vemu_sensors s; for( ;; ) { // Enforce task frequency vTaskDelayUntil( &xLastExecutionTime, READPOWTEMP_DELAY ); // read sensors vemu_read_sensors(&s); PowerModel.temps[PowerModel.num] = s.t; PowerModel.ps[PowerModel.num] = s.sp; PowerModel.pa[PowerModel.num] = s.ap; // if points are collected, fit the models if( ++PowerModel.num == POWER_MODEL_POINTS ){ // fit sleep power model fitPsModel(); // fit active power model fitPaModel(); // print results uputs("\n\n<<< slope / offset : >>>\n"); uputi((int)(1000*PowerModel.psslope)); uputs("\n"); uputi((int)(1000*PowerModel.psoffset)); uputs("\n"); uputi((int)(1000*PowerModel.paslope)); uputs("\n"); uputi((int)(1000*PowerModel.paoffset)); uputs("\n"); // find optimal DC PowerModel.optimalDC = findOptimalDC( PowerModel.lifetime_hours, PowerModel.energy_joules ); uputs("optimal DC x 1000\n"); uputi((int)(1000*PowerModel.optimalDC)); uputs("\n"); // reset power model PowerModel.num = 0; // suspend our own operation until someone wakes us up vTaskSuspend( NULL ); } } }
/** * [gui_pedometer_Task description] * @param task_param_t [description] * @return [description] */ static void gui_pedometer_Task( task_param_t param ) { while (1) { gui_status_t rightClickStatus = GuiDriver_QueueMsgGet( &gui_pedometer_packet , OSA_WAIT_FOREVER ); if( GUI_STATUS_SUCCESS == rightClickStatus ) { if ( packetType_pressRight == gui_pedometer_packet.type ) { if ( false == isPedometerActive ) { isPedometerActive = true; power_DisablePowerSave(); GuiDriver_CleanMainArea(); GuiDriver_LabelDraw( &gui_pedometer_stepCounter_label ); GuiDriver_LabelDraw( &gui_pedometer_stepText_label ); GuiDriver_LabelDraw( &gui_pedometer_calCounter_label ); GuiDriver_LabelDraw( &gui_pedometer_calText_label ); GuiDriver_ImageDraw(&screen_buttonStop); vTaskResume( gui_pedometer_step_counter_taskHandler ); pedometer_Resume(); } else { pedometer_Pause(); vTaskSuspend( gui_pedometer_step_counter_taskHandler ); GuiDriver_CleanMainArea(); GuiDriver_ImageDraw( &gui_pedometer_icon ); GuiDriver_ImageDraw(&screen_buttonStart); power_EnablePowerSave(); isPedometerActive = false; } haptic_Vibrate(); } } } }
void task_start(void *pvParameters) { (void) pvParameters; /* Start the LED flash tasks */ xTaskCreate(task_led, (signed char*)"LED", TASK_LED_STACK_SIZE, NULL, TASK_LED_PRIORITY, ( xTaskHandle * ) NULL); /* Start the ethernet tasks. */ vStartEthernetTaskLauncher( TASK_START_ETH_PRIORITY ); /* Start the SPI app tasks. */ vStartSpiTaskLauncher( TASK_SPI_HANDLE_PRIORITY ); for (;;) { vTaskSuspend(vStartTaskHandler); /* Suspend START task. */ } }
void IR3(void *p) { while(1) { UpdateLeftPWM(400); //Velocity Setting UpdateRightPWM(400); //Velocity Setting if(sen_dat[1]<210) //IR 3 { Stop(); vTaskSuspend(xforward); if( sen_dat[2]>170) { //DelaymSec(200); Right(); DelaymSec(50); Stop(); DelaymSec(50); } else if (sen_dat[0]>190) { Left(); DelaymSec(50); } else if(sen_dat[2]>170) { Right(); DelaymSec(50); } else { Back(); DelaymSec(50); } if(sen_dat[1]>200) { vTaskResume(xforward); } } } }
void stop_filling(void * pvParameters ) { for(;;) { if (xSemaphoreTake(full_sem, portMAX_DELAY) == pdPASS) { if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == SET) { jar_status = FULL; TIM_Cmd(TIM17, DISABLE); TIM_CtrlPWMOutputs(TIM17, DISABLE); TIM17->CCR1 = MOTOR_PWM_PERIOD; vTaskSuspend(blink_handler); GPIO_ResetBits(GPIOA, (GPIO_Pin_9 | GPIO_Pin_10)); xTimerStop(recue_tim_handler, 0); } } } vTaskDelete(NULL); }
void vTask4(void *pvParameters) { // Remove compiler warnings. (void) pvParameters; xTimer1 = xTimerCreate( "Timer 1",( 4000 ), pdTRUE,( void * ) 41, vTimerCallback1); xTimerStart(xTimer1,0); vTaskDelay(2000); xTimer2 = xTimerCreate( "Timer 2",( 4000 ), pdTRUE,( void * ) 42, vTimerCallback2); xTimerStart(xTimer2,0); vTaskDelay(1000); xTimer3 = xTimerCreate( "Timer 3",( 2000 ), pdTRUE,( void * ) 43, vTimerCallback3); xTimerStart(xTimer3,0); while (1) { vTaskSuspend(NULL); } vTaskDelete(NULL); }
static void prvTaskToDelete( void *pvParameters ) { /* Remove compiler warnings about unused parameters. */ ( void ) pvParameters; /* Check the enter and exit critical macros are working correctly. If the SVC priority is below configMAX_SYSCALL_INTERRUPT_PRIORITY then this will fault. */ taskENTER_CRITICAL(); taskEXIT_CRITICAL(); /* Exercise the API of various RTOS objects. */ prvExerciseEventGroupAPI(); prvExerciseSemaphoreAPI(); prvExerciseTaskNotificationAPI(); /* For code coverage test purposes it is deleted by the Idle task. */ configASSERT( uxTaskGetStackHighWaterMark( NULL ) > 0 ); vTaskSuspend( NULL ); }
void wdt_task( void *pvParameters ){ portTickType xLastWakeTime; wdt_opt_t wdt_options; struct tWatchdogRequest request; unsigned char gpsShutdown = FALSE, usbShutdown = FALSE, dataflashShutdown = FALSE, fuelShutdown = FALSE; debug_log(DEBUG_PRIORITY_INFO, DEBUG_SENDER_WDT, "Task Started"); wdtManagerQueue = xQueueCreate(WATCHDOG_QUEUE_SIZE, sizeof(request)); if( wdt_triggered() ){ debug_log(DEBUG_PRIORITY_WARNING, DEBUG_SENDER_WDT, "Reset from watchdog"); } xLastWakeTime = xTaskGetTickCount(); wdt_options.us_timeout_period = WATCHDOG_TIMEOUT_US; wdt_enable(&wdt_options); while(1){ wdt_clear(); if( xQueueReceive(wdtManagerQueue, &request, pdFALSE) == pdTRUE ){ switch(request.command){ case(WDT_REQUEST_POWEROFF): debug_log(DEBUG_PRIORITY_INFO, DEBUG_SENDER_WDT, "Shutdown requested"); fuel_send_request(FUEL_MGR_REQUEST_SHUTDOWN, NULL, NULL, NULL, NULL); //flash_send_request(FLASH_REQUEST_SHUTDOWN, NULL, NULL, NULL, NULL, NULL); flash_send_request(FLASH_MGR_REQUEST_SHUTDOWN, NULL, NULL, NULL, NULL, NULL); gps_send_request(GPS_MGR_REQUEST_SHUTDOWN, NULL, NULL, NULL, pdFALSE); debug_log(DEBUG_PRIORITY_INFO, DEBUG_SENDER_WDT, "Going down!"); wdt_clear(); // Kick the watchdog one more time to allow debug messages to be sent vTaskSuspend(NULL); break; } } vTaskDelayUntil( &xLastWakeTime, ( WATCHDOG_UPDATE_INTERVAL_MS / portTICK_RATE_MS ) ); } }
void vyber( void * pvParameters ) { (void) pvParameters; /* parameter not used */ for ( ;; ) { LCD_clear(); LCD_puts("VYBER: 500"); BankaOperace(-500); nVyberu++; // Po 5-ti probìhnutích se ukonèíme if (nVyberu >= 5) { VkladBezi = 0; vTaskSuspend(TaskVyber); } // Akce se provadi kazdych 900 ms vTaskDelay(900 / portTICK_RATE_MS); } }
void ICACHE_FLASH_ATTR transmitTask(void *pvParameters) { struct userdata *user = (struct userdata *)pvParameters; float temperature; int a, b; while(1) { // Suspend ourselves. vTaskSuspend( NULL ); // Mutex & Semaphore ? xQueueReceive(user->xQueue, &temperature, portMAX_DELAY); a = (int)temperature / 100; b = (int)temperature % 100; printf("{ \"temperature\": %d.%d }\n", a, b); } }
// suspends the given task if it was not already suspended, and (always) checks it out of the watchdog void task_suspend(task_type_t task_id) { TaskHandle_t* task_handle = task_handles[task_id]; configASSERT(task_handle != NULL && *task_handle != NULL); // the latter would suspend THIS task configASSERT(task_id != BATTERY_CHARGING_TASK && task_id != STATE_HANDLING_TASK && task_id != WATCHDOG_TASK && task_id != PERSISTENT_DATA_BACKUP_TASK); // always check out of watchdog when called (to be double-sure) // this is only called here so doesn't need to be safe check_out_task_unsafe(task_id); if (task_handle != NULL && *task_handle != NULL && eTaskGetState(*task_handle) != eSuspended) { // actually suspend using handle vTaskSuspend(*task_handle); } // if task_handle or it's value was NULL, we're in for a watchdog reset // which is what we want because somethings very wrong }
void vtaskControlTask(void* pvParameters) { PORTF = 0x80; for (;;) { if (xSemaphoreTake(xKeyInSemaphore, portMAX_DELAY) == pdTRUE) { vTaskDelay(SW_DEBOUNCE_TIME); if ((PIND & 0x01) == 0x00) { vTaskSuspend(xHandleLED1); PORTF = 0x40; } if ((PIND & 0x02) == 0x00) { vTaskResume(xHandleLED1); PORTF = 0x80; } EIMSK |= 0x03; } } }
void IR3_IR4 (void *p) { while(1) { UpdateLeftPWM(400); //Velocity Setting UpdateRightPWM(400); //Velocity Setting if(( ADC_Data[2]>60) && (sen_dat[1]<230)) //IR 3 and IR 4 { Stop(); vTaskSuspend(xforward); Back(); DelaymSec(50); Soft_Left2(); DelaymSec(50); if(( ADC_Data[2]<180)&&(sen_dat[1]>180)) { vTaskResume(xforward); } } } }
static void vInterruptMutexSlaveTask( void *pvParameters ) { /* Just to avoid compiler warnings. */ ( void ) pvParameters; for( ;; ) { /* This task starts by suspending itself so when it executes can be controlled by the master task. */ vTaskSuspend( NULL ); /* This task will execute when the master task already holds the mutex. Attempting to take the mutex will place this task in the Blocked state. */ if( xSemaphoreTake( xMasterSlaveMutex, portMAX_DELAY ) != pdPASS ) { xErrorDetected = pdTRUE; } if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS ) { xErrorDetected = pdTRUE; } } }