使用xTaskCreate运行函数,但任务创建后的代码不会运行

问题描述 投票:0回答:1

我正在使用 esp32 创建一个项目来模拟交通灯。我有两个交通灯,当一个是红灯时,另一个是绿灯。一个灯应保持绿色 10 秒,然后变为红色,然后另一个灯将变为绿色。在这个项目中,我应该将其设置为监听按钮按下,如果按下,灯将保持绿色 20 秒。我做了一个名为buttonCheck的函数来检查按钮是否被按下。我使用 xTaskCreate 让它在灯运行时检查按钮按下情况,但当我创建任务时,任务后面的代码不起作用。

按钮检查功能:

void buttonCheck(void *parameters){
    int *timer = (int *)parameters;
    esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
    gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
    gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
    bool timeswitch = true;
    vTaskDelay(500/portTICK_PERIOD_MS);
    while(1){
        if(gpio_get_level(GPIO_NUM_0) == 0 && timeswitch){
            *timer = 2000;
            timeswitch = false;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }

        if(gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch){
            *timer = 10000;
            timeswitch = true;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }
        //  vTaskDelay(10000/portTICK_PERIOD_MS);
    }
}

我如何调用main中的函数以及后面的代码

xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);

while (1) {
    if (EWgreen) {
        toRed(EWlight);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
        toGreen(NSlight);
        EWgreen = false;
    }
    else {
        toRed(NSlight);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
        toGreen(EWlight);
        EWgreen = true;
    }
    vTaskDelay(timer / portTICK_PERIOD_MS);
}

函数确实起作用,并且任务执行。我是嵌入式应用程序的新手,因此在做了一些研究后,我尝试减少/增加堆栈大小并降低函数的优先级。这些并没有改变结果。我想在函数进入 while 循环之前插入一个 taskDelay,希望这能让控制器在创建任务后有更多时间到达代码。这也没有改变结果。任何帮助将不胜感激!

这是所有代码:

#include<stdio.h>
#include<freertos/FreeRTOS.h>
#include<freertos/task.h>
#include<driver/gpio.h>

struct ledstuff {

    gpio_num_t red;
    gpio_num_t yellow;
    gpio_num_t green;

};

typedef struct ledstuff ledinfo;

void
toRed(ledinfo data)
{

    gpio_set_level(data.green, 0);
    gpio_set_level(data.yellow, 1);
    vTaskDelay(2000 / portTICK_PERIOD_MS);
    gpio_set_level(data.yellow, 0);
    gpio_set_level(data.red, 1);

}

void
toGreen(ledinfo data)
{

    gpio_set_level(data.red, 0);
    gpio_set_level(data.yellow, 0);
    gpio_set_level(data.green, 1);

}

void
trafficLights(void *params)
{

    int *timer = (int *) params;
    bool EWgreen = true;
    ledinfo NSlight;

    NSlight.red = GPIO_NUM_19;
    NSlight.yellow = GPIO_NUM_18;
    NSlight.green = GPIO_NUM_5;
    ledinfo EWlight;

    EWlight.red = GPIO_NUM_27;
    EWlight.yellow = GPIO_NUM_26;
    EWlight.green = GPIO_NUM_25;

    gpio_set_level(NSlight.red, 1);
    gpio_set_level(EWlight.green, 1);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
    while (1) {

        if (EWgreen) {
            toRed(EWlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(NSlight);
            EWgreen = false;
        }
        else {
            toRed(NSlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(EWlight);
            EWgreen = true;
        }
        vTaskDelay(*timer / portTICK_PERIOD_MS);

    }

}

void
buttonCheck(void *parameters)
{

    int *timer = (int *) parameters;

    esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
    gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
    gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
    bool timeswitch = true;

    vTaskDelay(500 / portTICK_PERIOD_MS);

    while (1) {

        if (gpio_get_level(GPIO_NUM_0) == 0 && timeswitch) {
            *timer = 2000;
            gpio_set_level(GPIO_NUM_18, 1);
            timeswitch = false;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }

        if (gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch) {
            *timer = 10000;
            gpio_set_level(GPIO_NUM_18, 0);
            timeswitch = true;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }
        // vTaskDelay(10000/portTICK_PERIOD_MS);

    }

}

void
app_main()
{

    int timer = 10000;
    bool EWgreen = true;

    gpio_set_direction(18, GPIO_MODE_OUTPUT);
    gpio_set_direction(19, GPIO_MODE_OUTPUT);
    gpio_set_direction(5, GPIO_MODE_OUTPUT);

    gpio_set_direction(27, GPIO_MODE_OUTPUT);
    gpio_set_direction(26, GPIO_MODE_OUTPUT);
    gpio_set_direction(25, GPIO_MODE_OUTPUT);

    ledinfo NSlight;

    NSlight.red = GPIO_NUM_19;
    NSlight.yellow = GPIO_NUM_18;
    NSlight.green = GPIO_NUM_5;
    ledinfo EWlight;

    EWlight.red = GPIO_NUM_27;
    EWlight.yellow = GPIO_NUM_26;
    EWlight.green = GPIO_NUM_25;

    gpio_set_level(NSlight.red, 1);
    gpio_set_level(EWlight.green, 1);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
    xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);
// xTaskCreate(trafficLights,"TRAFFICLIGHTS",400,&timer,5,NULL);

    while (1) {

        if (EWgreen) {

            toRed(EWlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(NSlight);
            EWgreen = false;

        }
        else {

            toRed(NSlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(EWlight);
            EWgreen = true;

        }

        vTaskDelay(timer / portTICK_PERIOD_MS);

    }
}
c esp32 freertos
1个回答
0
投票

以热门评论为序...

这是我100%需要的东西吗? – 瑞安·佩雷斯

是的...

  1. 与 posix [linux] 线程(例如)
    pthread_create
    )不同,在
    freertos
    下,
    xTaskCreate
    不会 start 任务。
  2. 这必须通过从
    vTaskStartScheduler
    函数调用
    main
    来完成。
  3. 此调用之后的任何代码都将不会被执行。
  4. 任何此类“主任务”代码都必须放入其自己的任务中(例如下面的
    main_task

这是重构后的代码。我编辑了它,但它编译测试:

#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/gpio.h>

struct ledstuff {
    gpio_num_t red;
    gpio_num_t yellow;
    gpio_num_t green;
};

typedef struct ledstuff ledinfo;

void
toRed(ledinfo data)
{

    gpio_set_level(data.green, 0);
    gpio_set_level(data.yellow, 1);
    vTaskDelay(2000 / portTICK_PERIOD_MS);
    gpio_set_level(data.yellow, 0);
    gpio_set_level(data.red, 1);

}

void
toGreen(ledinfo data)
{

    gpio_set_level(data.red, 0);
    gpio_set_level(data.yellow, 0);
    gpio_set_level(data.green, 1);

}

void
trafficLights(void *params)
{

    int *timer = (int *) params;
    bool EWgreen = true;
    ledinfo NSlight;

    NSlight.red = GPIO_NUM_19;
    NSlight.yellow = GPIO_NUM_18;
    NSlight.green = GPIO_NUM_5;
    ledinfo EWlight;

    EWlight.red = GPIO_NUM_27;
    EWlight.yellow = GPIO_NUM_26;
    EWlight.green = GPIO_NUM_25;

    gpio_set_level(NSlight.red, 1);
    gpio_set_level(EWlight.green, 1);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
    while (1) {

        if (EWgreen) {
            toRed(EWlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(NSlight);
            EWgreen = false;
        }
        else {
            toRed(NSlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(EWlight);
            EWgreen = true;
        }
        vTaskDelay(*timer / portTICK_PERIOD_MS);

    }

}

void
buttonCheck(void *parameters)
{

    int *timer = (int *) parameters;

    esp_rom_gpio_pad_select_gpio(GPIO_NUM_0);
    gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT);
    gpio_set_pull_mode(GPIO_NUM_0, GPIO_PULLUP_ONLY);
    bool timeswitch = true;

    vTaskDelay(500 / portTICK_PERIOD_MS);

    while (1) {

        if (gpio_get_level(GPIO_NUM_0) == 0 && timeswitch) {
            *timer = 2000;
            gpio_set_level(GPIO_NUM_18, 1);
            timeswitch = false;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }

        if (gpio_get_level(GPIO_NUM_0) == 0 && !timeswitch) {
            *timer = 10000;
            gpio_set_level(GPIO_NUM_18, 0);
            timeswitch = true;
            // vTaskDelay(500/portTICK_PERIOD_MS);
        }
        // vTaskDelay(10000/portTICK_PERIOD_MS);

    }

}

#if 1
// NOTE/FIX: main code must be in its own task
void
main_task(void *vp)
{
    int *timer = vp;
    bool EWgreen = true;

    while (1) {
        if (EWgreen) {
            toRed(EWlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(NSlight);
            EWgreen = false;

        }
        else {
            toRed(NSlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(EWlight);
            EWgreen = true;
        }

        vTaskDelay(*timer / portTICK_PERIOD_MS);
    }
}

void
app_main()
{

// NOTE/BUG(?) -- timer on the main stack _may_ not survive after starting
// tasks
#if 0
    int timer = 10000;
#else
    static int timer = 10000;
#endif

#if 0
    bool EWgreen = true;
#endif

    gpio_set_direction(18, GPIO_MODE_OUTPUT);
    gpio_set_direction(19, GPIO_MODE_OUTPUT);
    gpio_set_direction(5, GPIO_MODE_OUTPUT);

    gpio_set_direction(27, GPIO_MODE_OUTPUT);
    gpio_set_direction(26, GPIO_MODE_OUTPUT);
    gpio_set_direction(25, GPIO_MODE_OUTPUT);

    ledinfo NSlight;

    NSlight.red = GPIO_NUM_19;
    NSlight.yellow = GPIO_NUM_18;
    NSlight.green = GPIO_NUM_5;
    ledinfo EWlight;

    EWlight.red = GPIO_NUM_27;
    EWlight.yellow = GPIO_NUM_26;
    EWlight.green = GPIO_NUM_25;

    gpio_set_level(NSlight.red, 1);
    gpio_set_level(EWlight.green, 1);
    vTaskDelay(3000 / portTICK_PERIOD_MS);
    xTaskCreate(buttonCheck, "BUTTONPRESSCHECK", 150, &timer, 14, NULL);
// xTaskCreate(trafficLights,"TRAFFICLIGHTS",400,&timer,5,NULL);

// NOTE/BUG: buttonCheck task will _not_ be started until vTaskStartScheduler
// is executed
#if 1
// NOTE/FIX: must create a main task (not sure about the timer parameter for
// this)
    xTaskCreate(main_task, "main_task", 150, &timer, 14, NULL);
    vTaskStartScheduler();
    while (1);
#endif

// NOTE/BUG: this code will never be executed -- it must go into its own task
// (see main_task)
#if 0
    while (1) {
        if (EWgreen) {
            toRed(EWlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(NSlight);
            EWgreen = false;

        }
        else {
            toRed(NSlight);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            toGreen(EWlight);
            EWgreen = true;
        }

        vTaskDelay(timer / portTICK_PERIOD_MS);
    }
#endif
}

在上面的代码中,我使用

cpp
条件来表示旧代码与新代码:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

注意:这可以通过运行文件来清理

unifdef -k

© www.soinside.com 2019 - 2024. All rights reserved.