单片机,STM32F4-UCOS,学习笔记【1500字】【原创】


SVC异常

SVC=系统服务调用=系统调用
SVC异常=用户程序开始控制硬件系统(间接控制)
总的来说,用户程序=代码到操作系统=UCOSIII=OS代码(很稳定,很强大)到系统硬件=电路板=外部设备=底层硬件,操作系统不让用户程序直接操作底层硬件
UCOS没有使用这个SVC功能=Cortex-M3/M4内核中的SVC功能(不早说,我看了这么久)

PendSV异常

PendSV异常=和SVC协同使用=会自动延迟上下文切换(任务之间切换)时中断请求=防止任务切换动作拖延很久(被中断耽误)(反正我没懂)
PORT=端口
滴答计时器=24位倒计时器=168Mhz分8频时就是21Mhz,记满一次0.7989s左右

任务状态

任务状态
休眠态(仅仅是代码),就绪态(等待CPU使用),运行态(正在运行的任务),等待态(正在运行的任务在等待某个事件,如消息),中断服务态(正在执行的任务被中断打断,CPU转而执行中断服务程序,此时这个任务就会挂起,进入中断服务态)

任务介绍

任务控制块=结构体=成员是任务的各种信息状态及各种任务功能

任务堆栈=用来切换任务和调用其他函数时保存现场=每个任务都有自己的堆栈

任务就绪表=优先级位映射表(当某一个任务就绪以后,优先级位映射表中相应的位就会被置1,用来标记哪个任务就绪了)+就绪任务列表(用来记录每一个优先级下的所有就绪的任务)

任务调度和切换=让就绪表中优先级最高的任务获得CPU使用权=任务级调度器(首先检测任务是否在中断里面,和是否加锁,然后关中断(任务调度!=中断调度),获取就绪表中优先级最高的任务,再获取下一次任务切换时要运行的任务(同一优先级下可以有多个任务),再判断任务是否是正在运行的任务,如果是就不做任务切换,否则进行任务切换,执行完之后最后再开中断)+中断级调度器(首先判断UCOSIII是否在运行,然后中断嵌套计时器用来记录中断嵌套的次数,具体可看开发手册,最后一步是开中断)

时间片轮转调度(没懂这个),时间片=时钟节拍

简易OS设计

【简易OS设计】
运行态,等待态和挂起态,就绪态
运行态就是优先运行级别最高的任务(此时它占用CPU)(单核CPU一次只能做一件事情)
当级别最高的任务运行完毕或者某种原因挂起时,让出CPU使用权,此时就绪态开始运行
运行态之后就是等待态,等待态再到就绪态

就续表=32位变量=类似寄存器使用,从左至右,bit31到bit0,其中bit31就是优先级31,bit0就是优先级0,优先级0的优先级别最高,优先级是任务的唯一标识号,通过就续表来判断各个任务之间的优先级,就续表中通过一个for循环来进行查找最高的优先级,这种算法不算最好但是最简单,这种算法的延时随任务数量的改变而不同

多任务系统的时钟节拍由定时器0来产生,也就是T0定时器

当任务被挂起时,会设定其任务的延时节拍数,然后开始执行下一个任务,此时在T0中断里面对这个节拍数递减,当某一时刻递减到0时,则挂起态转为就绪态,准备开始进入运行态

IdleTask是系统自身创建了一个空闲任务,并设定为最低优先级(31),设定它的原因是当没有其他任务运行时,不让CPU闲着,不能在空闲任务中运行任何有可能使这个空闲任务挂起的函数,这不允许,因为必须是一直就绪状态

通过建立静态数组和指针,使得每个任务都有自己的私有栈,和自己的任务控制块=记录任务运行的环境=结构体(成员都是任务的一些信息,如堆栈顶,如延时时钟等),每个任务在被挂起之前,都会将挂起前的所有数据和状态存放在自己的私有栈里面,待到下一次运行态时再取出来给CPU即可,创建任务也就相当于创建一个私有栈(用来保持任务运行的环境),主要是接收任务的入口地址,任务堆栈的首地址,和任务的优先级这三个参数

CPU总是执行处于就绪条件下优先级最高的任务,但是高优先级任务如果处于某种情况下,如主动请求挂起,或者遇到更高级别的任务时(延时时钟),此时就会发生任务切换,也叫做抢占式调度。如果此时遇到了中断,也叫做中断级的切换,当然中断也可以嵌套中断,此时当所有的嵌套中断都完成时,才会返回之前的任务,若中断之后又需要任务切换,则也不会返回之前的那个任务

挂起可以挂起自己也可以挂起别的任务

文中“一些技巧”,不就是众拳里面的吗,哈哈哈,早已熟知,太秀了,第二个关于全局变量的定义技巧,真的让我拍案叫绝,拍手称快,666,建议一看

基于51单片机ucos实时操作系统 #include "includes.h" #include "serial.h" sbit LED1=P1^5; sbit LED2=P1^6; unsigned char xdata strbuf[8]; OS_STK TaskStartStk1[MaxStkSize],TaskStartStk2[MaxStkSize],TaskStartStk3[MaxStkSize]; void Task1(void *nouse) reentrant; void Task2(void *nouse) reentrant; void Task3(void *nouse) reentrant; void DecTochar(unsigned int n,unsigned char *buf) { unsigned char i; unsigned char buffer[8]; for(i=0;i0;i--)*buf++=buffer[i]; *buf++=buffer[i]; *buf='\r'; buf++; *buf='\n'; } void main(void) { OSInit(); InitHardware(); OSTaskCreate(Task1, (void *)0, &TaskStartStk1[0],2); OSTaskCreate(Task2, (void *)0, &TaskStartStk2[0],3); OSTaskCreate(Task3, (void *)0, &TaskStartStk3[0],4); OSStart(); } void Task1(void *nouse) reentrant { unsigned char const Str0[]="Welcome to MCU123.COM \r\n"; unsigned char const Str1[]="Task1 is running! LED1=ON \r\n"; unsigned char const Strv[]="uCosII_Ver"; nouse=nouse; SendStr(Str0, sizeof(Str0)); DecTochar(OSVersion(),strbuf); SendStr(Strv,sizeof(Strv)); SendStr(strbuf, sizeof(strbuf)); for(;;) { LED1 = 0; SendStr(Str1, sizeof(Str1)); OSTimeDly(OS_TICKS_PER_SEC*2); } } void Task2(void *nouse) reentrant { unsigned char const Str2[]="Task2 is running! LED2=ON \r\n"; nouse=nouse; for(;;) { LED2 = 0; SendStr(Str2, sizeof(Str2)); OSTimeDly(OS_TICKS_PER_SEC*2); } } void Task3(void *nouse) reentrant { unsigned char const Str3[]="Task3 is running! LED1=OFF LED2=OFF \r\n"; nouse=nouse; for(;;) { LED1 = 1; LED2 = 1; SendStr(Str3, sizeof(Str3)); OSTimeDly(OS_TICKS_PER_SEC); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值