MCU Promise/Async Library is an asynchronous runtime library designed for microcontrollers, implementing a lightweight asynchronous programming model using C++20 coroutines, making microcontroller development more efficient and manageable.
- Promise/Future Pattern: Similar to JavaScript Promises, facilitating asynchronous operations
- Lightweight Task Model: Task scheduling system based on polling
- Serial Console: Built-in command-line interface with history and command completion
- C++20 Coroutine Support: Simplifies asynchronous code writing using modern C++ features (Not fully implemented, Memory Leaks)
- Built-in Utility Libraries:
Poll/Task: Polling tasksTimeout: Timed tasksPromise: Similar to JavaScript Promises, for use when coroutines are not supportedStream: Passes multiple asynchronous values when coroutines are not supportedTuple/Vec<T>/Str/StrView: Standard library wrappers for ease of useBuf<T>: Circular bufferUartBuf: Serial buffer handlingPrintf/Scanf: Formatted input/outputretarget: Redirects printf to UartBufConsole: Support for a simple consoleAsync: C++ coroutine async function support (TODO)
git clone https://github.com/yourusername/mcu_async.git
cd mcu_async
mkdir build && cd build
cmake ..
make#include <promise.h>
auto start_request() {
return Promise<int>([](auto resolve) {
set_timeout(1000, [=] {
resolve(42); // Resolve the Promise after 1 second
});
});
}
auto wait_request() {
return Promise<void>([](auto resolve) {
start_request().then([resolve](int result){
printf("Received result: %d\n", result);
resolve(char{});
});
});
}
void use_promise() {
wait_request().then([](auto) {
printf("all promise done %d\n");
});
}
void main() {
use_promise();
poll(); // Start the asynchronous polling environment
}void wathc_dog_task(Task *self) {
MX_IWDG_Init();
set_poll([]{
HAL_IWDG_Refresh(&hiwdg);
});
}
static Shared<UartBuf> _uart2_buf; // console uart
static uint8_t _uart2_rx_byte;
void uart2_start() {
_uart2_buf = uart_controller_start(128, [](const char *data, int n) {
HAL_UART_Transmit(&huart2, (uint8_t *)data, n, HAL_MAX_DELAY);
});
_uart2_buf->set_name("console_uart2");
HAL_UART_Receive_IT(&huart2, &_uart2_rx_byte, 1);
}
void main() {
uart2_start();
retarget_stdio(_uart2_buf.get());
console_start(_uart2_buf.get(), _cmd_table)->set_name("console");
// create a task
auto task = start_task("wathc_dog_task", wathc_dog_task);
set_interval(30000, [task]{
task.stop(); // stop task after 30 seconds.
});
poll(); // Start the asynchronous polling environment
}
// UART2 Rx Interrupt callback
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if(huart == &huart2) {
_uart2_buf->uart_intput(_uart2_rx_byte);
HAL_UART_Receive_IT(&huart2, &_uart2_rx_byte, 1);
}
}// Set up polling
set_poll([](Poll p) {
printf("Polling in progress\n");
if (/* some condition */) {
p.remove(); // Stop polling
}
});
// Set up a timer
set_timeout(1000, [] {
printf("Executed after 1 second\n");
});
// Set up an interval
set_interval(500, [](Timeout t) {
static int count = 0;
printf("Executing every 500ms: %d\n", count++);
if (count >= 10) {
t.stop(); // Stop the interval
}
});#include <console.h>
// Synchronous command
void cmd_hello(Env e) {
e.io().printf("Hello, World!\n");
e.exit(0);
}
// Command table
const CommandEntry user_cmd_list[] = {
{"hello", cmd_hello, "Print welcome message"},
{nullptr, nullptr, nullptr} // End marker
};
// Start the console
auto uart = uart_controller_start(1024, uart_write);
auto console = console_start(uart.get(), user_cmd_list);Promise<T>- Promise typepromise.then(callback)- Add success callbackpromise_all(p1, p2, ...)- Wait for multiple Promises
Task- Task objectstart_task(callback)- Start taskstart_task_async(callback)- Start asynchronous taskget_task(id)- Get taskget_current_task()- Get current task
set_poll(callback)- Set pollingset_once(callback)- Set one-time pollingset_timeout(ms, callback)- Set timeoutset_interval(ms, callback)- Set intervalset_once_async(callback)- Set asynchronous one-time polling
console_start(uart, cmd_list)- Start consoleCommandEntry- Command entryEnv- Command environment
Vec<T>- Dynamic arrayStr- StringStrView- String viewBuf<T>- Circular bufferUartBuf- Serial bufferPrintf- Formatted outputScanf- Formatted input
Async<T>- Coroutine return typeco_await- Wait for asynchronous operationco_return- Return asynchronous resultsleep_ms(ms)- Asynchronous wait in millisecondssleep_sec(sec)- Asynchronous wait in secondsloop_when(condition)- Loop while condition is true
This project is licensed under the MIT License - see the LICENSE file for details.
