你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

AliOS 任务上下文切换原理分析

[复制链接]
STMCU-管管 发布时间:2018-9-29 16:29
前言
$ T& C4 Q8 f# b) e% Y/ @6 ]% r2 y9 @2 v$ l( M: x! |: b
一般来讲,MCU 相关的操作系统都具有最基本的多任务管理功能。多任务管理功能包含任务的上下文切换,因其涉及到特定寄存器的操作,都是使用汇编代码开发,相应代码由软件厂商提供。
( M8 @, \" n- G  D8 B7 I3 T* k5 a: N* `
在 STM32 技术人员的实际支持工作中,例如 IDE 移植,可能需要读懂和修改这些汇编代码。本文就是从这一需求出发,描述AliOS 操作系统里的任务上下文切换的基本原理。读者在明白了上下文切换原理后,去阅读和修改任何 MCU 操作系统的关于任务上下文切换的汇编代码就不会是个难题。本文包含的代码引用基于 STM32F4(ARM Cortex-M4 内核)芯片上的实现。 / B2 q' d* \0 G% O- b( ]9 I
5 w2 w: ?4 H3 Y3 ]# p
上下文切换的源动力 2 t, k+ g( K9 f  O1 I
' Z$ [3 U- a  C
带操作系统的应用程序,上下文切换的逻辑在 PendSV 中断处理函数中完成。 为什么是 PendSV 中断,而不是其它的中断? ARM技术文档里提到,PendSV 设计为上下文切换服务的中断请求,优先级最低。任务切换的策略可以根据时间片和优先级来制定。切换时机可由系统滴答时钟(SysTick)触发,或者由操作系统根据已有策略来触发 PendSV 中断。 3 }2 O: J) l7 R3 a% s+ K* A1 j! @

" n) s3 C' f5 l# \5 ]  \以 AliOS 的系统时钟中断处理函数为例,则可以看到有如下代码: # r# a9 N6 U% L! ]/ W8 q
/ Z1 o! Y+ r) Q( }7 P
QQ截图20180929161823.png
- H$ w7 x. Y7 S, o
在 AliOS 中有很多地方,根据系统的需要,还可直接调用 cpu_task_switch 来触发 PendSV 中断。这一部分是纯软件的设 计,不再列举。   u9 b& Y& t# t! Z

, H- B! Z) G9 M. J
QQ截图20180929161832.png
  @+ K: N+ n2 ^
上下文切换 3 K1 i7 ?" T/ U' M* }) _

1 D3 U  f5 f: M5 U; \- U上下文切换的汇编代码实现的功能就是把前一个与当前任务相关的寄存器信息进行压栈保存,比如当前栈指针、TCB 信息等,把将要运行的新任务的栈内信息恢复到对应寄存器中为新任务的执行做好准备。这里的上下文就是指各个寄存器信息。
; r7 Q( M: |& H% j' S# w
' [( x! B5 D0 f! B寄存器分类
% B* f4 ?3 c& ~4 g! z. e% f
  • 通用寄存器) D2 I& P0 M7 j  v# r/ M2 X) d

$ D, x( e4 ~/ Z0 t8 J    R0-R12 是 32 位通用寄存器。 * k! g- E) |8 x% @
  • 堆栈指针 SP
    . B- N8 @" {; ~; l( a8 a& ]& [
! y1 V$ ~# S; m
   R13 是堆栈指针寄存器。堆栈分为复位后缺省使用的主堆栈(由 MSP 指向)以及用户应用程序使用的任务堆栈(由PSP 指向)。可以通过控制寄存器控制当前正在使用的堆栈。
" j- H  w' ~1 D3 _- {/ N" b2 P) F5 \
  • 链接寄存器 LR
    ! g: [6 g* X/ X! h  c
& D: T0 j% c- {  H/ x, Z$ o2 |: @
   R14 是链接寄存器,用在函数或者异常/中断返回。 6 \' d0 Q" S! l6 K8 X2 T! P
  • 程序计数器 PC8 m3 U- S6 i. K% }0 h! _

& I2 {# D3 w2 r7 }   R15 是程序计数器。它指向当前运行的指令地址。 & Y: s8 x* ]1 W& ~& k/ m, C6 V
  • 程序状态寄存器 xPSR
    1 Y. A, o* p3 B( z% i1 [
6 Q7 j5 {" W3 g6 A  {7 ]& r
   程序状态寄存器包含三个寄存器:应用程序状态寄存器 APSR, 中断程序状态寄存器 IPSR 和执行程序状态寄存器EPSR。APSR 包含上一条指令执行后的条件标志,IPSR 包含有中断号,EPSR 包含有被中断指令的待执行寄存器信息,诸如 LDM、STM、PUSH、POP,或 IF-THEN 条件指令的信息以及当前是否运行在 Thumb 状态。 - v, k+ S( i7 {7 Z& R5 q7 h9 L
  • 优先级掩码寄存器 PRIMASK(1 位)
    7 N) Z3 g4 \& V% x7 f
$ S: ~% C5 {& x) C$ V' u8 L% L- t! f
   PRIMASK 置 1 后,系统阻止除 NMI 和 hard fault 外的所有异常/中断。 0 K& J/ y- o) N$ W
  • 故障掩码寄存器 FAULTMASK(1 位)" w1 w( m; b9 t6 Y5 E: I) T3 d

) o* R. D* h+ y" U2 I7 O. Z   FAULTMASK 置 1 后,系统阻止除 NMI 外的 所有异常/中断。 ; e; s' M8 T( i' i, J
  • 基线掩码寄存器 BASEPRI(9 位)
    * ^; \$ [+ X& d1 o
. e, z+ n- a# \: ?% ~
   根据在 BASEPRI 中的优先级设置,系统阻止优先级小于等于它的所有异常/中断。  
2 E9 e! P: P& [7 u: B+ ^: D) S  e
  • 控制寄存器 CONTROL- N7 G% a2 ~: S. h/ s3 A- S
: ~, Z- h% R% S3 K" M3 k
   CONTROL 寄存器控制在线程(THREAD)模式下所处的特权级别(特权级还是用户级),以及当前系统使用的堆栈。中断处理(Handler)模式只能处于特权级,总是使用主堆栈(由 MSP 指向)。可以通过读出 SPSEL 位来进行验证。线程(THREAD)模式可以通过 CONTROL 寄存器切换是使用主堆栈(由 MSP 指向),还是任务堆栈(由 PSP 指向)。
+ o6 M* i  U2 j2 `7 q1 I
0 n9 L  }9 S# n硬件管理的寄存器
  ~+ O; T5 B8 D% @+ {$ s! \! v& ?# Y! a+ {
在上下文切换的中断处理中,一部分寄存器由硬件管理。也就是说,在进入 PendSV 中断处理函数时一部分寄存器信息被自 动压栈保存,在退出 PendSV 中断时这些寄存器自动被弹出。 根据 ARM文档,在上下文切换中,不考虑浮点和考虑 32 个单精度或者 16 个双精度浮点寄存器两种情况下,由硬件管理的寄 存器列表分别如下: ; D% X; ^, y8 T" d

. Z) X( F# e" J, G; i) M8 L' ?% r* l7 b3 O" r4 ~/ J
...
# Y3 Y0 g" m! X+ G' t* e7 y; F* U& v, r+ `: L8 V2 t
了解更多,请下载后阅读' h+ D  P! R4 _( I

5 V& l$ o9 M6 e  ], S' X. d) E下载地址1>>                              下载地址2>>                            更多实战经验>>
: y5 L( t8 j6 a/ d+ V3 ]
5 v% O; @$ c) G" u! M5 ?( |
收藏 1 评论0 发布时间:2018-9-29 16:29

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版