基于Tricore架构的RTThread多核实现

描述

在《基于Hightec+TC375TP的RT-Thread移植详解》一文中,基于Tricore实现了单核RTThread的移植。最近,花了些时间完成遗留的任务:基于Tricore的多核移植。目前,多数项目中的单片机都具备多核,多核单片机似乎已经是项目的标配。如果搞汽车电子,不理解OS(Operating System),似乎感觉少了什么,就好像吃面不吃蒜的感觉。对于多核,又分为同构(homogeneous)多核和异构(heterogeneous)多核。
  • 同构(homogeneous)多核:单片机中,多个Core的结构相同,各个Core用的指令集相同。
  • 异构(heterogeneous)多核单片机中,多个Core的结构不同,不同的Core架构,使用不同的指令集。

本文基于TC397+Tasking实现SMP(Symmetric Multi-Processing,对称多处理),这里的多核属于同构多核。相对于SMP,AMP(Asymmetric Multi-Processing,非对称多处理)主要用于异构多核处理。

本文,主要记录RTThread多核实现过程中的"雷区"。

1、RTThread多核实现细节

(一)各Core实现硬件初始化

由于各个Core所使用的硬件资源不同,因此,各个Core在初始化时,需要实现对应的外设。eg:提供心跳的系统定时器(System Timer),本文Core1的外设初始化在Core1_init()中完成。从核除了初始化自身的硬件以外,还需要调用rt_system_scheduler_start()接口启动调度表,代码示意如下所示:

RT-Thread

提示:上述代码中,从核(Core1)初始化了一个线程。当然,在主核(Core0)完成所有核的线程初始化也可以。

(二)任务初始化

在Tricore架构中,虽然不同Core使用的CSA(Context Save Areas)不同,但是,线程Thread(等同Task)的初始化可以在主核中完成,之后通过rt_thread_control()接口,为线程静态分配控制的Core,eg:分配Core1调度led_thread_thread线程,代码示意如下:

RT-Thread

(三)线程间任务切换

如果不是systick触发的线程切换,即:由于线程状态挂起触发的线程切换时,需要判断线程是否上锁,如果已经解锁,则需要解锁之后在进行线程切换,避免死锁。多核rt_hw_context_switch()的接口实现如下所示:

RT-Thread

(四)中断切换标志置位时机

每次程序进入系统心跳中断服务例程时,需要先置位中断切换标志Flag,完成系统心跳的累加后复位。注意:不同于单核处理,多核处理中,此处还需要对中断切换进行处理,即:判断程序是否超时,如果超时,则对应的pcpu->irq_switch_flag置位,需要进行中断线程切换处理。代码实现如下所示:

RT-Thread

(五)线程上锁/解锁操作

上锁处理,对应代码实现如下所示:

RT-Thread

解释:__cmpswapw((address), ((unsigned long)value), (condition) ),上锁处理时,如果address处的值==condition,则将value值赋写到address位置。在Tricore架构中,__cmpswapw操作是原子操作,可以避免多核的并行访问。

解锁处理,对应的代码实现如下所示:

RT-Thread

注意:上锁/解锁必须成对出现。如上代码中,上锁/解锁处理中都有一个while操作,这也是为什么过多的spinlock会影响CPU效率的原因。
(六)主核(Core0)与从核(Core1)同步时机
主核(Core0)与从核(Core1同步时机可以选择在各自硬件初始化完成后进行,否则,从核可能会访问到空地址,进而进入Trap。完成同步后,主/从核进行线程操作,代码示意如下:

RT-Thread

(七)空闲线程时间片设置
本文修改了空闲线程的默认时间片,由默认的32tick修改为10个tick,目的:保证调度的准确性。为什么这样改?暂时未细查,留给未来。

RT-Thread

(八)确认线程是否在目标Core运行

如果想确认线程是否在目标Core运行,在目标线程设置一个断点(Breakpoint)即可,如下所示:

RT-Thread

2、RTThread任务调度

本文Core0创建了一个主线程main_thread(周期:50ms),一个空闲线程idle[0];Core1创建了两个线程led_thread_thread(周期:20ms)、core1_thread_1(周期:30ms),以及一个空闲线程idle[1]。
(一)main_thread运行周期

RT-Thread

(二)led_thread_thread运行周期

RT-Thread

(三)core1_thread_1运行周期

RT-Thread

提示:本文所有线程,静态创建。

2、源码链接

多核与单核的切换,在rtconfig.h文件中,使能或者关闭宏RT_USING_SMP即可打开/禁用SMP。

本文的RTThread中,启用了2个Core(主核Core0,一个从核Core1),如果需要启用更多的从核,可以在本文的基础上打开其余从核,其余从核的处理与Core1类似。

受限于时间和我的水平,本文在零零碎碎的时间里整理完,实现未必最优。而且,我并未严格的按照RTThread的架构处理,写的稍微有些随心所欲。大家可以基于我的工程进行调试和二次开发,以便于达到理解OS内核、任务切换等相关知识。

源码链接地址如下:

https://github.com/Kaixinguo2021/Tasking_TC397_MultiCore_RTThread.git

往期精彩回顾




Autosar往期精彩文章汇总:1~70
Autosar往期精彩文章汇总:71~100
Autosar往期精彩文章汇总:101~150

Autosar往期精彩文章汇总:151~200

Autosar往期精彩文章汇总:201~251

CAN通信:Busoff问题知多少

NVM基础:解读"切页"的头部信息

诊断基础:Event内存管理

Autosar通信模块COM:Update-Bits详解

Lin总线基础:为什么Master节点需要外接上拉电阻


 

点击下方关注,一起聊聊Autosar/嵌入式,如果需要,联系作者进群,给你更专业的解答


———————End——————

RT-Thread
RT-Thread
点击阅读原文报名


原文标题:基于Tricore架构的RTThread多核实现

文章出处:【微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分