|
|
4 ay önce | |
|---|---|---|
| .. | ||
| src | 4 ay önce | |
| .gitignore | 4 ay önce | |
| README.md | 4 ay önce | |
| platformio.ini | 4 ay önce | |
This example demonstrates the use of the _TASK_THREAD_SAFE compile option for safe multi-threaded operation with TaskScheduler on FreeRTOS-based platforms (ESP32, ESP8266, STM32, etc.).
_task_enqueue_request() and _task_dequeue_request() functionsrequestAction() from interrupt contextAlso compatible with:
// Required global queue
QueueHandle_t tsQueue;
uint8_t tsQueueData[TS_QUEUE_LEN * sizeof(_task_request_t)];
StaticQueue_t tsQueueBuffer;
// Required enqueue function
bool _task_enqueue_request(_task_request_t* req) {
if (xPortInIsrContext()) {
// ISR context
BaseType_t xHigherPriorityTaskWokenByPost = pdFALSE;
BaseType_t rc = xQueueSendFromISR(tsQueue, req, &xHigherPriorityTaskWokenByPost);
if (xHigherPriorityTaskWokenByPost) portYIELD_FROM_ISR();
return (rc == pdTRUE);
}
else {
// Normal task context
return (xQueueSend(tsQueue, req, pdMS_TO_TICKS(TS_ENQUEUE_WAIT_MS)) == pdTRUE);
}
}
// Required dequeue function
bool _task_dequeue_request(_task_request_t* req) {
return (xQueueReceive(tsQueue, req, TS_DEQUEUE_WAIT_MS) == pdTRUE);
}
void IRAM_ATTR buttonISR() {
// Signal StatusRequest from ISR (thread-safe)
ts.requestAction(&buttonPressed, TASK_SR_REQUEST_SIGNALCOMPLETE, 0, 0, 0, 0, 0);
isrTriggers++;
}
void IRAM_ATTR timerISR() {
// Change task interval from ISR (thread-safe)
ts.requestAction(&tBlink, TASK_REQUEST_SETINTERVAL, newInterval, 0, 0, 0, 0);
}
void workerThread(void* parameter) {
while (true) {
vTaskDelay(pdMS_TO_TICKS(3000));
// Safely adjust blink interval from worker thread
uint32_t newInterval = 300 + (counter % 5) * 100;
ts.requestAction(&tBlink, TASK_REQUEST_SETINTERVAL, newInterval, 0, 0, 0, 0);
}
}
# Navigate to example directory
cd lib/TaskScheduler/examples/Scheduler_example30_THREAD_SAFE
# Build and upload
pio run -t upload
# Monitor serial output
pio device monitor
src/main.cpp as a .ino fileAdd to Arduino IDE preprocessor defines:
-D_TASK_THREAD_SAFE
-D_TASK_STATUS_REQUEST
-D_TASK_TIMEOUT
-D_TASK_ISR_SUPPORT
Compile and upload
===========================================
TaskScheduler Example 30: _TASK_THREAD_SAFE
===========================================
Task request queue created (size: 16)
Button interrupt attached (press boot button)
Hardware timer started (triggers every 7 seconds)
Worker thread created
--- System initialized ---
Expected behavior:
1. LED blinks at variable rate
2. Press button for fast blink burst
3. Timer ISR changes rate every 7s
4. Worker thread adjusts rate every 3s
5. All operations are thread-safe!
[5123] Blink #10 (ISR triggers: 2, Thread updates: 1)
Button pressed! Starting fast blink sequence...
=== Statistics at 10000 ms ===
Total blinks: 45
ISR triggers: 2
Thread updates: 3
Current blink interval: 400 ms
================================
Adjust these constants in main.cpp:
#define TS_QUEUE_LEN 16 // Request queue size (increase if overflow occurs)
#define TS_ENQUEUE_WAIT_MS 10 // Max wait for enqueue (ms)
#define TS_DEQUEUE_WAIT_MS 0 // No wait for dequeue
If you see "Failed to enqueue request" messages:
TS_QUEUE_LENTS_ENQUEUE_WAIT_MSIf the ESP32 reboots with watchdog errors:
ts.execute() runs frequently in loop()Ensure all compile flags are set in platformio.ini:
_TASK_THREAD_SAFE (required)_TASK_STATUS_REQUEST (for button example)_TASK_ISR_SUPPORT (for ESP ISR methods)requestAction() from ISRs and worker threadsIRAM_ATTR (ESP32/ESP8266)execute())Same as TaskScheduler library (see library LICENSE file)
Created for TaskScheduler v3.8.0+ Updated for TaskScheduler v4.0.0 (October 2024)