Protothreads简介

介绍了一种轻量级多任务编程方法,该方法仅占用少量RAM资源,并提供了多个宏定义来控制任务的状态,适用于资源受限的单片机。
rel="File-List" href="file:///D:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> rel="Edit-Time-Data" href="file:///D:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso"> rel="themeData" href="file:///D:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> rel="colorSchemeMapping" href="file:///D:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">

    原来在用RTOS时感觉特别方便的就是任务函数中可以调用系统提供的延时,等待等函数,切换到 其它任务上执行,这样写程序又简单而且又能充分利用硬件资源,但这样做在切换任务时浪费了很多的系统时间及占用很多RAM,而且对于8位或16位小内存的 单片机也不太适合。最近几天在看开源网络协议UIP1.0,居然在DHCP应用实例中看到了一种以很简单的方法实现类似多任务功能的编程方法,只需占用只 个字节的RAM资源,而且非常的容易使用。
   
要实现这种这种编程方法,只需下载到UIP1.0的源代码,找到其中的三个文件分别是pt.h,lc.h,lc-switch.h,在自己项目中把pt.h包含进去就行。
   在DHCP中有完整的应用函数static PT_THREAD(handle_dhcp(void)),这个函数年看起来有点怪,但其实将其宏展开就是static char handle_dhcp(void),返回char类型静态函数,其实就是向外部返回任务执行状态。pt.h中提供很多功能的宏定义:

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) 
锁死任务并在等待条件成立,恢复执行

pt中一共定义四种线程状态,在任务函数退出到上一级函数时返回其状态
PT_WAITING  
等待
PT_EXITED  
退出
PT_ENDED  
结束
PT_YIELDED  
锁死


我会继续关注Protothreads并在项目中使用它.


ProtoThreads 是一个轻量级的 C 语言协程库,专为资源受限的嵌入式系统设计。它允许开发者在没有操作系统支持的情况下实现异步编程,从而避免阻塞式操作对性能的影响。通过使用 ProtoThreads,可以有效地管理多个并发任务,而无需依赖复杂的线程调度机制。 在实际应用中,ProtoThreads 被广泛用于处理需要与外部设备(如芯片)通信的任务。例如,在执行某些操作时,程序需要等待设备完成特定任务后才能继续,这种情况下通常会看到类似 `WAIT_AND_CHECK_STATUS(return_status, optiga_lib_status);` 的代码片段。这类操作可能非常耗时,但在有或没有操作系统的环境中都能通过 ProtoThreads 实现非阻塞的异步功能[^1]。 为了使用 ProtoThreads,开发者需要将 `include/pt.h` 头文件包含到自己的项目中,并根据具体需求编写相应的代码。值得注意的是,ProtoThreads-CPP 项目并没有提供明确的“启动文件”,这意味着用户需要自行创建这些文件以开始使用该库[^2]。 下面是一个简单的 ProtoThreads 使用示例,展示了如何定义一个协程以及如何在其内部进行状态检查和延时操作: ```c #include "pt.h" // 定义协程所需的结构体 struct pt my_thread; // 协程函数 static int my_thread_func(struct pt *pt) { PT_BEGIN(pt); // 模拟等待某个条件满足的过程 while (!some_condition()) { PT_WAIT_UNTIL(pt, some_condition()); } // 执行一些操作 do_something(); // 模拟延时操作 PT_SLEEP(pt, 1000); // 延迟1000个时钟周期 // 再次执行一些操作 do_another_thing(); PT_END(pt); } int main(void) { PT_INIT(&my_thread); while (1) { my_thread_func(&my_thread); } return 0; } ``` 在这个例子中,`PT_BEGIN` 和 `PT_END` 宏用于标记协程的开始和结束。`PT_WAIT_UNTIL` 宏使协程暂停执行,直到指定条件成立。此外,`PT_SLEEP` 宏可以让协程暂停一段指定的时间。这些宏共同作用,使得协程能够在不阻塞整个程序的前提下处理各种任务[^3]。 对于希望深入了解 ProtoThreads 或者寻找更多高级特性的开发者来说,可以参考由 Craig Graham 扩展的 `graham-pt.h` 文件,其中增加了对 sleep/wake/kill 等操作的支持,进一步增强了 ProtoThreads 的灵活性和实用性。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值