★★ 自己写的基于8051操作系统SCH51(优先级,可抢占) ★★
时间:10-02
整理:3721RD
点击:
代码的最新版本 SCH51 V1.41 已经发布。代码链接:http://www.openedv.com/posts/list/22990.htm
建议大家阅读代码的顺序为:config.h SCH51.h SCH51.C main.c T0_init.h T0_init.c TASK.h task.c 。
大家如果对代码中的某些算法有更高意识的意见或建议时,可以给我留言。你的建议可能 be part of the new version !
在聊这个操作系统之前,我们先来聊点题外话。后面,我会贴出所有代码,并且附上完整的工程文件给大家。
请注意,以下讨论的内容,都是以51单片机为硬件平台的,但是,本文所述的重点内容并不拘泥于某一种特定的处理器,大家可以回去把代码移植到STM32、S3C2440、以及一些DSP上去,因为本代码并未涉及任何堆栈处理。
这里我想表达的不是程序的算法,而是一种本人称之为“面向任务”的项目开发思想(如果你学过C++、JAVA并且理解什么是“面向对象”那就最好了,你应该明白我说的“面向任务”是个什么意思)。之所以以51为平台,是因为大家对51很熟悉,讲起来更容易理解。我曾经看过一些人学uC/OS-II,本来对STM32就不熟悉,又去在STM32上跑一个更不熟悉的 uC/OS-II ,甚至还有人在这种情况下又加上个 uC/GUI。我就只能说呵呵了。
为什么要写这个操作系统(准确的说应该是“调度系统”)?
本人现在还是学生,之前做过一些单片机、DSP以及ARM的项目,但是无一例外地,在做项目中都会遇到一个头疼的问题(这个阶段我总称它为“瓶颈期”或“难产期”),就是多任务并行问题的处理。我们不可能每次遇到多任务并行处理就把uC/OS-II拿过来,的确 uC/OS-II 是一个很好的RTOS,曾经很长一段时间我都迷恋她 ,但是我总觉得只有在非常必要的时候才应该把 uC/OS-II 搬上来,因为 uC/OS-II 真的会使我们的项目开发起来很简单,很有条理,但是每次遇到多任务就用 uC/OS-II 我就觉得有点小题大做了。况且,8位机仍然占据着微控领域的半壁江山,所以,把 uC/OS-II 搬到51中去开发项目,有点像把大象往冰箱里塞,整个系统也会非常迟钝。
我们知道,单片机程序最常见的就是超级循环模式,即while(1)大循环,这种结构一个很大的缺陷就是当我们的MCU需要同时处理多个任务的时候,作为开发者,你的优秀的程序构架就显得相当重要。比如某个项目中要求LED数码管每20ms(50Hz)扫描一次,另一个任务每100ms(10Hz)执行一次,还有一个任务每2s执行一次(比如AD转换监测),…… , 等等。对于这样的要求,其实我们可以通过这个方法来解决:定义很多个全局变量来计时,比如:Timr_A、 Timr_B、 Timr_C,……,等等,单片机上电后第一件事就是启动定时器,在定时中断中挨个使Timr_A、 Timr_B、 Timr_C,…… ,自增,各个任务根据自己的执行周期来判断各自对应的变量(Timr_A、 Timr_B、 Timr_C,…… )有没有达到指定数值,以决定是否执行任务函数。这个原理有点像STM32中的PWM生成。但是这种方法只是一种治标不治本的法子。如果任务非常多,定时器麻烦就大了,因为单片机的中断程序应该尽可能快的结束。而且,如果任务A和任务B定时同时定时到,该执行哪个?如果执行A,那么B就得舍弃,注意,是舍弃,不是等一会再执行B。还有,如果某个任务执行时间出现抖动,整个系统和其它任务都要遭殃了。任务之间的干涉会非常严重。等等。
“面向任务”的思想的一个很重要的原则就是任务之间是低耦合的,原则上是“完全并行”的(不考虑系统全局变量的话)。
在本代码中,力求将多任务并行的情况予以抽象,就其共性提出解决方案,并以代码的最终调试成功作为实现。在此,我不打算带着大家一行一行分析代码。这玩意讲解没用,自己去悟懂了才是王道,我的代码注释得已经很详细了其实。当然,我一贯认为程序是没有百分之百正确的,所以你要是发现这些代码中有值得改进的地方,请你速度指出来,我们一起实现!联系方式见下面。
如果有问题可以加我QQ(986796621),非常喜欢和大家一起讨论问题,使这段代码实用起来,以解决实际问题。
代码的重点是 SCH51.C 和 T0_INIT.C 两个文件,使用之前请务必先看看 CONFIG.H 的配置情况。task.c文件内容你可以自定义来实现。其它的我都有注释的。
海瑞
2013.10.22 NUAA
建议大家阅读代码的顺序为:config.h SCH51.h SCH51.C main.c T0_init.h T0_init.c TASK.h task.c 。
大家如果对代码中的某些算法有更高意识的意见或建议时,可以给我留言。你的建议可能 be part of the new version !
在聊这个操作系统之前,我们先来聊点题外话。后面,我会贴出所有代码,并且附上完整的工程文件给大家。
请注意,以下讨论的内容,都是以51单片机为硬件平台的,但是,本文所述的重点内容并不拘泥于某一种特定的处理器,大家可以回去把代码移植到STM32、S3C2440、以及一些DSP上去,因为本代码并未涉及任何堆栈处理。
这里我想表达的不是程序的算法,而是一种本人称之为“面向任务”的项目开发思想(如果你学过C++、JAVA并且理解什么是“面向对象”那就最好了,你应该明白我说的“面向任务”是个什么意思)。之所以以51为平台,是因为大家对51很熟悉,讲起来更容易理解。我曾经看过一些人学uC/OS-II,本来对STM32就不熟悉,又去在STM32上跑一个更不熟悉的 uC/OS-II ,甚至还有人在这种情况下又加上个 uC/GUI。我就只能说呵呵了。
为什么要写这个操作系统(准确的说应该是“调度系统”)?
本人现在还是学生,之前做过一些单片机、DSP以及ARM的项目,但是无一例外地,在做项目中都会遇到一个头疼的问题(这个阶段我总称它为“瓶颈期”或“难产期”),就是多任务并行问题的处理。我们不可能每次遇到多任务并行处理就把uC/OS-II拿过来,的确 uC/OS-II 是一个很好的RTOS,曾经很长一段时间我都迷恋她 ,但是我总觉得只有在非常必要的时候才应该把 uC/OS-II 搬上来,因为 uC/OS-II 真的会使我们的项目开发起来很简单,很有条理,但是每次遇到多任务就用 uC/OS-II 我就觉得有点小题大做了。况且,8位机仍然占据着微控领域的半壁江山,所以,把 uC/OS-II 搬到51中去开发项目,有点像把大象往冰箱里塞,整个系统也会非常迟钝。
我们知道,单片机程序最常见的就是超级循环模式,即while(1)大循环,这种结构一个很大的缺陷就是当我们的MCU需要同时处理多个任务的时候,作为开发者,你的优秀的程序构架就显得相当重要。比如某个项目中要求LED数码管每20ms(50Hz)扫描一次,另一个任务每100ms(10Hz)执行一次,还有一个任务每2s执行一次(比如AD转换监测),…… , 等等。对于这样的要求,其实我们可以通过这个方法来解决:定义很多个全局变量来计时,比如:Timr_A、 Timr_B、 Timr_C,……,等等,单片机上电后第一件事就是启动定时器,在定时中断中挨个使Timr_A、 Timr_B、 Timr_C,…… ,自增,各个任务根据自己的执行周期来判断各自对应的变量(Timr_A、 Timr_B、 Timr_C,…… )有没有达到指定数值,以决定是否执行任务函数。这个原理有点像STM32中的PWM生成。但是这种方法只是一种治标不治本的法子。如果任务非常多,定时器麻烦就大了,因为单片机的中断程序应该尽可能快的结束。而且,如果任务A和任务B定时同时定时到,该执行哪个?如果执行A,那么B就得舍弃,注意,是舍弃,不是等一会再执行B。还有,如果某个任务执行时间出现抖动,整个系统和其它任务都要遭殃了。任务之间的干涉会非常严重。等等。
“面向任务”的思想的一个很重要的原则就是任务之间是低耦合的,原则上是“完全并行”的(不考虑系统全局变量的话)。
在本代码中,力求将多任务并行的情况予以抽象,就其共性提出解决方案,并以代码的最终调试成功作为实现。在此,我不打算带着大家一行一行分析代码。这玩意讲解没用,自己去悟懂了才是王道,我的代码注释得已经很详细了其实。当然,我一贯认为程序是没有百分之百正确的,所以你要是发现这些代码中有值得改进的地方,请你速度指出来,我们一起实现!联系方式见下面。
如果有问题可以加我QQ(986796621),非常喜欢和大家一起讨论问题,使这段代码实用起来,以解决实际问题。
代码的重点是 SCH51.C 和 T0_INIT.C 两个文件,使用之前请务必先看看 CONFIG.H 的配置情况。task.c文件内容你可以自定义来实现。其它的我都有注释的。
海瑞
2013.10.22 NUAA
这么好的技术分析文章为嘛没人顶呀
牛,有想法。
任务都是在中断里执行的。
顶一下,分析的很好
这么好的技术分析文章充分顶!
我今年要用51单片机参加电赛,多任务运行一直在困扰我,希望大神多多指点!
学习一下,顶一下!
学习,学习