ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
10 июля
313189 Топик полностью
zeleny (07.03.2012 22:54, просмотров: 369) ответил MegaJohn на очередной велосипед - невытесняющая РТОС без единой асмовской вставки. Получился экий симбиоз из protothreads[+]
Отличная штука, давно пользую для AVR, PIC, STM32. Вот несколько полезных макросов и простейший диспетчер (старт/стоп + по одному миллисекундному таймеру на задачу). Еще есть программный 1-wire и I2C, оптимизорованные под Protothreads (могут обслуживать параллельно несколько шин). #ifndef UL_PTX_H_ #define UL_PTX_H_ #include "ul_other.h" #include "pt.h" /** Execute statement cmd and wait until condition becames true */ #define PTX_EXEC_WAIT_UNTIL(cmd, cond) { cmd; }; PT_WAIT_UNTIL(pt, cond) /** delay, ms using millisecond timer */ #define PTX_DELAY(tmr, time) PTX_EXEC_WAIT_UNTIL((tmr) += (time), (tmr) == 0); /** delay using thread millisecond timer */ #define PTX_DELAY_MS(time) PTX_DELAY(ptx->tmr, time) /** decrement timer if flag is set */ #define PTX_TIMER_DEC(flag, tmr) if ((flag) && (tmr)) (tmr)-- /** decrement millisecond timer */ #define PTX_TIMER_MS_DEC(tmr) PTX_TIMER_DEC(t_1000, tmr) /** thread structure */ struct ptx { struct pt pt; /**< protothread data */ char (*pf)(struct pt *pt, struct ptx *ptx); /**< thread function pointer */ U16 tmr; /**< thread timer */ U8 run; /**< thread run/stop flag */ void *data; /**< pointer to thread data */ }; /** threads queue */ extern struct ptx ptx_queue[PTX_MAX]; /** add new thread to queue */ struct ptx *ptx_add( char (*pf)(struct pt *pt, struct ptx *ptx), void *data, U8 run ); /** run started threads */ void ptx_dispatch( void ); #endif /* UL_PTX_H_ */ #include <stddef.h> #include "ul_ptx.h" #include "ul_timing.h" struct ptx ptx_queue[PTX_MAX]; U8 ptx_cnt; struct ptx *ptx_add( char (*pf)(struct pt *pt, struct ptx *ptx), void *data, U8 run ) { if (ptx_cnt < (PTX_MAX)) { struct ptx *ptx = &ptx_queue[ptx_cnt]; ptx->pf = pf; ptx->data = data; PT_INIT( &ptx->pt ); ptx->tmr = 0; ptx->run = run; ptx_cnt++; return ptx; } return NULL; } void ptx_dispatch( void ) { if (ptx_cnt > 0) { struct ptx *ptx = &ptx_queue[0]; for (U8 cnt=0; cnt<ptx_cnt; cnt++, ptx++) if (ptx->run) { //decrement millisecond timer PTX_TIMER_MS_DEC(ptx->tmr); //call thread function (ptx_queue[cnt].pf)(&ptx->pt, ptx); } } }