1

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

   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");}
4

3 回答 3

1

解决了!我只是切换了任务的创建顺序(xTaskCreatedPinnedToCore()),先创建任务2,然后创建任务1。看起来第一种情况,任务1,创建后继续运行,因此任务2从来没有机会成为创建!

于 2021-05-13T17:46:26.440 回答
1

请发布串行输出。

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

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

于 2021-05-13T13:28:48.203 回答
0
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

}
于 2022-01-01T04:01:39.433 回答