void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) { const TickType_t xMaxWaitTime = pdMS_TO_TICKS( 20UL * ( uint32_t ) usStringLength ); /* Only a single port is supported. */ ( void ) pxPort; /* Note there is no mutual exclusion at the driver level. If more than one task is using the serial port then mutual exclusion should be provided where this function is called. */ /* Ensure notifications are not already waiting. */ ( void ) ulTaskNotifyTake( pdTRUE, 0 ); /* Remember which task is sending the byte. */ xTransmittingTask = xTaskGetCurrentTaskHandle(); /* Mark the start and end of the data being sent. */ pcStringStart = pcString; pcStringEnd = pcStringStart + usStringLength; /* Start to send the first byte. */ pxUARTA0->rTXBUF.r = ( uint_fast8_t ) *pcString; /* Enable the interrupt then wait for the byte to be sent. The interrupt will be disabled again in the ISR. */ MAP_UART_enableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT ); ulTaskNotifyTake( pdTRUE, xMaxWaitTime ); }
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime ) { const TickType_t xMaxWaitTime = pdMS_TO_TICKS( 20UL ); /* Only a single port is supported. */ ( void ) pxPort; /* Note there is no mutual exclusion at the driver level. If more than one task is using the serial port then mutual exclusion should be provided where this function is called. */ /* Ensure notifications are not already waiting. */ ( void ) ulTaskNotifyTake( pdTRUE, 0 ); /* Remember which task is sending the byte. */ xTransmittingTask = xTaskGetCurrentTaskHandle(); /* Mark the start and end of the data being sent - in this case just a single byte. */ pcStringStart = &cOutChar; pcStringEnd = pcStringStart + sizeof( cOutChar ); /* Start to send the byte. */ pxUARTA0->rTXBUF.r = ( uint_fast8_t ) cOutChar; /* Enable the interrupt then wait for the byte to be sent. The interrupt will be disabled again in the ISR. */ MAP_UART_enableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT ); ulTaskNotifyTake( pdTRUE, xMaxWaitTime ); return pdPASS; }
uint8_t xI2CSlaveTransfer ( I2C_ID_T i2c_id, uint8_t * rx_data, uint32_t timeout ) { /* Take the mutex to access shared memory */ xSemaphoreTake( I2C_mutex[i2c_id], portMAX_DELAY ); /* Register this task as the one to be notified when a message comes */ i2c_cfg[i2c_id].slave_task_id = xTaskGetCurrentTaskHandle(); /* Relase mutex */ xSemaphoreGive( I2C_mutex[i2c_id] ); /* Function blocks here until a message is received */ if ( ulTaskNotifyTake( pdTRUE, timeout ) == pdTRUE ) { /* Debug asserts */ configASSERT(rx_data); configASSERT(i2c_cfg[i2c_id].msg.rx_data); xSemaphoreTake( I2C_mutex[i2c_id], portMAX_DELAY ); /* Copy the rx buffer to the pointer given */ memcpy( rx_data, i2c_cfg[i2c_id].msg.rx_data, i2c_cfg[i2c_id].msg.rx_len ); xSemaphoreGive( I2C_mutex[i2c_id] ); } else { return 0; } /* Return message length */ return i2c_cfg[i2c_id].msg.rx_len; }
static void prvExerciseTaskNotificationAPI( void ) { uint32_t ulNotificationValue; BaseType_t xReturned; /* The task should not yet have a notification pending. */ xReturned = xTaskNotifyWait( 0, 0, &ulNotificationValue, mainDONT_BLOCK ); configASSERT( xReturned == pdFAIL ); configASSERT( ulNotificationValue == 0UL ); /* Exercise the 'give' and 'take' versions of the notification API. */ xTaskNotifyGive( xTaskGetCurrentTaskHandle() ); xTaskNotifyGive( xTaskGetCurrentTaskHandle() ); ulNotificationValue = ulTaskNotifyTake( pdTRUE, mainDONT_BLOCK ); configASSERT( ulNotificationValue == 2 ); /* Exercise the 'notify' and 'clear' API. */ ulNotificationValue = 20; xTaskNotify( xTaskGetCurrentTaskHandle(), ulNotificationValue, eSetValueWithOverwrite ); ulNotificationValue = 0; xReturned = xTaskNotifyWait( 0, 0, &ulNotificationValue, mainDONT_BLOCK ); configASSERT( xReturned == pdPASS ); configASSERT( ulNotificationValue == 20 ); xTaskNotify( xTaskGetCurrentTaskHandle(), ulNotificationValue, eSetValueWithOverwrite ); xReturned = xTaskNotifyStateClear( NULL ); configASSERT( xReturned == pdTRUE ); /* First time a notification was pending. */ xReturned = xTaskNotifyStateClear( NULL ); configASSERT( xReturned == pdFALSE ); /* Second time the notification was already clear. */ }
/* Function required in order to link UARTCommandConsole.c - which is used by multiple different demo application. */ void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) { const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 5000 ); /* Only one port is supported. */ ( void ) pxPort; /* Clear the flag before initiating a new transmission */ sci1_txdone = FALSE; /* Don't send the string unless the previous string has been sent. */ if( ( xSendingTask == NULL ) && ( usStringLength > 0 ) ) { /* Ensure the calling task's notification state is not already pending. */ xTaskNotifyStateClear( NULL ); /* Store the handle of the transmitting task. This is used to unblock the task when the transmission has completed. */ xSendingTask = xTaskGetCurrentTaskHandle(); /* Send the string using the auto-generated API. */ R_SCI1_Serial_Send( ( uint8_t * ) pcString, usStringLength ); /* Wait in the Blocked state (so not using any CPU time) until the transmission has completed. */ ulTaskNotifyTake( pdTRUE, xMaxBlockTime ); } }
i2c_err xI2CRead( I2C_ID_T i2c_id, uint8_t addr, uint8_t * rx_data, uint8_t rx_len ) { /* Take the mutex to access shared memory */ xSemaphoreTake( I2C_mutex[i2c_id], portMAX_DELAY ); i2c_cfg[i2c_id].msg.i2c_id = i2c_id; i2c_cfg[i2c_id].msg.addr = addr; i2c_cfg[i2c_id].msg.tx_len = 0; i2c_cfg[i2c_id].msg.rx_len = rx_len; i2c_cfg[i2c_id].master_task_id = xTaskGetCurrentTaskHandle(); xSemaphoreGive( I2C_mutex[i2c_id] ); /* Trigger the i2c interruption */ /* Is it safe to set the flag right now? Won't it stop another ongoing message that is being received for example? */ I2CCONSET( i2c_id, ( I2C_I2EN | I2C_STA ) ); /* Wait here until the message is received */ if ( ulTaskNotifyTake( pdTRUE, portMAX_DELAY ) == pdTRUE ){ /* Debug asserts */ configASSERT(rx_data); configASSERT(i2c_cfg[i2c_id].msg.rx_data); xSemaphoreTake( I2C_mutex[i2c_id], portMAX_DELAY ); /* Copy the received message to the given pointer */ memcpy (rx_data, i2c_cfg[i2c_id].msg.rx_data, i2c_cfg[i2c_id].msg.rx_len ); xSemaphoreGive( I2C_mutex[i2c_id] ); } return i2c_cfg[i2c_id].msg.error; }
/** * @brief Water task for valve controlling * @param pvParameters */ static void WATER_Task( void *pvParameters ) { uint16_t moisture; while(1) { ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); xSemaphoreTake(m_waterLock, portMAX_DELAY); SOIL_Open(); vTaskDelay(100 / portTICK_PERIOD_MS); // wait sensor stable moisture = SOIL_Read(); vTaskDelay(100 / portTICK_PERIOD_MS); // wait sensor stable moisture = SOIL_Read(); SOIL_Close(); if( moisture < m_moistureThreshold) { GPIO_ResetBits(WATER_PIN_PORT, WATER_PIN_NUM); vTaskDelay(m_period / portTICK_PERIOD_MS); GPIO_SetBits(WATER_PIN_PORT, WATER_PIN_NUM); } xSemaphoreGive(m_waterLock); } }
static void prvControllingTask( void *pvParameters ) { TaskHandle_t xBlockingTask; uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS; TickType_t xTimeAtStart; const TickType_t xStartMargin = 2UL; /* Just to remove compiler warnings. */ ( void ) pvParameters; xBlockingTask = xTaskGetTaskHandle( pcBlockingTaskName ); configASSERT( xBlockingTask ); for( ;; ) { /* Tell the secondary task to perform the next test. */ xTimeAtStart = xTaskGetTickCount(); xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite ); /* The secondary task has a higher priority, so will now be in the Blocked state to wait for a maximum of xMaxBlockTime. It expects that period to complete with a timeout. It will then block for xMaxBlockTimeAgain, but this time it expects to the block time to abort half way through. Block until it is time to send the abort to the secondary task. xStartMargin is used because this task takes timing from the beginning of the test, whereas the blocking task takes timing from the entry into the Blocked state - and as the tasks run at different priorities, there may be some discrepancy. Also, temporarily raise the priority of the controlling task to that of the blocking task to minimise discrepancies. */ vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY ); vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin ); xTaskAbortDelay( xBlockingTask ); /* Reset the priority to the normal controlling priority. */ vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY ); /* Now wait to be notified that the secondary task has completed its test. */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); /* Did the entire test run for the expected time, which is two full block times plus the half block time caused by calling xTaskAbortDelay()? */ prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) ); /* Move onto the next test. */ ulTestToPerform++; if( ulTestToPerform >= abtMAX_TESTS ) { ulTestToPerform = 0; } /* To indicate this task is still executing. */ xControllingCycles++; } }
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) { uint32_t ulReturn; BaseType_t xRunningPrivileged = xPortRaisePrivilege(); ulReturn = ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ); vPortResetPrivilege( xRunningPrivileged ); return ulReturn; }
static void prvTestAbortingTaskNotifyTake( void ) { TickType_t xTimeAtStart; uint32_t ulReturn; /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This first delay should just time out. */ ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); if( ulReturn != 0 ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This second delay should be aborted by the primary task half way through. */ ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); if( ulReturn != 0 ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This third delay should just time out again. */ ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); if( ulReturn != 0 ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); }
// has one job: updates the screen when notified static portTASK_FUNCTION(screen_task, param) { (void) param; ui_load_menu(); while (true) { // wait for someone to ask us to update the screen ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // update the screen lcd_write_screen(screen); } }
void task_led3(void *pvParameters) { // const TickType_t xDelay = 1000 / portTICK_PERIOD_MS; for (;;) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); LED_Blue.toggle(); // vTaskDelay(xDelay); } }
static void prvPermanentlyBlockingNotificationTask( void *pvParameters ) { /* Prevent compiler warning about unused parameter in the case that configASSERT() is not defined. */ ( void ) pvParameters; /* This task should block on a task notification, and never return. */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); /* The above ulTaskNotifyTake() call should never return, force an assert if it does. */ configASSERT( pvParameters != NULL ); vTaskDelete( NULL ); }
void controller_run() { // xio_init(); while (true) { /* Block to wait for prvTask1() to notify this task. */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); intepreterRunning = true; while(intepreterRunning) _controller_HSM(); // vTaskDelay(10 / portTICK_PERIOD_MS); } }
static void pppos_client_task(void *self_in) { ppp_if_obj_t *self = (ppp_if_obj_t*)self_in; uint8_t buf[256]; while (ulTaskNotifyTake(pdTRUE, 0) == 0) { int err; int len = mp_stream_rw(self->stream, buf, sizeof(buf), &err, 0); if (len > 0) { pppos_input_tcpip(self->pcb, (u8_t*)buf, len); } } self->client_task_handle = NULL; vTaskDelete(NULL); }
void emergencia_task(void) { uint32_t keyEntry = 0; uint8_t emergencyCount = 0; bool realease = false; while(1) { emergenciaFlag = false; realease = false; IR(ICU, IRQ8) = 0; //Clear any previously pending interrupts IEN(ICU, IRQ8) = 1; // Enable interrupt ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); IR(ICU, IRQ8) = 0; //Clear any previously pending interrupts IEN(ICU, IRQ8) = 0; // Enable interrupt while(EMERGENCIA && !realease) { vTaskDelay(1 / portTICK_PERIOD_MS); emergencyCount++; if(emergencyCount == 100) { static mn_screen_event_t mn_emergencia; emergenciaFlag = true; if (isCuttingGet() == true) { stopDuringCut_Set(true); } //machine_pause(); mn_emergencia.event = EMERGENCIA_SIGNAL_EVENT; xQueueSend( menu.qEvent, &mn_emergencia, 0 ); ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); realease = true; emergencyCount = 0; } } } }
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) { const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 150UL ); ( void ) pxPort; /* Note this is the currently sending task. */ xUARTSendingTask = xTaskGetCurrentTaskHandle(); /* Output uxStringLength bytes starting from pcString. */ XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) pcString, usStringLength ); /* Wait in the Blocked state (so not using any CPU time) for the Tx to complete. */ ulTaskNotifyTake( pdTRUE, xMaxBlockTime ); }
void socket_watcher_task(void *arg) { TickType_t xTimePrev = xTaskGetTickCount(); struct SocketWatcherData *pWatcher = (struct SocketWatcherData *)arg; for (;;) { ulTaskNotifyTake(pdTRUE, TICKS_TO_WAIT); if (pdFALSE == xSemaphoreTakeRecursive(m_watcher.mutw, TICKS_TO_WAIT)) { continue; } if (pWatcher->apb_size > 0) { if (FreeRTOS_select(pWatcher->xFD_set, TICKS_TO_WAIT) != 0) { pubnub_t **ppbp; for (ppbp = pWatcher->apb; ppbp < pWatcher->apb + pWatcher->apb_size; ++ppbp) { if (FreeRTOS_FD_ISSET((*ppbp)->pal.socket, pWatcher->xFD_set)) { pbnc_fsm(*ppbp); } } } } if (PUBNUB_TIMERS_API) { TickType_t xTimeNow = xTaskGetTickCount(); int elapsed = elapsed_ms(xTimePrev, xTimeNow); if (elapsed > 0) { pubnub_t *expired = pubnub_timer_list_as_time_goes_by(&m_watcher.timer_head, elapsed); while (expired != NULL) { pubnub_t *next = expired->next; pbnc_stop(expired, PNR_TIMEOUT); expired->previous = NULL; expired->next = NULL; expired = next; } xTimePrev = xTimeNow; } } xSemaphoreGiveRecursive(m_watcher.mutw); } }
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime ) { const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 150UL ); portBASE_TYPE xReturn; ( void ) pxPort; ( void ) xBlockTime; /* Note this is the currently sending task. */ xUARTSendingTask = xTaskGetCurrentTaskHandle(); XUartLite_Send( &xUartLiteInstance, ( unsigned char * ) &cOutChar, sizeof( cOutChar ) ); /* Wait in the Blocked state (so not using any CPU time) for the Tx to complete. */ xReturn = ulTaskNotifyTake( pdTRUE, xMaxBlockTime ); return xReturn; }
void ssp_write_read( uint8_t id, uint8_t *tx_buf, uint32_t tx_len, uint8_t *rx_buf, uint32_t rx_len, uint32_t timeout ) { Chip_SSP_DATA_SETUP_T * data_st = &ssp_cfg[id].xf_setup; tx_ssp = pvPortMalloc(tx_len); rx_ssp = pvPortMalloc(rx_len+tx_len); memcpy(tx_ssp, tx_buf, tx_len); ssp_cfg[id].caller_task = xTaskGetCurrentTaskHandle(); data_st->tx_cnt = 0; data_st->rx_cnt = 0; data_st->tx_data = tx_ssp; data_st->rx_data = rx_ssp; data_st->length = rx_len+tx_len; /* Assert Slave Select pin to enable the transfer */ ssp_ssel_control(id, ASSERT); if (ssp_cfg[id].polling) { Chip_SSP_RWFrames_Blocking(ssp_cfg[id].lpc_id, data_st); ssp_ssel_control(id, DEASSERT); } else { Chip_SSP_Int_FlushData(ssp_cfg[id].lpc_id); /* Enable interrupt-based data transmission */ Chip_SSP_Int_Enable( ssp_cfg[id].lpc_id ); /* User defined timeout ? */ /* Wait until the transfer is finished */ ulTaskNotifyTake(pdTRUE, timeout); } if (rx_buf && rx_len > 0) { memcpy(rx_buf, rx_ssp, rx_len+tx_len); } vPortFree(rx_ssp); vPortFree(tx_ssp); }
i2c_err xI2CWrite( I2C_ID_T i2c_id, uint8_t addr, uint8_t * tx_data, uint8_t tx_len ) { /* Checks if the message will fit in our buffer */ if ( tx_len >= i2cMAX_MSG_LENGTH ) { return i2c_err_MAX_LENGTH; } /* Take the mutex to access the shared memory */ if (xSemaphoreTake( I2C_mutex[i2c_id], 10 ) == pdTRUE) { xSemaphoreTake( I2C_mutex[i2c_id], 10 ); /* Populate the i2c config struct */ i2c_cfg[i2c_id].msg.i2c_id = i2c_id; i2c_cfg[i2c_id].msg.addr = addr; memcpy(i2c_cfg[i2c_id].msg.tx_data, tx_data, tx_len); i2c_cfg[i2c_id].msg.tx_len = tx_len; i2c_cfg[i2c_id].msg.rx_len = 0; i2c_cfg[i2c_id].master_task_id = xTaskGetCurrentTaskHandle(); xSemaphoreGive( I2C_mutex[i2c_id] ); } else { return i2c_err_FAILURE; } /* Trigger the i2c interruption */ /* @bug Is it safe to set the flag right now? Won't it stop another ongoing message that is being received for example? */ I2CCONCLR( i2c_id, ( I2C_SI | I2C_STO | I2C_STA | I2C_AA)); I2CCONSET( i2c_id, ( I2C_I2EN | I2C_STA ) ); if ( ulTaskNotifyTake( pdTRUE, portMAX_DELAY ) == pdTRUE ){ /* Include the error in i2c_cfg global structure */ //I2CCONSET(i2c_id, I2C_I2EN | I2C_AA ); return i2c_cfg[i2c_id].msg.error; } /* Should not get here, so return failure */ return i2c_err_FAILURE; }
static void prvUARTCommandConsoleTask( void *pvParameters ) { char cRxedChar; int8_t cInputIndex = 0, *pcOutputString; uint8_t port; static int8_t cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ]; portBASE_TYPE xReturned; ( void ) pvParameters; /* Wait indefinitly until a '\r' is received on one of the ports */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); port = PcPort; cRxedChar = '\0'; /* Obtain the address of the output buffer. Note there is no mutual exclusion on this buffer as it is assumed only one command console interface will be used at any one time. */ pcOutputString = FreeRTOS_CLIGetOutputBuffer(); /* By default, the UART interrupt priority will have been set to the lowest possible. It must be kept at or below configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, but can be raised above its default priority using a FreeRTOS_ioctl() call with the ioctlSET_INTERRUPT_PRIORITY command. */ //xReturned = FreeRTOS_ioctl( xConsoleUART, ioctlSET_INTERRUPT_PRIORITY, ( void * ) ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 1 ) ); //configASSERT( xReturned ); /* Send the welcome message. */ writePxITMutex(port, pcWelcomeMessage, strlen(pcWelcomeMessage), cmd50ms); for( ;; ) { /* Only interested in reading one character at a time. */ readPxMutex(port, &cRxedChar, sizeof( cRxedChar ), cmd50ms, HAL_MAX_DELAY); /* Echo the character back. */ writePxITMutex(port, &cRxedChar, 1, cmd50ms); if( cRxedChar == '\r' ) { /* The input command string is complete. Ensure the previous UART transmission has finished before sending any more data. This task will be held in the Blocked state while the Tx completes, if it has not already done so, so no CPU time will be wasted by polling. */ writePxITMutex(port, pcNewLine, strlen(pcNewLine), cmd50ms); /* See if the command is empty, indicating that the last command is to be executed again. */ if( cInputIndex == 0 ) { strcpy( ( char * ) cInputString, ( char * ) cLastInputString ); } /* Pass the received command to the command interpreter. The command interpreter is called repeatedly until it returns pdFALSE as it might generate more than one string. */ do { /* Once again, just check to ensure the UART has completed sending whatever it was sending last. This task will be held in the Blocked state while the Tx completes, if it has not already done so, so no CPU time is wasted polling. */ /* Get the string to write to the UART from the command interpreter. */ xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE ); /* Write the generated string to the UART. */ //writePxITMutex(port, (char*) pcOutputString, strlen((char*) pcOutputString), cmd50ms); writePxMutex(port, (char*) pcOutputString, strlen((char*) pcOutputString), cmd50ms, HAL_MAX_DELAY); } while( xReturned != pdFALSE ); /* All the strings generated by the input command have been sent. Clear the input string ready to receive the next command. Remember the command that was just processed first in case it is to be processed again. */ strcpy( ( char * ) cLastInputString, ( char * ) cInputString ); cInputIndex = 0; memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); /* Start to transmit a line separator, just to make the output easier to read. */ writePxITMutex(port, pcEndOfCommandOutputString, strlen(pcEndOfCommandOutputString), cmd50ms); } else { if( cRxedChar == '\n' ) { /* Ignore the character. */ } else if( cRxedChar == '\b' ) { /* Backspace was pressed. Erase the last character in the string - if any. */ if( cInputIndex > 0 ) { cInputIndex--; cInputString[ cInputIndex ] = '\0'; } } else { /* A character was entered. Add it to the string entered so far. When a \n is entered the complete string will be passed to the command interpreter. */ if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) ) { if( cInputIndex < cmdMAX_INPUT_SIZE ) { cInputString[ cInputIndex ] = cRxedChar; cInputIndex++; } } } } taskYIELD(); } }
void plasma_task(void) { uint8_t debounce; uint32_t qSend = 0; bool pinState; while(1) { ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); ArcoOktaskIdle = true; debounce = 0; while(ArcoOktaskIdle) { pinState = ARCO_OK; vTaskDelay(pdMS_TO_TICKS(10)); if(pinState == ARCO_OK) { debounce++; } if(debounce == DEBOUNCE_COUNT) { if (!ARCO_OK) { if (!simTorch) { //xTaskNotifyGive(xCncTaskHandle); xSemaphoreGive( xArcoOkSync ); } } debounce = 0; do { if(ARCO_OK) { debounce++; arcoOkSet(false); } else { debounce = 0; arcoOkSet(true); } vTaskDelay(pdMS_TO_TICKS(10)); }while(debounce != ARCOOK_DELAY_COUNT && isCutting && ArcoOktaskIdle); if (isCutting && ArcoOktaskIdle) { // xTimerStop( swTimers[AUTO_MENU_TIMER], 0 ); stopDuringCut_Set(true); // vTaskPrioritySet( xCncTaskHandle, 3 ); // warm_stop(2); // vTaskPrioritySet( xCncTaskHandle, 1 ); // TORCH = FALSE; // if( uxTaskPriorityGet( xCncTaskHandle ) != 1 ) // { // // } // lstop = true; // ut_lcd_output_warning("PLASMA NÃO\nTRANSFERIDO\n"); // while(qSend != KEY_ESC){ // WDT_FEED // xQueueReceive( qKeyboard, &qSend, portMAX_DELAY ); // } mn_screen_event_t arcoOk_Fail; arcoOk_Fail.event = ARCO_OK_FAILED_EVENT; qSend = ARCO_OK_FAILED; xQueueSend( menu.qEvent, &arcoOk_Fail, 0 ); } } } } }
static void prvGMACDeferredInterruptHandlerTask( void *pvParameters ) { xNetworkBufferDescriptor_t *pxNetworkBuffer = NULL; xIPStackEvent_t xRxEvent = { eEthernetRxEvent, NULL }; static const TickType_t xBufferWaitDelay = 1500UL / portTICK_RATE_MS; uint32_t ulReturned; /* This is a very simply but also inefficient implementation. */ ( void ) pvParameters; for( ;; ) { /* Wait for the GMAC interrupt to indicate that another packet has been received. A while loop is used to process all received frames each time this task is notified, so it is ok to clear the notification count on the take (hence the first parameter is pdTRUE ). */ ulTaskNotifyTake( pdTRUE, xBufferWaitDelay ); ulReturned = GMAC_OK; while( ulReturned == GMAC_OK ) { /* Allocate a buffer to hold the data if one is not already held. */ if( pxNetworkBuffer == NULL ) { pxNetworkBuffer = pxNetworkBufferGet( ipTOTAL_ETHERNET_FRAME_SIZE, xBufferWaitDelay ); } if( pxNetworkBuffer != NULL ) { /* Attempt to read data. */ ulReturned = gmac_dev_read( &xGMACStruct, pxNetworkBuffer->pucEthernetBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, ( uint32_t * ) &( pxNetworkBuffer->xDataLength ) ); if( ulReturned == GMAC_OK ) { #if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 1 { if( pxNetworkBuffer->xDataLength > 0 ) { /* If the frame would not be processed by the IP stack then don't even bother sending it to the IP stack. */ if( eConsiderFrameForProcessing( pxNetworkBuffer->pucEthernetBuffer ) != eProcessBuffer ) { pxNetworkBuffer->xDataLength = 0; } } } #endif if( pxNetworkBuffer->xDataLength > 0 ) { /* Store a pointer to the network buffer structure in the padding space that was left in front of the Ethernet frame. The pointer is needed to ensure the network buffer structure can be located when it is time for it to be freed if the Ethernet frame gets used as a zero copy buffer. */ *( ( xNetworkBufferDescriptor_t ** ) ( ( pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING ) ) ) = pxNetworkBuffer; /* Data was received and stored. Send it to the IP task for processing. */ xRxEvent.pvData = ( void * ) pxNetworkBuffer; if( xQueueSendToBack( xNetworkEventQueue, &xRxEvent, ( TickType_t ) 0 ) == pdFALSE ) { /* The buffer could not be sent to the IP task. The frame will be dropped and the buffer reused. */ iptraceETHERNET_RX_EVENT_LOST(); } else { iptraceNETWORK_INTERFACE_RECEIVE(); /* The buffer is not owned by the IP task - a new buffer is needed the next time around. */ pxNetworkBuffer = NULL; } } else { /* The buffer does not contain any data so there is no point sending it to the IP task. Re-use the buffer on the next loop. */ iptraceETHERNET_RX_EVENT_LOST(); } } else { /* No data was received, keep the buffer for re-use. The loop will exit as ulReturn is not GMAC_OK. */ } } else { /* Left a frame in the driver as a buffer was not available. Break out of loop. */ ulReturned = GMAC_INVALID; } } } }
void os_threadWait(void) { (void)ulTaskNotifyTake(true, portMAX_DELAY); }
void vMainMappingTask( void *pvParameters ) { // Initialize the buffers used for mapping operations. Each sensor has its // own buffers that are allocated on the heap. point_buffer_t *PointBuffers = pvPortMalloc(NUMBER_OF_SENSORS * sizeof(point_buffer_t)); line_buffer_t *LineBuffers = pvPortMalloc(NUMBER_OF_SENSORS * sizeof(line_buffer_t)); // Set initial lengths to 0 for (uint8_t i = 0; i < NUMBER_OF_SENSORS; i++) { PointBuffers[i].len = 0; LineBuffers[i].len = 0; } // Initialize the repo for storing the completely merged line segments line_repo_t *LineRepo = pvPortMalloc(sizeof(line_repo_t)); LineRepo->len = 0; // Verify allocation configASSERT(PointBuffers && LineBuffers && LineRepo ); // Set task to run at a fixed frequency /* TickType_t xLastWakeTime; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; xLastWakeTime = xTaskGetTickCount(); */ while (1) { //vTaskDelayUntil(&xLastWakeTime, xFrequency); if (gHandshook == TRUE && gPaused == FALSE) { // Read the robots current pose pose_t Pose; xQueuePeek(globalPoseQ, &Pose, 10 / portTICK_PERIOD_MS); // Convert to centimeters Pose.x /= 10.0; Pose.y /= 10.0; // Put inside [0,2pi) func_wrap_to_2pi(&Pose.theta); // Block here waiting for measurement from the sensor tower. measurement_t Measurement; if (xQueueReceive(measurementQ, &Measurement, 200 / portTICK_PERIOD_MS) == pdTRUE) { // Append new IR measurements to the end of each PB mapping_update_point_buffers(PointBuffers, Measurement, Pose); } // Check for notification from sensor tower task. Do not wait. if (ulTaskNotifyTake(pdTRUE, 0) == 1) { // Run create and merge functions for each of the sensors' buffers for (uint8_t j = 0; j < NUMBER_OF_SENSORS; j++) { mapping_line_create(&PointBuffers[j], &LineBuffers[j]); mapping_line_merge(&LineBuffers[j], LineRepo); } // Merge the repo with itself until it cannot be reduced further uint8_t lastRepoLen; do { lastRepoLen = LineRepo->len; LineRepo = mapping_repo_merge(LineRepo); } while (LineRepo->len < lastRepoLen); } line_t LineOut = { 0 }; if (LineRepo->len > 0) { LineOut = LineRepo->buffer[LineRepo->len-1]; LineRepo->len--; } #ifdef SEND_LINE // Send update to server. LineOut contains all zeroes if one was not available from the LineRepo. send_line(ROUND(Pose.x), ROUND(Pose.y), ROUND(Pose.theta*RAD2DEG), LineOut); #endif /* SEND_LINE */ } else { // If disconnected and/or paused vTaskDelay(200 / portTICK_PERIOD_MS); } } }
void gps_task(void *pArg) { char rx_sentence[200]; char *data_ptr; uint32_t len; uint32_t notificationValue; PRINTF("from gps task...\r\n"); /* Use Task Notification to sychronize between UART Rx handler and GPS task */ xGpsTaskHandle = xTaskGetCurrentTaskHandle(); /* Initialize UART driver with given parameters */ UART_Init(GPS_UART_BASE, &gps_uart_config, GPS_UART_SRCCLK); /* Initialize UART driver and install our own handler for UART Rx data, which is called by the ISR */ UART_TransferCreateHandle(GPS_UART_BASE, &gps_uart_handle, gps_uart_rx_handler, NULL); /* Set receive buffer pointer explicitly for custom handling */ gps_uart_handle.rxData = gps_rx_buf; gps_uart_handle.rxDataSize = 1; /* Enable RX interrupt (start reception of bytes from GPS module) */ UART_EnableInterrupts(GPS_UART_BASE, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); /* Turn on RED LED */ while (1) { /* Wait for notification from UART Rx handler */ if((notificationValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY)) == 1) { /* Copy the received sentence */ len = gps_rx_len; memcpy((void *) rx_sentence, (void *) gps_rx_sentence, len); /* Parse the received sentence to update gps_info structure */ if (NULL != strstr(rx_sentence, "GPGGA")) { data_ptr = &rx_sentence[6]; gps_parse_gga(data_ptr, &gps_info); } if ((NULL != strstr(rx_sentence, "GPRMC")) || (NULL != strstr(rx_sentence, "GNRMC"))) { data_ptr = &rx_sentence[6]; gps_parse_rmc(data_ptr, &gps_info); } } /* Check for GPS Fix */ if (NO_FIX != gps_info.fix) { /* Turn on GREEN LED */ LED_GREEN_ON(); } else { /* Turn off GREEN LED */ LED_GREEN_OFF(); } } }
static void prvNotifiedTask( void *pvParameters ) { const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0; TickType_t xPeriod; /* Remove compiler warnings about unused parameters. */ ( void ) pvParameters; /* Run a few tests that can be done from a single task before entering the main loop. */ prvSingleTaskTests(); /* Create the software timer that is used to send notifications to this task. Notifications are also received from an interrupt. */ xTimer = xTimerCreate( "Notifier", xMaxPeriod, pdFALSE, NULL, prvNotifyingTimer ); for( ;; ) { /* Start the timer again with a different period. Sometimes the period will be higher than the tasks block time, sometimes it will be lower than the tasks block time. */ xPeriod = prvRand() % xMaxPeriod; if( xPeriod < xMinPeriod ) { xPeriod = xMinPeriod; } /* Change the timer period and start the timer. */ xTimerChangePeriod( xTimer, xPeriod, portMAX_DELAY ); /* Block waiting for the notification again with a different period. Sometimes the period will be higher than the tasks block time, sometimes it will be lower than the tasks block time. */ xPeriod = prvRand() % xMaxPeriod; if( xPeriod < xMinPeriod ) { xPeriod = xMinPeriod; } /* Block to wait for a notification but without clearing the notification count, so only add one to the count of received notifications as any other notifications will remain pending. */ if( ulTaskNotifyTake( pdFALSE, xPeriod ) != 0 ) { ulTimerNotificationsReceived++; } /* Take a notification without clearing again, but this time without a block time specified. */ if( ulTaskNotifyTake( pdFALSE, xDontBlock ) != 0 ) { ulTimerNotificationsReceived++; } /* Wait for the next notification from the timer, clearing all notifications if one is received, so this time adding the total number of notifications that were pending as none will be left pending after the function call. */ ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod ); /* Wait for the next notification again, clearing all notifications if one is received, but this time blocking indefinitely. */ ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); /* Incremented to show the task is still running. */ ulNotifyCycleCount++; } }
static void prvEMACHandlerTask( void *pvParameters ) { TimeOut_t xPhyTime; TickType_t xPhyRemTime; UBaseType_t uxCount; #if( ipconfigZERO_COPY_TX_DRIVER != 0 ) NetworkBufferDescriptor_t *pxBuffer; #endif uint8_t *pucBuffer; BaseType_t xResult = 0; uint32_t xStatus; const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS ); /* Remove compiler warnings about unused parameters. */ ( void ) pvParameters; configASSERT( xEMACTaskHandle ); vTaskSetTimeOutState( &xPhyTime ); xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS ); for( ;; ) { vCheckBuffersAndQueue(); if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 ) { /* No events to process now, wait for the next. */ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime ); } if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 ) { ulISREvents &= ~EMAC_IF_RX_EVENT; /* Wait for the EMAC interrupt to indicate that another packet has been received. */ xResult = prvEMACRxPoll(); } if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 ) { /* Future extension: code to release TX buffers if zero-copy is used. */ ulISREvents &= ~EMAC_IF_TX_EVENT; while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE ) { #if( ipconfigZERO_COPY_TX_DRIVER != 0 ) { pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer ); if( pxBuffer != NULL ) { vReleaseNetworkBufferAndDescriptor( pxBuffer ); tx_release_count[ 0 ]++; } else { tx_release_count[ 1 ]++; } } #else { tx_release_count[ 0 ]++; } #endif uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore ); if( uxCount < GMAC_TX_BUFFERS ) { /* Tell the counting semaphore that one more TX descriptor is available. */ xSemaphoreGive( xTXDescriptorSemaphore ); } } } if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 ) { /* Future extension: logging about errors that occurred. */ ulISREvents &= ~EMAC_IF_ERR_EVENT; } if( xResult > 0 ) { /* A packet was received. No need to check for the PHY status now, but set a timer to check it later on. */ vTaskSetTimeOutState( &xPhyTime ); xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS ); xResult = 0; } else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) { /* Check the link status again. */ xStatus = ulReadMDIO( PHY_REG_01_BMSR ); if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) ) { ulPHYLinkStatus = xStatus; FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) ); } vTaskSetTimeOutState( &xPhyTime ); if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) { xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS ); } else { xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS ); } } } }