Пример работы с protothreads на GCC-AVR
Вдохновившись описанием Protothreads у BSVi, набросал небольшой пример их использования в виде программы, мигающей двумя светодиодами с разной частотой. Для пущей важности был использован system tick timer и супер-макросы для работы с GPIO.
Интересно, правильно ли я понял идею протопотоков? :)
Архив с исходниками можно скачать.
#include "libs/common.h"
#define LED1 B, 5, H
#define LED2 B, 4, H
// IO Init
static inline void init_io(void)
{
// Turn UART off after bootloader
UCSRB = 0;
DRIVER(LED1, OUT);
DRIVER(LED2, OUT);
#if DEBUG_BUILD
// UART
uart_init(UART_BAUD_RATE);
stdout = &uart_str;
puts_P(PSTR("MCU started..."));
#endif
}
static struct pt blink1_pt, blink2_pt;
static PT_THREAD(blink1(struct pt *pt))
{
static uint32_t last_timer;
PT_BEGIN(pt);
last_timer = st_millis();
ON(LED1);
#if DEBUG_BUILD
puts_P(PSTR("Blinking protothread #1 started..."));
#endif
while(1)
{
PT_WAIT_UNTIL(pt, (st_millis() - last_timer) >= 500);
last_timer = st_millis();
TOGGLE(LED1);
#if DEBUG_BUILD
printf_P(PSTR("Blink #1 at %" PRIu32 "\n"), last_timer);
#endif
}
PT_END(pt);
}
static PT_THREAD(blink2(struct pt *pt))
{
static uint32_t last_timer;
PT_BEGIN(pt);
last_timer = st_millis();
ON(LED2);
#if DEBUG_BUILD
puts_P(PSTR("Blinking protothread #2 started..."));
#endif
while(1)
{
PT_WAIT_UNTIL(pt, (st_millis() - last_timer) >= 1000);
last_timer = st_millis();
TOGGLE(LED2);
#if DEBUG_BUILD
printf_P(PSTR("Blink #2 at %" PRIu32 "\n"), last_timer);
#endif
}
PT_END(pt);
}
int main(void)
{
init_io();
st_init();
sei();
PT_INIT(&blink1_pt);
PT_INIT(&blink2_pt);
while(1)
{
blink1(&blink1_pt);
blink2(&blink2_pt);
}
}
