gd32f303 设计中断优先级_和廖老师一起起飞的嵌入式系统设计

本文详细介绍了GD32F303微控制器中中断优先级的设计与任务调度。内容涵盖任务管理、中断保护与恢复、硬件中断处理、任务调度算法,以及在μcOS操作系统中的应用。文中通过对任务控制块(TCB)的分析,阐述了任务创建、状态管理和中断响应机制,同时讨论了任务与进程的区别,并简要提及了实时操作系统中的调度算法和资源访问同步问题。
摘要由CSDN通过智能技术生成

嵌入式系统设计要结课了,这课的氛围实属猛的一,学到了很多东西,非常感谢廖老师的教会我们来复习一波

国际班的朋友们,拿笔记复习的时候记得顺手点个赞!!!

7dbd26bb9dda39ac49acf4c27a6fc95d.png
看到这个链接你是否有一丝恐慌

嵌入式系统的四个主要讲点

  • 任务管理(调度)
  • 同步,信号量,交流(这部分讲的比较少)
  • 内存管理 基本没怎么讲
  • 中断 时间管理(对于事件的处理方法)

task任务

  • 内核的功能是什么?调度让不同的程序分时共享CPU从而达到近似的并行
  • 内核如何调度?给每一个执行程序分配一个task
  • task是什么?一个可以执行的软件,有代码 数据 计算资源 操作系统当中举的例子是一个计算机科学家要做蛋糕,食谱是代码,剩下的准备材料和做的过程就是task, 从代码的角度来说,task是一个无限循环的void函数,他会在内存当中不断地被调度,比如QQ一直在后台运行,直到你强制退出。 task是一个逻辑上的存在,并且是动态存在的,根据冯诺依曼体系,我们可以看出代码是存 储执行的,即静态的,这也是task和code的主要区别 A task is an executable software entity specialized to perform a special action which includes sequential code and relative data and computer resource A task is an infinite loop function. it looks just like any other C function containing a return type and an argument but it must return. The return type of a task must always be declared to be void
  • task的特点是什么?同步 异步 动态性(不是重点)

如何描述一个task?

  1. 上述定义的描述方法
  2. 代码描述

4f178cad1c9912917e53bc5e39a9d842.png

把内部的固定执行函数来看,task就是一个执行的函数,一个无限循环的void函数

  • 为什么是无限循环? 因为一个任务要在系统当中不断地调度,而不是用一次就废了
  • 为什么返回void,task是独立存在的,不需要为其他task做什么(即便需要也是共享或者通信)

下面我们通过代码进程块来了解一下task进程块在计算机当中的使用(调度)方法。

f5dd91300086dbf3af47c20f686b3188.png

c3a563feeb22eb339c9bca27b9abe629.png

上面两段代码分别是两个task的代码。在循环外的代码主要目的是设置时钟节拍(晶体振荡器),剩下几个是寻找对应的引脚来控制指定引脚灯的开关(初始化)

A控制开灯,B控制关灯。

在μcOS操作系统当中维护着几个队列

  1. 就绪队列:等待执行的task,等待现在正在执行的task退出然后即可进入
  2. 延迟队列:延时的时间节拍不为0,暂时不能执行

为了防止CPU空转,在任务管理器当中设置一个空任务IDLE,简单讲就是占着茅坑不拉屎,等着别人去占用他。

有了这些基础知识,我们来看这两个任务如何工作的8

  • 什么时候这些task被创建?操作系统当中有两种模式:核模式和运行模式(这个词我给搞忘了)只有在核模式下才可以创建任务。一般情况下,时间中断(也同样是个task,完成调度的任务)会打断运行进入核模式,创建任务
  • 在哪被创建?在μcOS当中,为了保证时间复杂度的确定性,我们没有虚拟内存,都在内存当中被创建,放入就绪队列当中。
  • 如何启动任务执行? 时间中断的task会在就绪队列当中选择优先级最高的task出队执行

在第一个时间片当中,A从就绪队列当中出队,执行,OSTimeDLy让他进入延迟队列当中,然后IDLE任务进入。

第一个时间片结束,时间中断任务进入,把所有延迟队列当中内容OSTimeDLy减1,选择就绪队列当中第二个任务执行。

二到九时间片都是IDLE空转,直到第10个时间片的时候,A的OSTimeDLy变为0,移入就绪队列当中再次执行。(我觉得讲清楚了)

所以灯是10个时间片一闪,再亮10个时间片的循环 一个时间片可以完成多个任务 上一个结束就会启动新的调度

task 和 process的区别是什么

1f888a8d329fcd21a4efe429ca4d8c19.png

4786ad405e7e3b73725af8b3daed4c0d.png

我们还是通过上面的例子来说,上面两个例子两次的输出都是什么?

1 还是 2?

答案是task是1 process是2

task某种程度上可以理解为线程,他不像进程一样会产生阻塞。

task的控制核心->TCB描述任务

前面我们提到的task都是一个大的概念,这里我们通过细节的分析这个数据结构来掌握任务的管控情况。

除去额外的成员,TCB的组织基本如下(后面是占用字节数目的大小)

OS_STK *OSTCBStkPtr 4(堆栈指针) ptos

Os_tcb* OSTCBNext 4(双向链表的下一个)

Os_tcb* OSTCBPrev 4 (上一个)

Unsigned short OSTCBDly 2 (时延) 0

Unsigned char OSTCBStat 1 (状态) OS_STAT_RDY

Unsigned char OSTCBPrio 1 (优先级) (INT8U)prio

Unsigned char OSTCBX 1

Unsigned char OSTCBY 1

Unsigned char OSTCBBitX 1

Unsigned char OSTCBBitY 1

后面四个我们逐一来介绍

OSTCBNext 和 OSTCBPrev

这两个成员揭示了任务的存储方式即双向链表

为了方便,我们在boot初始化的时候就创建所有的TCB,64个(分别对应64个优先级)前两个是系统的优先级(用于处理紧急事件,比如掉电),后两个就是IDLE和系统监测(比如CPU温度)

所有的TCB都通过一个双向链表相连,称为TCBFreeList。如果TCB被某个对应优先级的task占用,就从Freelist到TCBList当中,代表正在使用的TCB。

显而易见,双向链表虽然能自适应的调整空间,但是查询时很慢的,所有系统当中还维护一个优先级队列(实质上是一个数组) 数组下标和优先级一一对应。

OSTCBStat

如果一个系统想要运行起来,就必须有一个完整的没有死状态的状态循环表,μcOS如下

81de9d37dc283228208d9348ac1711a0.png

这里可以看到我们之前提到的timetick(延迟队列到ready队列)还有吧啦吧啦一丢就不多说了,重点在于标识状态

OSTimeTick就是我们之前对应的时间中断task,每一次发出信号

OSTCBX OSTCBY OSTCBBitX OSTCBBitY

ptcb->OSTCBY=prio>>3 向右移动三位

ptcb->OSTCBBitY=OSMapTBI[ptcb->OSTCBY] 对应表当中的映射

ptcb->OSTCBX=prio & 0x07 对应低三位的与运算

ptcb->OSTCBBitX = OSMapTbpptcb->OSTCBX]

806e85b6ea8368a057b9691b367664ac.png

为了加速对最高优先级的查询过程,系统当中设计了一个数据结构标定任务是否被占用

这个方阵当中,如果被占用则为1,未占用则为0,(这里不是二维数组,而是一个数的不同位!!!)

PriorityReadyTable有8个数字,每个表示这一行当中的8个优先级是否有被占用

PriorityReadyGroup只有1个,8位,如果PriorityReadyTable的任意一项全部为0,则置0,否则为1.即检测该行是否有优先级被占用。

OSTCBX和OSTCBY分别对应着prio的高三位和低三位,也就分别对应着这个类似二维数组的两个索引。我们可以通过X和Y进行访问当前节点

OSTCBBitX OSTCBBitY的内容出现的目的是为了快速访问,也就是变成掩码的形式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值