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.