完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
|
|
相关推荐
1个回答
|
|
|
TreeOS学习总结
TreeOS在自我介绍时说自己提出的一种面向场景编程的构件化方法,解决了标准化系统软件架构的问题。TreeOS是一种无核的、软件构件化的、实时嵌入式操作系统。 笔者觉得的这是一种前后台系统(文章后面会解释什么是前后台),它对于编程各个任务让我错乱的我提供了特别大的帮助,目前网上相关的代码很少,我通过官网找到了它的两百页的使用指南,大受裨益。如果你也是苦恼于单片机各个任务的管理,或者在准备电赛的程序,这里强烈推荐大家阅读它前80页内容。[TREEOS操作指南] 就像和《疯狂动物城》里的闪电对话一样 定时器中断中的显示—按键结合函数可以在公共while中调用,以节约中断资源 场景子场景的子场景编写规范。 为提高编程效果,当A为主场景时。与B同级的场景,如B1、B2等建议分成不同的.C和.H文件,但对于场景B而言,C和D可看作相同.C文件中的不同任务,通过不同函数来实现,再通过switch来选择调用。 这种多级树形结构可将任务持续细化,但也规定了必须有且只有一个主场景。但是如果持续细化任务嵌套导致过于占用堆栈。 常用的单片机裸机程序框架 如果不上操作系统的话(如freetos 、rt-thread ),裸机框架其实可以完成各种任务,并且系统非常考验处理器的性能,也会占用过多的资源。所以我打算还是主要学习逻辑框架。以下学习来自野火的《RT-Thread内核实现与应用开发实践指南》 1.轮询系统 最常用也是最简单的一种方法,没有外部事件时常用。 int main(void) { init_something(); while(1) { do_something1(); do_something2(); do_something3(); } } 2.前后台系统 前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台,main 函数里面的无限循环我们称为后台。 特点:事件的响应和处理分开,事件的处理还是在后台里面顺序执行的,但相比轮询系统,前后台系统 确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力 int flag1 = 0; int flag2 = 0; int flag3 = 0; int main(void) { /* 硬件相关初始化 */ HardWareInit(); /* 无限循环 */ for (;;) { if (flag1) { /* 处理事情 1 */ DoSomething1(); } if (flag2) { /* 处理事情 2 */ DoSomethingg2(); } if (flag3) { /* 处理事情 3 */ DoSomethingg3(); } } } void ISR1(void) { /* 置位标志位 */ flag1 = 1; /* 如果事件处理时间很短,则在中断里面处理 如果事件处理时间比较长,在回到后台处理 */ DoSomething1(); } void ISR2(void) { /* 置位标志位 */ flag2 = 2; /* 如果事件处理时间很短,则在中断里面处理 如果事件处理时间比较长,在回到后台处理 */ DoSomething2(); } void ISR3(void) { /* 置位标志位 */ flag3 = 1; /* 如果事件处理时间很短,则在中断里面处理 如果事件处理时间比较长,在回到后台处理 */ DoSomething3(); } 3.多线程系统 相比前后台系统,多线程系统的事件响应也是在中断中完成的,但是事件的处理是在线程中完成的。在多线程系统中,线程跟中断一样,也具有优先级,优先级高的线程会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的线程的优先级足够高,就会立马得到响应。相比前后台系统,多线程系统的实时性又被提高了。 线程:在多线程系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为线程。每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。 int flag1 = 0; int flag2 = 0; int flag3 = 0; int main(void) { /* 硬件相关初始化 */ HardWareInit(); /* OS 初始化 */ RTOSInit(); /* OS 启动,开始多线程调度,不再返回 */ RTOSStart(); } void ISR1(void) { /* 置位标志位 */ flag1 = 1; } void ISR2(void) { /* 置位标志位 */ flag2 = 2; } void ISR3(void) { /* 置位标志位 */ flag3 = 1; } void DoSomething1(void) { /* 无限循环,不能返回 */ for (;;) { /* 线程实体 */ if (flag1) { } } } void DoSomething2(void) { /* 无限循环,不能返回 */ for (;;) { /* 线程实体 */ if (flag2) { } } } void DoSomething3(void) { /* 无限循环,不能返回 */ for (;;) { /* 线程实体 */ if (flag3) { } } } 系统重要概念 临界段 临界段用一句话概括就是一段在执行的时候不能被中断的代码段。在系统里面,这个临界段最常出现的就是对全局变量的操作,全局变量就好像是一个枪把子,谁都可以对他开枪,但是我开枪的时候,你就不能开枪,否则就不知道是谁命中了靶子。 那么什么情况下临界段会被打断?一个是系统调度,还有一个就是外部中断。在进入临界段之前,我们会先把中断关闭,退出临界段时再把中断打开。 在STM32中,简单粗暴的方法就是直接: //进入临界段 INTX_DISABLE(); ..................... //退出临界段 INTX_ENABLE(); 共享资源 这里通俗来讲就是不同场景之间的全局变量,多个任务共同使用的资源叫做共享资源(如数据、文件、输入输出设备等)。为了防止数据被破坏或设备异常,每个任务使用共享资 源时,必须独占该资源,不能被打断。最常用的做法是先关中断,运行临界区代码,然后重新开中断。 阻塞与非阻塞赋值 这段概念来源于学习FPGA,若大家想深入了解可以参考正点原子的FPGA教程。 阻塞: 非阻塞 拆分与拆分技术 学习来自treeos: 对于运行时间长、实时性要求不高的普通任务,可以拆分成两部分或两部分以上的任务,而每部分运行时间都较短。每次循环只运行其中的一部分,多次运行才能获得结果。这实际上是一种多道系统的处理方法,也称为分时调度。 例如,对键盘可以通过多次循环扫描的方法,监控按键释放动作出现后再进行处理。这样可以避免占用处理 器长时间延时等待的问题。拆分技术可以减少循环总时间。 拆分技术会经常用到。 而对于实时性要求较高的普通任务,可以在任务顺序队列中插入两次或两次以上的运行机会,使任务的实时性要求获得满足。插入技术使循环总时间增加。例如,在一个场景中,任务顺序队列完成一次循环最大时间需要 50ms,而某个任务则需要 30ms 内执行一次,那么 就可以采用这种插入技术,使该任务的实时性要求获得满足。 底半处理(优先任务=中断标志+while触发任务) 尽管嵌入式系统对中断程序处理时间一般不做限制,但是普遍的做法是尽量缩短中断处理时间,以免影响其它中断服务或紧急任务。 一种有效的做法是把中断处理任务过程分为两部分,上半部分(top half)处理紧急事务,例如设置标志或者接收输入数据单元,这部分运行时间很短,放在中断服务程序中进行。然后把一些需耗时处 理或对时间要求不太紧急的事务放在之后运行(例如放在后台程序 中),这部分程序称为底半部分(bottom half)。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
1599 浏览 0 评论
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
4738 浏览 0 评论
4229 浏览 9 评论
3822 浏览 16 评论
4398 浏览 1 评论
4211浏览 3评论
2380浏览 0评论
3394浏览 0评论
1158浏览 0评论
2843浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 07:27 , Processed in 0.893561 second(s), Total 74, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1738