朱工

早年从事单片机、实时控制系统产品设计及编程。目前耄耋之年开始学习AI技术。

利用中断或异常实现协程多任务的切换

1
阅读(4342)


利用中断或异常实现协程多任务的切换

-- 微控制器中基于协程的实时协作多任务方法 (5)


  在以往用汇编编程时,我有时借用中断实现协程多任务的切换,即借用中断完成协程的YIELD。这种方法也可用于C与汇编混合编程实现无标号切换。

  前面说到,用CALL指令可以取得后一指令的地址而无须使用标号。除此之外,另一个不用标号而可以取得后一指令的地址就是中断;对ARM而言,就是异常(Exceptions)。

  例如,在8051的具体应用中,我们往往不会用完所有的中断,我们可以借用空置的中断来取得后一指令的地址。

  设某中断INTn被借用,我们可以用

    SETB INTn_flag ;中断标志往往可以用软件来置位

来取代前面的

    CALL yield ;

而用前面yield的汇编指令作为INTn的中断响应。一进入中断,“后一指令的地址”就已经在堆栈中。

  具体变化多而灵活,无法在此一一罗列汇编代码。熟悉汇编的工程师自然可以自行写出混合编程的代码了。

  利用中断实现协程多任务切换,带来一个好处。就是,我们可以在一定程度上掌握协程多任务切换的优先权。甚至可以选择最高优先权,在与抢占式方法联合使用时,协程切换时的优先权可以高于任一抢占式的优先权。


  对应于ARM Cortex-M,自然是“异常”了。ARM Cortex-M的系统服务调用指令SVC(软中断指令)很适合作此运用。

  在这之前,我必须先说一下Cortex-M的YIELD指令。

  在ARM Cortex-M的具体产品问世后,我觉得,在产品设计中MCU的选择从8051升级到Cortex-M的时机到了。因此,一些以前在8051或其他MCU中使用的成功方法,也该转移到Cortex-M。

  其中,我考虑上述通过中断切换协程多任务的方法,该如何移植到Cortex-M。首先,吸引我的是YIELD指令。数据手册中对它的描述是:

YIELD indicates to the hardware that the current thread is performing a task, for example a spinlock, that can be swapped out. Hardware can use this hint to suspend and resume threads in a multithreading system.

YIELD 可告知硬件有线程正在执行任务,例如可换出的自旋锁。 硬件可使用此提示在多线程系统中暂挂并恢复执行线程。

  但是找不到YIELD是如何执行的。直到在姚文祥(Joseph Yiu)的《Cortex_M3权威指南》看到YIELD是一条未支持的hint指令。

  为了搞清原委,2011年1月在圣塔克拉拉会展中心的RTECC(Real-Time & Embedded Computing Conference)展会上,我问ARM展台的产品经理Robert Boys先生:为什么Cortex-M3不支持YIELD指令。他说:没有这回事(it is not true)。

  回家后,我找到了姚文祥的原文,当晚给Bob Boys发了一份邮件,并告知,我想借用YIELD实现实时多任务的切换,而不借助于RTOS。

  Robert Boys把邮件转给了ARM权威姚文祥,姚先生第二天给我回了邮件,说明YIELD指令是为具有“硬件多线程处理能力”的处理器而预设的。目前还没有这样的处理器,所以等效于NOP。有兴趣的话,可看一下附件:姚文祥(Joseph Yiu)关于YIELD指令的邮件.pdf

  这等于透露了一个消息,预计会出现具有“硬件多线程处理能力”的处理器,而无需软件介入了。

  Joseph 还说到,可用Cortex-M的SVC来实现这种切换。这与我前面的想法一致,所以我回应说:我知道怎么办了。


  用Cortex-M的SVC实现协程多任务的切换。

  实际上,看了我前面所介绍的混合编程实现协程多任务的切换方法;以及知道进入SVC异常服务程序,可从栈中保存的PC取得“后一指令的地址”这一招;掌握汇编的人,都该“知道怎么办了”。 使用SVC,可能要多花费几条指令。

  SVC #immd指令后面的立即数,可分别指示way_out、yield函数等等;以及传递ret_code等等。不过,SVC往往还承担其他功能调用,如何协调,只能各显神通。大家可自由发挥,海阔天空,无法一一穷尽。再写,就显得多余和啰嗦了。

  顺便说说,某些培训教材,说的是针对Cortex-M0,关于SVC调用,抄的是《Cortex_M3权威指南》中Cortex-M3关于SVC调用的指令例子。其中,好多条M3的指令在Cortex-M0中是行不通的,千万要注意。最好是去看看Joseph Yiu的《The Definitive Guide to the ARM Cortex-M0》。

  只可惜,已经告别产品设计了,不能亲手将这种用于ARM Cortex-M的实施方法,用在一个具体的应用产品中去。


===

 fy_zhu

 2013-02-26 SV_CA