Немного информации - по ссылкам. http://bsvi.ru/tag/protopotoki/
http://we.easyelectronics.ru/search/topics/?q=protothreads
И несколько полезных макросов + простейший диспетчер задач для PT:
/** Execute statement cmd and wait until condition becames true */
#define PT_EXEC_WAIT_UNTIL(cmd, cond) { cmd; }; PT_WAIT_UNTIL(pt, cond)
/** delay, ms using millisecond timer */
#define PT_DELAY(tmr, time) PT_EXEC_WAIT_UNTIL((tmr) += (time), (tmr) == 0);
/** delay using thread millisecond timer */
#define PT_DELAY_MS(time) PT_DELAY(ptx->tmr, time)
/** decrement timer if flag is set */
#define PT_TIMER_DEC(flag, tmr) if ((flag) && (tmr)) (tmr)--
/** decrement millisecond timer */
#define PT_TIMER_MS_DEC(tmr) PT_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 );
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
PT_TIMER_MS_DEC(ptx->tmr);
//call thread function
(ptx_queue[cnt].pf)(&ptx->pt, ptx);
}
}
}
http://we.easyelectronics.ru/search/topics/?q=protothreads
И несколько полезных макросов + простейший диспетчер задач для PT: