做了7个文件,分别是
os_core.h //核心文件的参数定义
os_core.c //核心文件,包含进程的6种操作,系统级别的操作
task_switch.h //任务切换函数的定义
task_switch.c //任务切换函数的实现,采用抢占式中断调用(T2自动重载)
sem.h //信号量的定义,其实也就是3个函数,创建信号量,发送一个信号量,接收信号量,在教材里面讲得那么复杂,差点把人搞晕了,实现起来不要太简单
sem.c //信号量实现
main.c //任务以及它的操作和主函数包括在这里
//---------------------------------------------------os_core.h---------------------------------------------------------------// #ifndef __OS_CORE_H__ #define __OS_CORE_H__ #includetypedef signed char int8s; typedef unsigned char int8u; typedef signed int int16s; typedef unsigned int int16u; typedef signed long int32s; typedef unsigned long int32u; //任务的5种状态 #define TASK_STATUS_CREATE 0x00 #define TASK_STATUS_RDY 0x01 #define TASK_STATUS_SUSPEND 0x02 #define TASK_STATUS_ENDED0x04 #define TASK_STATUS_SEM0x08 //任务控制块 typedef struct { int8u task_status;//任务状态 int8u task_priority;//任务的优先级 int8u task_stack_top;//任务栈顶地址(保存任务栈顶的地址) int8u task_wait_tick;//任务延时等待次数 }OS_TCB; #define MAX_TASKS 4//最大的任务数量 //任务的优先级从小到大一次排列,数值越小,优先级越高 #define TASK_STACK_DEPTH 17//最大任务堆栈深度(2字节程序地址+13字节寄存器数据+2字节中断过程保存字节) #define NUM_RESISTER_PUSHED 13//人工堆栈中需要被保存的寄存器数量(这里因为是8051,所以有13字节) extern idata volatile OS_TCB os_tcb[MAX_TASKS];//任务控制块列表 extern volatile int8u task_running_id;//正在运行任务的标号 extern volatile int8u os_res_list;//系统资源表,表示哪些资源是否被占用(最大为8个) extern volatile int8u idata task_stack[MAX_TASKS][TASK_STACK_DEPTH];//每个任务的任务栈 extern volatile int8u task_int_list;//任务中断标记(最大为8个) extern volatile int8u int_count;//进入中断次数 extern volatile int8u os_en_cr_count;//进入临界区次数 #define os_enter_critical() {EA=0;os_en_cr_count++;} //进入临界区 #define os_exit_critical() {if(os_en_cr_count>0){os_en_cr_count--;if(os_en_cr_count==0){EA=1;}}}//退出临界区 //任务的六种操作 void task_create(void (*task)(void),int8u task_priority); void task_delete(int8u task_id); void task_sleep(); void task_wake(); void task_suspend(int8u task_id); void task_resume(int8u task_id); //系统操作 void os_init();//初始化系统 void os_start();//开始系统 void os_delay(int8u tick);//任务延时 void os_task_idle();//空任务,具有最低优先级 #endif //---------------------------------------------------os_core.c---------------------------------------------------------------// #include "os_core.h" #include "task_switch.h" idata volatile OS_TCB os_tcb[MAX_TASKS];//任务控制块列表 volatile int8u task_running_id;//正在运行任务的标号 volatile int8u os_res_list;//系统资源表,表示哪些资源是否被占用(最大为8个) volatile int8u idata task_stack[MAX_TASKS][TASK_STACK_DEPTH];//每个任务的任务栈 volatile int8u task_int_list;//任务中断标记(最大为8个) volatile int8u int_count;//进入中断次数 volatile int8u os_en_cr_count;//进入临界区次数 /* ******************************************************************************************************** 任务操作 ******************************************************************************************************** */ void task_create(void (*task)(void),int8u task_priority) { static int8u i; static int8u task_id; static int8u *stack_point; for(i=0; i >8; //任务高8位给task_stack[task_id][1] stack_point += NUM_RESISTER_PUSHED; //将13个寄存器位置保存起来 //为任务添加属性 os_tcb[task_id].task_stack_top = (int8u)stack_point; os_tcb[task_id].task_priority = task_priority; os_tcb[task_id].task_wait_tick = 0; os_tcb[task_id].task_status = TASK_STATUS_RDY;//将任务置于就绪态 } void task_suspend(int8u task_id) { //挂起一个任务 os_enter_critical(); os_tcb[task_id].task_status = TASK_STATUS_SEM;//将该任务的状态置于被挂起的状态(由于信号量) os_exit_critical(); if(task_id == task_running_id) { os_task_switch(); //调用一下任务切换,切换到其它任务 } } void task_resume(int8u task_id) { os_enter_critical(); if(os_res_list&(0x01< 总结:
在51单片机上实现操作系统是我们不常讨论的话题,其实操作系统还是有蛮大的用处的, 上次我写了一篇文章:一个简单的51单片机操作系统的实现,连接是:http://www.51hei.com/mcu/1325.html ,这篇其实是对上篇文章的补充.实现更多的一些功能,希望大家多多指点啊.
实现了任务的互斥,使得两个任务之间能够互斥运行,但是不能是两个以上,因为系统采用的是抢占式的中断调度,所以两个以上任务公用一个信号量,会出现优先级较低的那个任务出现饥饿的情况。
任务的实时性是很有保障的,因为内部函数比较简单,所以不存在嵌套中断的说法。
计算一下程序使用的RAM,一共使用大概101字节,剩余107字节可用,感觉还不错.
现在已经成功地实现信号量的功能。
剩下的还有邮箱、事件、内存等等了,不过由于8051RAM空间还是小了些,如果能扩充到4KB以上,发展潜力倒是会有很大的提高,不过外置RAM肯定速度上比不了内置的。
自己动手做51操作系统现在暂时告一段落,操作系统还是在片上资源丰富的系统上用比较好,不过STC的那个最NB的STC90C516AD拥有4KB的RAM和62KB的ROM用起来也可以的。价格也不贵,有空再去尝试...
当任务多了的时候,任务的配置模块也很多,RAM里面84%以上的空间都是用于任务的各种属性的配置,包括任务堆栈和任务的互斥。
希望接下来的复习能够更加认真!!!现在算是了却了我内心中的一桩心愿吧,真正实现了自己的操作系统!!!(功能匮乏,只有进程调度和互斥实现)
现在我才知道链表的操作是多么地耗费内存.创建一个指针就要3个字节,如果搞个链表出来,包括结构体,在资源不那么丰富的8051上(操作系统中),简直是宰牛用杀鸡刀,完全吃不消.但是如果是AVR或者ARM等片上资源丰富的单片机,那就不存在了.
为什么手机的操作系统里面一个安装文件动不动就几MB的大小,为什么Android中的程序动不动就占用几MB的内存?
这就和操作系统有很大关系了,创建一个任务,给它定义进程控制块,堆栈,还要包括它的GUI,别看图形界面特别简单,实际上采用图形界面还是相当吃内存的.在进程切换中,保存堆栈和一些进程信息,这又得占用一部分内存.Android因为采用虚拟机的缘故,这虚拟机它也得吃内存啊,开个程序就有个虚拟机跟着,速度当然不如symbian了.可惜symbian内存和cpu的频率比较低...
所以内存占用和系统任务的个数是线性关系的.当某个程序比较大,它占用内存越多,而且可能会频繁地读取内存,这样就会造成其它程序速度变慢.这就是为什么在听歌的时候,上网有时会有点卡的原因之一.
系统启动的时候,会把程序加载进入内存中,当需要加载的程序数量过多时,自然就会比较卡.所以开机的时候会有一段延迟.
上一篇:基于DS1302的简易数码管电子钟
下一篇:基于单片机的12864液晶显示动画效果设计
推荐阅读最新更新时间:2024-03-16 13:05
设计资源 培训 开发板 精华推荐
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?
- 村田推出高精度汽车用6轴惯性传感器
- 福特获得预充电报警专利 有助于节约成本和应对紧急情况