Ještě mi bude chvilku trvat, než doplním chybějící věci, ale přepínání kontextu už šlape, to je ostatně to nejhorší (protože asm). Korutina:
struct fibre_info {
void* stack;
void* stackpos;
void* retaddr;
};
Spuštění korutiny:
__attribute__((naked)) void detach_fibre_asm(struct fibre_info*, void(*)(void*), void* stack, void* arg) {
asm(
"push {r4,r5,r6,r7}\n\t"
"mov r4, r8\n\t"
"mov r5, r9\n\t"
"mov r6, r10\n\t"
"mov r7, r11\n\t"
"push {r4,r5,r6,r7}\n\t"
"mov r4, sp\n\t"
"str r4, [r0, #4]\n\t"
"mov r4, lr\n\t"
"str r4, [r0, #8]\n\t"
"mov sp, r2\n\t"
"mov r0, r3\n\t"
"bx r1"
);
}
Celkem primitivní, prostě se uloží kontext a přepne stav. Aby to jelo na Cortex-M0 (Pico), musí se šaškovat s registry od r8 nahoru, ale to jsou detaily. Scheduler už naštěstí bude v céčku. Použití:
void fibre(pico_channel_t ch) {
pico_sleep_ms(1000);
pico_send(ch, pico_create_string("Bonjour, monde!"));
}
void main() {
auto ch = pico_create_channel();
pico_detach(&fibre, ch);
auto str = pico_receive(ch);
// do something with str
}
Funkce sleep, send a receive přepínají korutiny, tj. neblokují, ale prostě vrátí řízení scheduleru.