1.理解:任务切换,用堆栈指针SP保存即将要切换的任务的前后文,然后是用PendSV来执行这些操作的;由于是基于优先级的调度策略,所以每次“心跳”都会看有没有优先级更高的出现,如果有就用PendSV进行上下文切换。
2.编写部分:
①每个任务自己的属性统称为TCB任务控制块。
②任务就绪表有设置优先级(设置的时候变量或上优先级的变量让某个位数等于1),从任务就绪表中删除(删除时用与来得等于0),
寻找最高优先级(用for轮询,小于就一直轮,直到大于最高的同时取反的时候确定存在即定为找出最高优先级),
这些都由一个变量-OSRDYTbl中的32位各位中的0或1来决定,第31位优先级最低。
③系统初始化:心跳产生(system)->栈空间向下生产(手动指定加起来)->任务创建(R4-R11寄存器都初始化),
同时运行空闲任务->寻找最高优先级任务并获得赋予给当前任务->然后专门最高优先级的制作pcb p指向当前任务的栈顶->启动内核(这个过程是由汇编组成的)
To-汇编部分:手动PSP入栈。R4-R11入栈。入栈后要把p_TCB_Cur指向第一个结构体成员,入了栈后进行这个操作也方便之后的出栈。
④构建白天黑夜(系统时钟):滴答定时器作系统时钟-注意是倒推减少这个思想-装载值可以发现:
当nus=1时,fac_us=SystemCoreClock/8000000。SystemCoreClock为72M,则fac_us=9。
即装载值为9。减少一个数所需要的时间:即为systick的频率,也就是9MHz,转换为时间为
延迟时间:9*1/9MHz=1us (Hz对应s,KHz对应ms,MHz对应us)
故这个也是,就是把1/9改成别的所需要的延迟,随后就设置进入中断时间
(补充:uboot启动的时候,需要设置时钟分频,分频的目的就是产生三种时钟:PCLK、FCLK和HCLK,PCLK供APB总线使用,
HCLK供AHB总线使用,FCLK则供cpu使用)
⑤进入中断之后,进行任务调度,也就是查看是否就绪表中有最高优先级的任务没有安排到当前任务
⑥编写延时函数:设置TCB结构体中属于延时的成员的数值,随后引发调度即可
⑦下载例程(链接:http://t.csdnimg.cn/sMSMP)
①理解:一块内存可以看成一个大数组,也就是内存池,然后管理这个可以申请一个小数组也就是内存管理表来管理大的,
表中对应字节为0则内存空,为1则有数据。
②过程:要返回需要的是哪部分内存,据此返回此块内存的地址(基地址➕偏移量),然后再把对应表中的顺序置为1,
随后就是指针对应到被置1的位置以此来使用,这就是申请内存的过程。申请了之后用完要释放,也就是对应的顺序字节置0即可,然后也要传回要申请一个多大的内存。
③具体编写:
定义变量,申请用多大内存管理表(1:8–每八个字节对应管理表的一个字节)管理一个多大的内存,
均匀切开后每一次只能申请多少块内存。同时内存池要用8字节对齐(__align(8))。
定义好了之后要在程序一开始初始化时置管理表的项全部为0(for循环全部MMTS的数量使mmt[i]=0)
随后申请的时候要看需要多大内存,同时大for遍历管理表里面的所有序号,
小for找哪块内存刚好有一样大或者大一点的内存是为0,有就标记下来占用为1。
随后通过此函数是指针函数返回一个获取到的内存末地址(return 这个末值),失败的话返回0x00000000L
最后就是内存释放了,直接把内存管理表对应序号置为0就行。(void*指的是可以指向任意类型返回,所以是白搭)
①理解:这个是在多线程环境下使用的一种