大一学了51单片机,对于单片机的一些常用外设有了一定的了解。之后,大家都在说当前最流行的单片机是stm32,所以我抽出了暑假的时间的时间学习了stm32单片机,刚开始学的时候真的很痛苦,在坚持了一个星期之后,我慢慢找到了自信,stm32单片机实际上和51是一样的,只是需要配置的寄存器多了一点。在刚开始学的时候,经常在配置的时候无法配置完全,导致无法得到预期的实验效果,但是实际上,大家没必要过分纠结于配置,完全可以直接参考别人使用该功能的配置方式。我们应该将心思放在功能的开发上,而不是纠结于前期简单的配置。在熟悉使用stm32之后,开始接触操作系统ucos,过程中一直觉得自己似懂非懂,所以我在想为什么我自己不利用51写一个简易操作系统,来加深自己的理解。初期写出的操作系统不用考虑通信等高级功能,只需要写出可以调度多个任务的操作系统即可,下面给大家介绍一下我自己写的操作系统(写的不太好,仅供大家参考)。
实现简易操作系统,主要需要实现三个函数:
1 创建任务函数介绍
int OSTaskCreate(unsigned int Task, unsigned char* pStack, unsigned char TaskID)
{
unsigned char i = 0, j = 0;
*pStack++ = Task & 0xFF; //低八位地址(51单片机入栈向上,出栈向下)
*pStack = Task >> 8; //高八位地址
os_enter_critical();
TaskCB[TaskID].OSTaskStackButtom = (unsigned char)pStack + 13;
TaskCB[TaskID].OSWaitTick = 0;
TASK_READY(TaskID); //将该优先级的任务在全局变量中标记为就绪
os_exit_critical();
return 0;
}
入口参数:
unsigned int Task ---- 任务函数的入口地址
unsigned char* pStack ---- 任务函数的堆栈,主要用来保存现场参数
unsigned char TaskID ----- 任务优先级
2 任务延时函数
void OSTimeDly(unsigned int time)
{
TaskCB[CurrentTaskID].OSWaitTick = time; //将任务的延时时间赋值给任务控制块
task_sw(); //任务调度
}
static void task_sw()
{
os_enter_critical();
TASK_BLOCK(CurrentTaskID); //将当前任务的就绪状态取消
#pragma asm //将现场的关键参数存入堆栈
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#00H
PUSH AR0
PUSH AR1
PUSH AR2
PUSH AR3
PUSH AR4
PUSH AR5
PUSH AR6
PUSH AR7
#pragma endasm
TaskCB[CurrentTaskID].OSTaskStackButtom = SP ; //将当前任务的堆栈位置保存,用于下次恢复该任务
CurrentTaskID = Task_High(); //找出处于就绪态的最高优先级的任务
SP = TaskCB[CurrentTaskID].OSTaskStackButtom;
#pragma asm
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR2
POP AR1
POP AR0
POP PSW
POP DPL
POP DPH
POP B
POP ACC
#pragma endasm
os_exit_critical(); //离开时会把SP的当前位置的值送入PC指针,所以最高优先级的任务得以运行
}
3 中断调度函数
void TF0_isr() interrupt 1
{
TH0 = 56320/256;
TL0 = 56320%256;
TaskCB[CurrentTaskID].OSTaskStackButtom = SP; //被中断的任务的现场已经压入堆栈,所以只需保存SP
CurrentTaskID = Task_Ready_High(); //取出就绪中优先级最高的任务
SP = TaskCB[CurrentTaskID].OSTaskStackButtom;
#pragma asm
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR2
POP AR1
POP AR0
POP PSW
POP DPL
POP DPH
POP B
POP ACC
RETI
#pragma endasm
}
总结:
以上三个函数就是一个简易操作系统的关键函数,大家可以自己动手实现一下。这对大家学习ucos有很大的帮助,同时也为学习linux系统打下基础。
后续我会继续完善这个简易操作系统,添加通信等功能,希望大家可以关注我,共同进步。
联系客服