
我正在开发基于ESP32的高频数据采集器,freeRTOS.There将是2个任务,第一个任务将在内核0上运行,使用SPI总线与传感器通信以收集4000SPS的数据。任务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");}发布于 2021-05-13 21:28:48
请发布串行输出。
无论如何,我的猜测是Task1正在独占运行WiFi堆栈的核心,因此WiFi永远没有机会连接。然而,任务2依赖于要连接的WiFi。此外,任务2正在等待数据在环形缓冲区中可用,但您的代码没有在那里发布任何内容。
无论如何,这是从计时器中受益的东西。如果您需要以特定的间隔运行采样进程,请使用该间隔配置一个计时器,在中断中执行采样并将其发送到您的处理线程。这比在循环中旋转,占据整个核心要确定得多。另外,它将空闲的周期留给那些需要它们的任务(除了您的代码之外,还有相当多的任务)。
发布于 2021-05-14 01:46:26
解决了!我刚刚改变了任务( xTaskCreatedPinnedToCore())的创建顺序,先创建任务2,然后创建任务1。看起来像第一种情况,任务1在创建后继续运行,因此任务2从未有机会创建!
发布于 2022-01-01 04:01:39
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
}https://stackoverflow.com/questions/67519441
复制相似问题