51 单片机多任务操作系统的原理与实现 51 单片机多任务操作系统的原理与实现-- 一个超轻量级的操作系统前言想了很久,要不要写这篇文章?最后觉得对操作系统感兴趣的人还是很多,写吧.我不一定能造出玉,但我可以抛出砖.包括我在的很多人都对 51 使用操作系统呈悲观态度,因为 51 的片上资源太少.但对于很多要求不高的系统来说,使用操作系统可以使代码变得更直观,易于维护,所以在 51 上仍有操作系统的生存机会. 流行的 uCos,Tiny51 等,其实都不适合在 2051 这样的片子上用,占资源较多,唯有自已动手,以不变应万变,才能让 51 也有操作系统可用.这篇贴子的目的,是教会大家如何现场写一个 OS,而不是给大家提供一个 OS 版本.提供的所有代码,也都是示例代码,所以不要因为它没什么功能就说 LAJI 之类的话.假如把功能写全了,一来估量你也不想看了,二来也失去灵活性没有价值了. 下面的贴一个示例出来,可以清楚的看到,OS 本身只有不到 10 行源代码,编译后的目标代码 60 字节,任务切换消耗为 20 个机器周期.相比之下,KEIL 嵌的TINY51 目标代码为 800 字节,切换消耗 100~700 周期.唯一不足之处是,每个任务要占用掉十几字节的堆栈,所以任务数不能太多,用在 128B 存的 51 里有点难度,但对于 52 来说问题不大.这套代码在 36M 主频的 STC12C4052 上实测,切换任务仅需 2uS. #include #define MAX_TASKS 2 //任务槽个数.必须和实际任务数一至 #define MAX_TASK_DEP 12 //最大栈深.最低不得少于 2 个,保守值为 12. unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP]; //任务堆栈. unsigned char task_id; //当前活动任务号 //任务切换函数(任务调度器) void task_switch(){ task_sp[task_id] = SP; if(++task_id == MAX_TASKS) task_id = 0; SP = task_sp[task_id]; } //任务装入函数.将指定的函数(参数 1)装入指定(参数 2)的任务槽中.假如该槽中原来就有任务,则原任务丢失,但系统本身不会发生错误. void task_load(unsigned int fn, unsigned char tid){ task_sp[tid] = task_stack[tid] + 1; task_stack[tid][0] = (unsigned int)fn & 0xff; task_stack[tid][1] = (unsigned int)fn >> 8; }//从指定的任务开始运行任务调度.调用该宏后,将永不返回. #define os_start(tid) {task_id = tid,SP = task_sp[tid];return;} /*===...