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.
