注意:
(1)任务中使用的变量应为静态变量
(2)线程内不能使用纯 while(1)--即含 PT_WAIT_UNTIL()等宏的 while(1)是可以的。
不能在 switch(){case…}中调用任务 Protothreads API 带有 case 的语句(即只能单向嵌套)。
(3)线程内可以使用:
for(){…}
switch(){case…}-- case 与 case 之间必须是一个完整的语句或者语句段
if(){…}else{…}
含宏的 while(1){…}
(4)ProtothreadS 系统可以仍然还是个大 while(1)循环。但也可设计为根据定时器产生的恒定间隔的中断来触发和管理任务
--时间触发方式的嵌入式系统,此时可更改 pt 结构体为(见《时间触发模式下的 ProtothreadS 设计应用》):
struct pt{
lc_t lc;
unsigned short count; // 每次中断都减 1
unsigned short load; // 初始计数值
char ready; // 任务就绪标志
}
(5)在 ProtothreadS 系统中延时:
1)如果 ProtothreadS 系统是基于时间触发,则延时可基于该触发--即基于系统时钟。
2)如果 ProtothreadS 系统中无系统时钟,
(6)Protothreads 虽然提供了在各自线程内的条件阻塞机制,但对于在该线程内调用的其它函数,则无法阻塞其运行。所以,
如果要在线程内调用占用时间较多的函数,为保证各个线程的实时性要求,需要将这类函数进一步划分为更小的函数,分步执
行。
(7)Protothread 的精华:当 Protothread 程序运行到 PT_WAIT_UNTIL 时,判断其运行条件是否满足,若不满足,则阻塞。
Protothread 的阻塞其实质就是函数返回。
Protothread 仅能在程序员指定位置阻塞。
(8)能满足系统实时性要求的条件是:(当且仅当)TaskA 、TaskB、TaskC 三个任务的运行时间之和要小于系统实时响应的
时间要求。
(9)由于事件驱动模型没有阻塞机制,因此需要由程序员构造一个有限状态机来实现顺序流控制。
ProtothreadS 函数说明 1:
函数 说明
PT_INIT(pt) 初始化任务变量,只在初始化函数中执行一次就行
PT_BEGIN(pt) 启动任务处理,放在函数开始处
PT_END(pt) 结束任务,放在函数的最后
PT_WAIT_UNTIL(pt, condition)
等待某个条件(条件可以为时钟或其它变量,IO 等)成立,否则直接退
出本函数,下一次进入本函数就直接跳到这个地方判断
PT_WAIT_WHILE(pt, cond) 和上面一个一样,只是条件取反了
PT_WAIT_THREAD(pt, thread) 等待一个子任务执行完成
PT_SPAWN(pt, child, thread)
新建一个子任务,并等待其执行完退出
PT_RESTART(pt)
重新启动某个任务执行
PT_EXIT(pt) 任务后面的部分不执行,直接退出重新执行
PT_YIELD(pt) 锁死任务
PT_YIELD_UNTIL(pt, cond) 锁死任务并在等待条件成立,恢复执行
ProtothreadS 函数说明 2:
函数 说明
struct pt {
lc_t lc;};
#define PT_INIT(pt) LC_INIT((pt)->lc)
Initialize a protothread
初始化 Protothread 线程,实际上是将线程控制结构
体里的 lc 置 0
#define PT_THREAD(name_args) char name_args
Declaration of a protothread
声明线程
例如:PT_THREAD(task1(struct pt *pt))
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1;
LC_RESUME((pt)->lc)
Declare the start of a protothread
启动任务处理
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ Declare the end of a protothread
评论0
最新资源