ucos-II操作系统
19.1 操作系统介绍
UC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个.
19.1.1 操作系统简介
什么是操作系统
操作系统是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。介于APP和硬件之间。
19.1.1 常见的操作系统
常见的操作系统:
IOS(苹果)、安卓()、Windows、Linux、塞班、UCOS、FreeRTOS、RT-T(国产)、Vxworks、eCos等等。
实时操作系统(RTOS)
UCOS(学习免费,商用需要注册)、FreeRTOS、RT-T(国产)、Vxworks、eCos
会给每个任务一个基础的时间长度,根据任务的需求适当调整任务时长。任务与任务直接切换都有相应的规则。
分时操作系统
Windows----2000以前、Linux----2.6以前
给每一个任务分配一个固定的时长,如果这个任务在固定的时长内已经空闲,分时操作系统还是会给该任务规定好的时长。
半实时操作系统
Windows----7/8/10、Linux----2.6以后
19.1 UCOS操作系统介绍
19.1.1 操作系统的调度原则
UCOS操作系统调度原则是:以任务优先级为调度原则。任务优先级编号越小的,任务优先级越高。
注意点:每个任务只有一个优先级,不同任务优先级编号不能一致。
19.1.1 操作系统的程序结构
没有操作系统时
整个裸机项目工程中有且仅有一个死循环,这个死循环存在main函数中。其它地方可以有死循环但是必须要有退出条件。
有操作系统时
整个操作系统项目工程中可以有多个死循环,每个任务中有一个死循环,main函数中无死循环。
注意点:操作系统在main中必须完成两点:①设定好操作系统心跳节拍;②创建一个任务(该任务必须创建成功)。
19.1.1 操作系统的任务调度
任务调度:指的是什么时候会发生任务调度。
两种情况下会发生任务调度。
操作系统的心跳节拍到达。心跳节拍称为一个Tick。UCOS中有一个专用的操作系统心跳节拍函数:OSTimeTick();
操作系统中的程序代码调用OS_Sched();该函数时会产生任务调度。OS_Sched():称为任务调度函数。
注意:任务调度函数我们不能够直接调用,只能是操作系统调用。程序员调用该函数会使得UCOS操作系统崩溃。
注意点①:操作系统发生任务调度不一定切换任务;任务切换一定需要产生任务调度。
注意点②:操作系统中高优先级任务必须要有释放CPU控制权函数调用。
19.1.1 操作系统的任务状态
UCOS操作系统中,任务状态有五种:停止/休眠、准备就绪、运行、挂起/等待、中断。只有当任务进入到运行状态才可以执行任务中的程序代码。
停止:任务被删除。
休眠:当前没有任何一个任务准备就绪,运行状态中没有任务执行。
准备就绪:任务运行需要满足的条件都准备完成。
运行:任务正在运行。
挂起:任务需要等待某一个条件发生,其他任务可以将这个任务挂起。
等待:延时相关的。
中断:程序发生了中断事件,CPU要去处理中断服务函数,中断操作系统。
19.1.1 操作系统的任务中断
中断状态中需要注意以下几点:
从运行状态进入中断状态必须要调用函数OSIntEnter();该函数的功能是用来告诉操作系统当前程序进入中断。
从中断状态退出后进入运行状态之前必须调用函数OSIntExit();该函数的功能是用来告诉操作系统当前程序退出中断。
程序从中断中退出,操作系统返回到任务中去,这时不一定返回到原来的任务中。
1 /* 2 函数功能:初始化系统滴答定时器 3 函数形参:任意毫秒 4 函数返回值:无 5 备注:控制操作系统的心跳节拍----中断方式 6 作者:李工 7 时间:2018-09-19 8 */ 9 void SysTick_Init(u16 n_ms) 10 { 11 SysTick->CTRL = 0;//清空配置 12 //选择时钟源为21MHz 13 14 SysTick->VAL = 0; 15 16 SysTick->LOAD = n_ms * 21000; 17 18 SysTick->CTRL |= (0X1 << 1);//开启模块级中断使能 19 20 SysTick->CTRL |= (0X1 << 0);//开启递减计数器--使能 21 } 22 23 /* 24 函数功能:系统滴答定时器的中断服务函数 25 函数形参:无 26 函数返回值:无 27 备注:告诉操作系统进中断、出中断、心跳节拍函数 28 作者:李工 29 时间:2018-09-19 30 */ 31 void SysTick_Handler(void) 32 { 33 OSIntEnter();//进中断 34 35 if(SysTick->CTRL & (0X1 << 16)) 36 { 37 OSTimeTick();//心跳节拍函数 38 } 39 40 OSIntExit();//出中断 41 } 42 43 /* 44 函数功能:主函数 45 函数形参:无 46 函数返回值:整型 47 备注:使用UCOS操作系统 48 49 */ 50 int main(void) 51 { 52 //初始化系统滴答定时器 53 SysTick_Init(1000 / OS_TICKS_PER_SEC); 54 //初始化操作系统 55 OSInit(); 56 //创建一个任务 57 OSTaskCreate(os_start_task,NULL,&OS_STK_START_TASK_SIZE[OS_STK_START_TASK_LENGTH - 1],OS_START_TASK_PRIO); 58 //启动操作系统 59 OSStart(); 60 //如果任务创建失败则执行这个无限循环 61 while(1) 62 { 63 ; 64 } 65 }
1 INT8U OSTaskCreate (void (*task)(void *p_arg), 2 void *p_arg, 3 OS_STK *ptos, 4 INT8U prio) 5 函数功能:创建一个任务 6 函数形参:void (*task)(void *p_arg):函数指针,用来存放任务函数 7 void *p_arg:任务函数的形参传递,如果无形参传递使用NULL即可 8 OS_STK *ptos:任务的任务栈的栈顶 9 INT8U prio:任务的优先级编号 10 函数返回值:OS_ERR_NONE:表示创建成功;否则表示失败 11 使用方法: 12 OSTaskCreate(os_start_task,NULL,&OS_STK_START_TASK_SIZE[OS_STK_START_TASK_LENGTH - 1],OS_START_TASK_PRIO); 13 任务的具体实现: 14 #define OS_START_TASK_PRIO 10 15 #define OS_STK_START_TASK_LENGTH 256 16 OS_STK OS_STK_START_TASK_SIZE[OS_STK_START_TASK_LENGTH]; 17 18 /* 19 函数功能:启动任务 20 函数形参:万能指针 21 函数返回值:无 22 备注:无 23 作者:李工 24 时间:2018-09-19 25 */ 26 void os_start_task(void *p_arg) 27 { 28 29 while(1) 30 { 31 32 } 33 }
19.1 UCOS操作系统任务管理
19.4.1ucos任务组成
任务控制块(底层,不需要掌握)、任务优先级,任务栈,任务函数。
任务控制块:当创建一个任务的时候,ucos会分配一段内存空间给这个任务,这段内存空间就称为任务控制块。任务控制块记录了任务的相关信息:任务函数地址、任务的优先级、任务状态、任务栈地址。
任务优先级:每个任务都有一个唯一的优先级,优先级也只我们这个任务在ucos中的唯一标识,任务的优先级是ucos做任务调度的依据。
任务栈:当任务切换的时候保存该任务的状态(切换之前执行到哪里了,局部变量)。
任务函数:当任务被调度的时候,要完成的工作。
19.1 UCOS操作系统任务间通信
19.1.1 信号量
(保护那段代码不被别的进程抢走)
作用:保护共享资源。
信号量:在UCOS操作系统里面就相当于一个全局变量,释放信号量让这个信号量的值加1,使用信号量让这个信号量的值减1。最小值为0。
19.1.1 消息邮箱
19.1.1 消息队列
19.1.1 互斥信号量
19.1 UCOS操作系统事件标志组