硬汉嵌入式论坛

 找回密码
 立即注册
查看: 8021|回复: 3
收起左侧

自编51单片机的小型操作系统

[复制链接]

4

主题

12

回帖

34

积分

新手上路

积分
34
发表于 2015-3-9 20:41:36 | 显示全部楼层 |阅读模式
这是在寒假里完成的基于51单片机的操作系统,能实现的功能有信号(Signal)、互斥体(Mutex)、消息(Message),当然任务的创建和暂停、无阻塞延时、统计、定时器等功能是有的,遗憾的是身边没有单片机实物,只是在KEIL里仿真。
一优先级一任务,OS_MAX_NUM_TASK定义最大任务个数,OS_TickFrequency系统滴答频率,操作系统占用最高优先级(OS_SYS_Task)和最低优先级(TaskIdle),定时器和统计任务就是通过OS_SYS_Task实现的。
我会用UCOS-III(运行在STM32F407),但是看不懂它是怎么编的,用起来感觉别扭。刚好上一学期学了51单片机汇编语言,所以决定自己编一个能在51上运行的操作系统。
感觉比较难的是上下文切换,这里用到很多汇编语句。系统每次切换任务时,首先会保存上文(CPU寄存器组+堆栈),而后获取下一就绪任务,恢复下文。基本都是这样。
具体代码如下:
PUBLIC    OS_TaskSwitch
.......
OS_TaskSwitch:
USING    0
        DISABLE_ALL_INT                            ;屏蔽中断
        PUSH_ALL_REG                            ;压栈保存
        LCALL    TaskSwitch_HOOK                    ;调用钩子函数
        LCALL    FIND_NEXT_TASK                    ;寻找下一优先级任务
        MOV        A,OS_CurTaskNum                    ;判断是否需要任务切换
        CJNE    A,OS_NexTaskNum,TASK_SWITCH_1    ;下一就绪任务不是当前任务,需切换
        LJMP    TASK_BACK_1                        ;下一就绪任务是当前任务,不用切换
        TASK_SWITCH_1:                            ;开始任务切换
        SAVE_CONTEXT                            ;保存上文
        LOAD_NEXT_PRIO                            ;优先级保存
        RESTORE_CONTEXT                            ;恢复下文
        TASK_BACK_1:                            ;任务不用切换直接返回
        POP_ALL_REG                                ;弹栈恢复
        ENABLE_ALL_INT                            ;打开中断
RET
我把挂起任务的堆栈和寄存器保存在XDATA,不会占用DATA(正在运行的任务的堆栈就在DATA)
完成了这个功能(最基本的),再配合一些“表”,其他的功能不是问题。
第二难的就是中断管理了,我做的不好,外部中断0代码如下:
CSEG    AT    00003H
    LJMP    Extern_0_Int_
RSEG    ?PR?Extern_0_Int_?OS_ASM
Extern_0_Int_:
USING    0
        DISABLE_ALL_INT
        PUSH_ALL_REG
        LCALL    Extern_0_Int
        LCALL    FIND_NEXT_TASK                    ;寻找下一优先级任务
        MOV        A,OS_CurTaskNum                    ;判断是否需要任务切换
        CJNE    A,OS_NexTaskNum,TASK_SWITCH_3    ;下一就绪任务不是当前任务,需切换
        LJMP    TASK_BACK_3                        ;下一就绪任务是当前任务,不用切换
        TASK_SWITCH_3:                            ;开始任务切换
        SAVE_CONTEXT                            ;保存上文
        LOAD_NEXT_PRIO                            ;优先级保存
        RESTORE_CONTEXT                            ;恢复下文
        TASK_BACK_3:                            ;任务不用切换直接返回
        POP_ALL_REG                                ;弹栈恢复
        ENABLE_ALL_INT                            ;打开中断
RETI
其实就是任务切换函数+LCALL    Extern_0_Int,5个中断源都是这样处理的,幸亏只有5个,否则我肯定不会这么做。
第三难的就是函数的参数以及可重入问题了,查阅了相关资料,看着挺费劲的,算了,函数参数和局部变量尽量少,返回值也不加了。
还有就是中断安全的问题了,在操作重要数据(比如就续表)的时候,一定不能被中断。
编写完成,感觉自己对操作系统的了解深入了很多。现拿出来分享,希望能帮到那些有需要的人。
顺便向各位经验丰富的网友咨询一个问题,我是一个大三的学生(东北电力大学-自动化),现面临考研,我的兴趣就是嵌入式这些东西,
因此我希望我以后能在此方向发展,毕竟兴趣和职业相结合是最好不过的,那我考研应该考什么方向的呢?我想听一下各位的建议,谢谢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2015-3-9 20:48:27 | 显示全部楼层
感谢楼主分享,加精[s:151] [s:150]
回复

使用道具 举报

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2015-4-10 12:07:08 | 显示全部楼层
额 完全看不懂
回复

使用道具 举报

100

主题

275

回帖

575

积分

金牌会员

积分
575
发表于 2015-5-24 16:00:49 | 显示全部楼层
学了一学期就能编操作系统了也是强人啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-1 20:42 , Processed in 0.176795 second(s), 31 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表