梅科尔工作室-看鸿蒙设备开发实战14天笔记(四)-内核管理
###本文章仅整理视频笔记及对一些地方的解释,如果想看详细内容,请在鸿蒙开发者学堂搜索鸿蒙设备开发###
###本文章图片来自视频后PDF文档,本文侧重代码讲解###
1.任务管理
1.1.任务管理基本概念
1.2.任务相关概念
1.3.任务调度机制
1.4.相关函数
1.5.代码实例
1.6.代码讲解
1.6.1.引入库
unistd.h内部有时间函数,可以用来设置时间,usleep(t)单位是微秒(千分之一毫秒)
ohos_init.h 内部有执行代码所需的函数APP_FEATURE_INIT(函数名)
cmsis_os2.h 用来提供进程API接口
1.6.2.编写任务创建代码
创建两个ID变量用来接收创建进程后的ID,全局变量
创建进程入口函数参数,存储进程相关信息
写入相关信息,name进程名,attr_bits与jion函数有关,暂时用不到,cb_mem控制块指针,没有NULL,cb_size不设置0U,stack_mem栈指针,stack_size栈大小(这个是需要设置的。priority进程优先级,CMSIS数字越大,进程优先级越高。
创建失败输出代码,上面创建函数内,thread1为函数名,NULL作为启动参数传给任务函数的指针为空,&attr传入相关参数
创建一个低优先级进程,由于attr并没有消失,直接改变进程值即可,其他值不变。
为了之后终端没有其他不必要提示,不用APP_FEATURE_INIT使用SYS_RUN并把上图最后一行代码注释
编写任务函数
首先两个任务创建后都处于就绪态,高优先级的Hi执行打印完毕迅速延迟,这时Hi处于阻塞态,低优先级Lo不断打印,还没打印完10个,高优先级Hi延时结束,任务切换,进入就绪态,由于Hi比Lo高,Lo停止进入就绪态,Hi迅速打印,之后被挂起,此时Hi再次进入阻塞态,Lo执行继续打印,直到运行到恢复代码,Hi恢复由阻塞态进入就绪态,执行Hi,输出恢复成功后删除进程,Lo执行,执行删除任务,结束。
2.软件定时器
2.1.基本概念
2.2.运作机制
2.3.如何使用API接口
2.4.实例代码
2.5.代码讲解
2.5.1.引入库
我们获取的项目文件的实例文件夹(sample)里面有大量实例代码,包括上面的任务管理Thread实例也包括软件定时器实例
2.5.2.定时器相关代码
定义两个给回调函数传的参数,并将它们设置成1U(10ms)
两个回调函数,时间到时执行的函数,里面都参数是exec1,exec2
定义变量,第一行是定时器id,第二行延时时间变量,第三行用来判断状态(是否停止、删除、开始)
定义一个定时器,返回一个id赋给id1,第一个参数是回调函数,第二个是定时器类型(单次osTimerOnce,周期性osTimerPeriodic),第三个是传入回调函数的参数,第四个属性参数为NULL
之后如果返回的id不是空,就执行下面if中代码,设置定时器间隔1s(timerDelay)
延时0.5s后执行停止函数并对是否执行成功进行判断,定时器只有在运行过程中才能停止,设置的是单次定时器,如果定时器已经结束了,osDelay才结束并执行停止函数,那么,将停止失败。
停止后再执行开始函数再次启动单次定时器,并传入定时器时间1s
2s后删除定时器(不管是运行中还是已经运行结束都可以进行删除)并对是否删除进行判断,函数是否执行成功通过status判断,osOk表示执行成功
第二个定时器(周期性)
之后使用APP_FEATURE_INIT调用实例函数,不要忘了在实例文件夹BUILD.gn进行配置,并取消注释任务管理中注释的SAMGR_Bootstrap();
3.信号量
3.1.基本概念
3.2.运作机制
3.3.信号量API接口使用(下方不是互斥锁是信号量)
3.4.实例代码
3.5.代码讲解
库不变
主函数代码
创建了三个同优先级的任务,并且创建了最大值为4的信号量
三个任务函数
第一个函数执行每100U释放两次信号量,信号量加2.第二个函数申请信号量,成功则打印提示,失败则等待50U,再打印失败提示。第三个函数申请信号量,申请失败则永久等待,直到有信号量可利用。
编译运行结果
一开始函数1释放两个信号量,函数2由于没有延迟可以申请两次并打印成功提示,之后函数2申请失败进入阻塞态等待50U打印失败提示,在阻塞态期间函数3执行申请失败进入阻塞态没有提示。
函数1还在等待,函数2再次申请失败进入阻塞态打印失败提示,执行函数3成功,并进入延时进入阻塞态,在阻塞态短短时间内,函数2执行申请信号量再次成0,再次申请失败后进入阻塞态并打印提示,函数3由于没有信号量也进入阻塞态,循环过程。
4.事件管理
4.1.基本概念
4.2.运作机制
4.3.API接口函数使用
4.4.实例代码
4.5.代码讲解
库一样
为三个事件分配空间
创建事件并创建两个同优先级任务
两个任务函数,发送事件,接收事件
发送事件任务每隔1s发送三个事件之后挂起1s执行接收事件函数,接收事件函数关键部分osEventFlagsWait第一个参数事件id,第二个是事件,第三个osFlagsWaitAll表示逻辑与,即第二个参数事件全部发送才会执行否则等待,第四个参数表示永久等待,打印的flags表示事件数,如果逻辑或则打印1,任意一个事件发生即可触发,如果是逻辑与,参数第二个有几个事件flags就是几,几个事件同时发生才能触发。
5.互斥锁
5.1.基本概念
5.2.运作机制
5.3.API接口函数
5.4.代码实例
5.5.代码讲解
库一样
创建三个不同优先级的任务,并创建互斥锁
三个不同优先级任务函数
一开始高优先级与中优先级延时1s进入阻塞态,低优先级获取互斥锁打印成功,期间中优先级打印三次任务执行(因为没有互斥锁操作,相当于独立出来了),之后低优先级释放互斥锁,高优先级获取,中优先级打印三次后,高优先级释放,低优先级获取,循环往复。
当互斥锁创建后再删除,获取互斥锁的函数都无法执行,被卡在获取那一步,提示获取失败,中优先级继续打印。
6.消息队列
6.1.基本概念
6.2.运作机制
6.3.API接口函数使用
6.4.实例代码
6.5.代码讲解
库一样
定义消息队列长度16(节点个数),定义消息队列结构体并创建变量名msg,定义消息队列id
创建消息队列,大小100,参数NULL,并创建两个任务
消息队列相关函数
第一个发送函数,定义一个变量num,消息队列文字你好。。。,将num赋值给消息队列idx,发送,每发送一次num加一,进入阻塞态1s。
第二个接收函数,status用来判断函数是否执行成功,定义一个count用来记录消息队列内消息数(接收减一,发送加一),如果消息数等于定义的消息队列长度,删除消息队列。一开始消息发送一个,idx是0,发送的时候没加,count为1(一个消息)。之后每三秒函数1执行三次发送三个消息,函数2接收一次,相当于每三秒count加2,但由于先进先出原则,获取的idx每次加一(以为不会跳着获取,消息加2是往后面加,取消息时是从头取,依次是0,1,2。。。)