本帖最后由 aramy 于 2024-7-31 09:42 编辑
Beetle ESP32 C6迷你开发板搭载了160MHz的高性能RISC-V 32位处理器。如果使用单任务处理问题,大多数时间都会浪费在各类传感器和外设的等待上,为了更好地利用处理器,引入了操作系统,可以让用户使用多任务处理问题,提升了处理器的利用率。ESP32 C6中使用了FreeRTOS操作系统。用户可以在FreeRTOS操作系统创建多个任务去处理不同的问题。这里实现了在FreeRTOS操作系统上创建两个任务,两个任务之间使用消息队列进行通讯的功能。
需求描述:通过Beetle ESP32 C6开发板上的按键,控制板载的LED灯的亮灭。需求很简单,但是是使用两个任务来实现的。
任务1:LED控制任务,负责控制LED灯的亮灭。任务阻塞在读取消息队列上,当读取到消息时,通过消息内容进行判断。当消息内容为0时,关闭LED灯,为1时,点亮LED灯。
任务2:按键读取任务。负责读取按键值。设置一个状态位,当按键按下时,就取反状态位的值,然后将状态位封装进消息队列,丢到消息队列中发送出去。
具体实现:实习使用了esp-idf编程。这里我使用的esp-idf版本是5.1.2。使用vscode作为编辑器。使用官方例程blink作为项目基础进行修改。
第一步:先修改芯片类型,将芯片类型修改为esp32c6,然后修改串口号,选中Beetle ESP32 C6迷你开发板插入电脑后分配的串口号。参考开发板的电路图定义好LED的管脚和按键的管脚。
#define LED1_IO 15
#define BUTTON_PIN 9
第二步:定义多个任务。
void buttontask(void *arg)
{
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_PIN, GPIO_PULLUP_ONLY);
char s_led_state[1];
while (1)
{
if (gpio_get_level(BUTTON_PIN) == 0)
{
xQueueSend(queue1, &s_led_state, portMAX_DELAY);
s_led_state[0] = !s_led_state[0];
ESP_LOGI(TAG, "Button Pressed!\n");
}
vTaskDelay(200 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL); // 在本函数中删除,不需要传递句柄
}
void ledBlinkTask(void *pvParam)
{
char led_state[1];
gpio_set_direction(LED1_IO, GPIO_MODE_OUTPUT);
while (1)
{
if (xQueueReceive(queue1, &led_state, portMAX_DELAY))
{
gpio_set_level(LED1_IO, led_state[0]);
ESP_LOGI(TAG, "Get mesage %d!",led_state[0]);
}
}
vTaskDelete(NULL); // 在本函数中删除,不需要传递句柄
}
这里定义了两个任务。一个是用来接收按键的任务,一个是用来控制LED的任务。可以看出任务首先对GPIO进行初始化,设置GPIO方向为为输入或输出。然后就是一个死循环,任务将在这个循环内一直执行,直至退出或被杀死。在按键任务中定义了一个s_led_state的变量,当检测到按键有按下后,就将这个变量发送到消息队列中。然后将s_led_state取反。在led控制任务中,任务会阻塞在接收消息队列位置,当消息队列中有消息了,就取出消息,并修改LED灯的状态。
第三步:启动任务。
void app_main(void)
{
queue1 = xQueueCreate(5, sizeof(char));
xTaskCreate(ledBlinkTask, "ledBlinkTask", 2048, NULL, 1, NULL); // 传出任务句柄
xTaskCreate(buttontask, "buttontask", 2048, NULL, 1, NULL);
while (1)
{
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
}
在main方法中首先是定义了一个消息队列,这里消息队列的最大容量为5,意味着最多可以容纳5个消息。当消息队列中消息数量等于5时,就无法在容纳新的消息了。消息队列使用了一个全局变量名称,这样在所有的任务中都能直接通过变量名访问到这个消息队列了。然后是启动子任务。主函数自身也是一个任务,但是这个任务没有做任何功能。
第四步:效果展示.。通过vscode编译,然后烧录。按板子右下角的按键即可控制LED灯的亮灭。
VID_20240727_104906