task_delay

这个task_delay是通过把当前线程挂起,实现时间的延时,同时释放CPU给其他线程使用。

但其精度将由线程的切换时间片决定,比如线程的切换时间是10ms,那么每次task_delay就是比10ms要大,那怕你task_delay(1),那也是10ms,而不是1ms.


如果需要精确的delay,那只能通过消耗CPU的时间,重新实现task_delay接口,判断tick数,来精确delay.

/* * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ /* * The following example demonstrates a master node in a TWAI network. The master * node is responsible for initiating and stopping the transfer of data messages. * The example will execute multiple iterations, with each iteration the master * node will do the following: * 1) Start the TWAI driver * 2) Repeatedly send ping messages until a ping response from slave is received * 3) Send start command to slave and receive data messages from slave * 4) Send stop command to slave and wait for stop response from slave * 5) Stop the TWAI driver */ #include <stdio.h> #include <stdlib.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "esp_err.h" #include "esp_log.h" #include "driver/twai.h" /* --------------------- Definitions and static variables ------------------ */ //Example Configuration #define PING_PERIOD_MS 250 #define NO_OF_DATA_MSGS 50 #define NO_OF_ITERS 3 #define ITER_DELAY_MS 1000 #define RX_TASK_PRIO 8 #define TX_TASK_PRIO 9 #define CTRL_TSK_PRIO 10 #define TX_GPIO_NUM CONFIG_EXAMPLE_TX_GPIO_NUM #define RX_GPIO_NUM CONFIG_EXAMPLE_RX_GPIO_NUM #define EXAMPLE_TAG "TWAI Master" #define ID_MASTER_STOP_CMD 0x0A0 #define ID_MASTER_START_CMD 0x0A1 #define ID_MASTER_PING 0x0A2 #define ID_SLAVE_STOP_RESP 0x0B0 #define ID_SLAVE_DATA 0x0B1 #define ID_SLAVE_PING_RESP 0x0B2 typedef enum { TX_SEND_PINGS, TX_SEND_START_CMD, TX_SEND_STOP_CMD, TX_TASK_EXIT, } tx_task_action_t; typedef enum { RX_RECEIVE_PING_RESP, RX_RECEIVE_DATA, RX_RECEIVE_STOP_RESP, RX_TASK_EXIT, } rx_task_action_t; static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS(); static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NORMAL); static const twai_message_t ping_message = { // Message type and format settings .extd = 0, // Standard Format message (11-bit ID) .rtr = 0, // Send a data frame .ss = 1, // Is single shot (won't retry on error or NACK) .self = 0, // Not a self reception request .dlc_non_comp = 0, // DLC is less than 8 // Message ID and payload .identifier = ID_MASTER_PING, .data_length_code = 0, .data = {0}, }; static const twai_message_t start_message = { // Message type and format settings .extd = 0, // Standard Format message (11-bit ID) .rtr = 0, // Send a data frame .ss = 0, // Not single shot .self = 0, // Not a self reception request .dlc_non_comp = 0, // DLC is less than 8 // Message ID and payload .identifier = ID_MASTER_START_CMD, .data_length_code = 0, .data = {0}, }; static const twai_message_t stop_message = { // Message type and format settings .extd = 0, // Standard Format message (11-bit ID) .rtr = 0, // Send a data frame .ss = 0, // Not single shot .self = 0, // Not a self reception request .dlc_non_comp = 0, // DLC is less than 8 // Message ID and payload .identifier = ID_MASTER_STOP_CMD, .data_length_code = 0, .data = {0}, }; static QueueHandle_t tx_task_queue; static QueueHandle_t rx_task_queue; static SemaphoreHandle_t stop_ping_sem; static SemaphoreHandle_t ctrl_task_sem; static SemaphoreHandle_t done_sem; /* --------------------------- Tasks and Functions -------------------------- */ static void twai_receive_task(void *arg) { while (1) { rx_task_action_t action; xQueueReceive(rx_task_queue, &action, portMAX_DELAY); if (action == RX_RECEIVE_PING_RESP) { //Listen for ping response from slave while (1) { twai_message_t rx_msg; twai_receive(&rx_msg, portMAX_DELAY); if (rx_msg.identifier == ID_SLAVE_PING_RESP) { xSemaphoreGive(stop_ping_sem); xSemaphoreGive(ctrl_task_sem); break; } } } else if (action == RX_RECEIVE_DATA) { //Receive data messages from slave uint32_t data_msgs_rec = 0; while (data_msgs_rec < NO_OF_DATA_MSGS) { twai_message_t rx_msg; twai_receive(&rx_msg, portMAX_DELAY); if (rx_msg.identifier == ID_SLAVE_DATA) { uint32_t data = 0; for (int i = 0; i < rx_msg.data_length_code; i++) { data |= (rx_msg.data[i] << (i * 8)); } ESP_LOGI(EXAMPLE_TAG, "Received data value %"PRIu32, data); data_msgs_rec ++; } } xSemaphoreGive(ctrl_task_sem); } else if (action == RX_RECEIVE_STOP_RESP) { //Listen for stop response from slave while (1) { twai_message_t rx_msg; twai_receive(&rx_msg, portMAX_DELAY); if (rx_msg.identifier == ID_SLAVE_STOP_RESP) { xSemaphoreGive(ctrl_task_sem); break; } } } else if (action == RX_TASK_EXIT) { break; } } vTaskDelete(NULL); } static void twai_transmit_task(void *arg) { while (1) { tx_task_action_t action; xQueueReceive(tx_task_queue, &action, portMAX_DELAY); if (action == TX_SEND_PINGS) { //Repeatedly transmit pings ESP_LOGI(EXAMPLE_TAG, "Transmitting ping"); while (xSemaphoreTake(stop_ping_sem, 0) != pdTRUE) { twai_transmit(&ping_message, portMAX_DELAY); vTaskDelay(pdMS_TO_TICKS(PING_PERIOD_MS)); } } else if (action == TX_SEND_START_CMD) { //Transmit start command to slave twai_transmit(&start_message, portMAX_DELAY); ESP_LOGI(EXAMPLE_TAG, "Transmitted start command"); } else if (action == TX_SEND_STOP_CMD) { //Transmit stop command to slave twai_transmit(&stop_message, portMAX_DELAY); ESP_LOGI(EXAMPLE_TAG, "Transmitted stop command"); } else if (action == TX_TASK_EXIT) { break; } } vTaskDelete(NULL); } static void twai_control_task(void *arg) { xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); tx_task_action_t tx_action; rx_task_action_t rx_action; for (int iter = 0; iter < NO_OF_ITERS; iter++) { ESP_ERROR_CHECK(twai_start()); ESP_LOGI(EXAMPLE_TAG, "Driver started"); //Start transmitting pings, and listen for ping response tx_action = TX_SEND_PINGS; rx_action = RX_RECEIVE_PING_RESP; xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); //Send Start command to slave, and receive data messages xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); tx_action = TX_SEND_START_CMD; rx_action = RX_RECEIVE_DATA; xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); //Send Stop command to slave when enough data messages have been received. Wait for stop response xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); tx_action = TX_SEND_STOP_CMD; rx_action = RX_RECEIVE_STOP_RESP; xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); ESP_ERROR_CHECK(twai_stop()); ESP_LOGI(EXAMPLE_TAG, "Driver stopped"); vTaskDelay(pdMS_TO_TICKS(ITER_DELAY_MS)); } //Stop TX and RX tasks tx_action = TX_TASK_EXIT; rx_action = RX_TASK_EXIT; xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY); xQueueSend(rx_task_queue, &rx_action, portMAX_DELAY); //Delete Control task xSemaphoreGive(done_sem); vTaskDelete(NULL); } void app_main(void) { //Create tasks, queues, and semaphores rx_task_queue = xQueueCreate(1, sizeof(rx_task_action_t)); tx_task_queue = xQueueCreate(1, sizeof(tx_task_action_t)); ctrl_task_sem = xSemaphoreCreateBinary(); stop_ping_sem = xSemaphoreCreateBinary(); done_sem = xSemaphoreCreateBinary(); xTaskCreatePinnedToCore(twai_receive_task, "TWAI_rx", 4096, NULL, RX_TASK_PRIO, NULL, tskNO_AFFINITY); xTaskCreatePinnedToCore(twai_transmit_task, "TWAI_tx", 4096, NULL, TX_TASK_PRIO, NULL, tskNO_AFFINITY); xTaskCreatePinnedToCore(twai_control_task, "TWAI_ctrl", 4096, NULL, CTRL_TSK_PRIO, NULL, tskNO_AFFINITY); //Install TWAI driver ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config)); ESP_LOGI(EXAMPLE_TAG, "Driver installed"); xSemaphoreGive(ctrl_task_sem); //Start control task xSemaphoreTake(done_sem, portMAX_DELAY); //Wait for completion //Uninstall TWAI driver ESP_ERROR_CHECK(twai_driver_uninstall()); ESP_LOGI(EXAMPLE_TAG, "Driver uninstalled"); //Cleanup vQueueDelete(rx_task_queue); vQueueDelete(tx_task_queue); vSemaphoreDelete(ctrl_task_sem); vSemaphoreDelete(stop_ping_sem); vSemaphoreDelete(done_sem); } 增强上述代码可读性,将添加注释后的代码发出
10-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值