首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SPI : ESP32任务阻止其他任务(即使是在不同的内核上!)

SPI : ESP32任务阻止其他任务(即使是在不同的内核上!)
EN

Stack Overflow用户
提问于 2021-05-13 20:42:01
回答 3查看 244关注 0票数 1

我正在开发基于ESP32的高频数据采集器,freeRTOS.There将是2个任务,第一个任务将在内核0上运行,使用SPI总线与传感器通信以收集4000SPS的数据。任务2将在核心1上运行,从第一个任务接收数据并通过TCP异步发送。理想情况下,任务2应该在任务1收集最新数据的同时发送数据(双核,对吧?)当我做测试运行时,我让SPI总线尽可能快地运行,但它只是阻止任务2运行!!我不想使用vTaskDelay(1),因为它会影响数据收集的速度。现在我应该怎么做,让两个任务同时运行?谢谢!!

代码语言:javascript
复制
   void inFromSensor(void *parameter)
{
    for (;;)
    {
        SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
      //  digitalWrite(SS, LOW);
        SPI.write(0b000011100);
        SPI.write(0b000011100);
        SPI.write(0b000011100);
        SPI.endTransaction();
        // vTaskDelay(1000/portTICK_PERIOD_MS);
        // for (int i = 0; i < 88; i++)
        // {
        //     testBuffer1[i] = 8;
        //     itoa(testBuffer1[i], &buffer1[i], 10);
        // }
        // buffer1[0] = '1';
        // buffer1[87] = '\n';

        // UBaseType_t res = xRingbufferSend(buf_handle, buffer1, sizeof(buffer1), pdMS_TO_TICKS(1000));
        // if (res != pdTRUE)
        // {
        //     printf("Failed to send item\n");
        // }
        
        TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
        TIMERG0.wdt_feed = 1;
        TIMERG0.wdt_wprotect = 0;
    }
    vTaskDelete(NULL);
}
void outToTCP(void *parameter)
{
    for (;;)
    {
        Serial.println("a");
        WiFiClient client = wifiServer.available();
        if (client)
        {
            Serial.println("client connected");
            while (client.connected())
            {
                unsigned long start = millis();
                while (millis() - start < 5000)
                {
                    size_t item_size;
                    char *item = (char *)xRingbufferReceive(buf_handle, &item_size, pdMS_TO_TICKS(1000));
                    if (item != NULL)
                    {
                        client.write(item);
                        //Return Item
                        vRingbufferReturnItem(buf_handle, (void *)item);
                    }
                    else
                    {
                        //Failed to receive item
                        printf("Failed to receive item\n");
                    }
                }
                Serial.println("done");
                return;
            }

            client.stop();
            Serial.println("Client disconnected");
        }
        
        TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
        TIMERG0.wdt_feed = 1;
        TIMERG0.wdt_wprotect = 0;
    }
    vTaskDelete(NULL);
}
void setup()
{
    Serial.begin(112500);
    WiFi.begin(ssid, password);
    SPI.begin(SCK, MISO, MOSI, SS);
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("Connecting to WiFi..");
    }
    wifiServer.begin();

    buf_handle = xRingbufferCreate(50280, RINGBUF_TYPE_NOSPLIT);
    if (buf_handle == NULL)
    {
        printf("Failed to create ring buffer\n");
    }
    Serial.println("ready");
    xTaskCreatePinnedToCore(
        inFromSensor,      /* Task function. */
        "lowPriorityTask", /* name of task. */
        15000,             /* Stack size of task */
        NULL,              /* parameter of the task */
        4,                 /* priority of the task */
        NULL,              /* Task handle to keep track of created task */
        1);
    delay(500);



xTaskCreatePinnedToCore(
    outToTCP,           /* Task function. */
    "highPriorityTask", /* name of task. */
    15000,              /* Stack size of task */
    NULL,               /* parameter of the task */
    6,                  /* priority of the task */
    NULL,               /* Task handle to keep track of created task */
    0);
delay(500);

Serial.println("ready");}
EN

回答 3

Stack Overflow用户

发布于 2021-05-13 21:28:48

请发布串行输出。

无论如何,我的猜测是Task1正在独占运行WiFi堆栈的核心,因此WiFi永远没有机会连接。然而,任务2依赖于要连接的WiFi。此外,任务2正在等待数据在环形缓冲区中可用,但您的代码没有在那里发布任何内容。

无论如何,这是从计时器中受益的东西。如果您需要以特定的间隔运行采样进程,请使用该间隔配置一个计时器,在中断中执行采样并将其发送到您的处理线程。这比在循环中旋转,占据整个核心要确定得多。另外,它将空闲的周期留给那些需要它们的任务(除了您的代码之外,还有相当多的任务)。

票数 1
EN

Stack Overflow用户

发布于 2021-05-14 01:46:26

解决了!我刚刚改变了任务( xTaskCreatedPinnedToCore())的创建顺序,先创建任务2,然后创建任务1。看起来像第一种情况,任务1在创建后继续运行,因此任务2从未有机会创建!

票数 1
EN

Stack Overflow用户

发布于 2022-01-01 04:01:39

代码语言:javascript
复制
void inFromSensor(void *parameter)
{
     VTaskDelay(NULL) // this will prevent task from running right after it is initialised, NULL parameter known that it is asking itself to delay.
    for (;;)
    {
    }
}

void setup()
{
xTaskCreatePinnedToCore(inFromSensor,"lowPriorityTask", 15000, NULL,4,Task1,1);// give task handle such as Task1 and you will have to declare this on top.

delay(500);
// You can then here control the order of resuming the task
vTaskResume(Task1);// this will start the task and you should do this ideally

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67519441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档