Použití sériové komunikace v interruptu
Napsal: 18 bře 2020, 19:40
Trochu jsem experimentoval se sériovou komunikací v interruptu (jen tou HW, ne software serial). Obecně se to nedoporučuje, ale už není nějak popsané, zda to jde a za jakých podmínek.
Výsledek mohu shrnout následovně: Jde to, ale musí se dodržet určité podmínky.
V interruptové funkci jsou zakázány interrupty a tím je i znemožněno přijímání a vyslání znaků fyzickou linkou. Ale objektové funkce sériového portu pracují s bufferem. Samotné odeslání nebo přijímáni se provádí až po opuštění interruptové funkce. To musíme mít na paměti, pokud něco posíláme v přerušení, protože se to hned nevyšle, ale jenom zařadí nebo vyjme z fronty. Při vysílání si musíme důsledně pohlídat, zda je ve frontě místo pro znaky, co chceme vyslat (Serial.availableForWrite()). Jinak dojde k zaplnění vysílacího bufferu a bude se čekat na uvolnění, které ale díky zakázaným interruptům nenastane a program vytuhne. U čtení musíme zase kontrolovat, než budeme něco číst, zda je v bufferu nějaký znak (Serial.available()), jinak zase dojde k vytuhnutí, protože se nemůže nic přijmout.
Z toho důvodu tedy rozhodně nepoužívat jiné funkce než read(),write(),peek(). S funkcemi print() a println() opatrně, protože většinou generují více znaků a musíme mít jistotu, že se vejdou do bufferu. A nakonec, pokud v přerušení něco čteme do globálně deklarované proměnné, tak musí být typu volatile.
Výsledek mohu shrnout následovně: Jde to, ale musí se dodržet určité podmínky.
V interruptové funkci jsou zakázány interrupty a tím je i znemožněno přijímání a vyslání znaků fyzickou linkou. Ale objektové funkce sériového portu pracují s bufferem. Samotné odeslání nebo přijímáni se provádí až po opuštění interruptové funkce. To musíme mít na paměti, pokud něco posíláme v přerušení, protože se to hned nevyšle, ale jenom zařadí nebo vyjme z fronty. Při vysílání si musíme důsledně pohlídat, zda je ve frontě místo pro znaky, co chceme vyslat (Serial.availableForWrite()). Jinak dojde k zaplnění vysílacího bufferu a bude se čekat na uvolnění, které ale díky zakázaným interruptům nenastane a program vytuhne. U čtení musíme zase kontrolovat, než budeme něco číst, zda je v bufferu nějaký znak (Serial.available()), jinak zase dojde k vytuhnutí, protože se nemůže nic přijmout.
Z toho důvodu tedy rozhodně nepoužívat jiné funkce než read(),write(),peek(). S funkcemi print() a println() opatrně, protože většinou generují více znaků a musíme mít jistotu, že se vejdou do bufferu. A nakonec, pokud v přerušení něco čteme do globálně deklarované proměnné, tak musí být typu volatile.