前言
通过<
问题:如何理解Spinlok自旋锁中的”自旋“的含义?
缩略词
简写 | 全称 |
PSW | Program State Word |
注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!
正文
LDL和STC指令可用于获取原子读-写操作,用于多核系统对内存更新进行精确处理。LDL和STC指令的操作方式如下。
每个CPU只能创建一个Link(LLbit)。该链接包含关于创建它的地址的信息,并根据STC指令在该地址是否成功或失败以及该链接是否丢失来进行接下来的控制。该链接还包括创建链接时的数据大小信息,因此,数据大小与创建链接的LDL指令不同的任何STC指令总是会失败,STC指令失败则该链接被删除。
每个CPU都能够生成一个到Local RAM和cluster RAM的链接。
在目标RAM上执行LDL指令导致链接地址被注册,同时设置链接标志,并响应该指令读取生成链接。
(a)每个CPU的Local RAM
(b)Cluster RAM
每个CPU都能够生成一个到(a)或(b)的链接。
在生成Link之后,存储将只响应执行与生成的链路对应的STC指令而进行,也就说说该存储地址只能通过STC指令写入。
如果链路丢失,即使处理相应地址的STC指令,存储也不会继续。当处理与链接不对应的STC指令时,也不会继续存储。
个人理解:Link是一个抽象概念,通过LDL指令能够创建一个link,且每个CPU只能创建一个Link,通过STC指令能改写CPU Link的RAM的值。
如果满足以下条件,则判定STC指令为与该链路对应的地址:
生成链接的LDL指令的地址和大小与STC指令的地址和大小相匹配。
当满足某些事件或地址条件时,链接将丢失。表1显示了Link loss情况。如果满足此表中所示的任何条件,则一个链接就会丢失。
Table 1 Link Loss Conditions
Note: 在Local RAM中,如果执行了除STC/CAXI指令以外的存储指令,则链接并不总是丢失。因此,触使Link Loss的指令程序流是可以不需要的。例如,在接下来的示例代码中,在使用LDL指令读取锁变量后,只有在没有锁的情况下才执行STC指令,如果锁已经存在(Link已经建立)则通过Lock Release对应的Link Loss程序流就是不需要的。也就是说,LDL指令Link成功,STC指令存储成功(创建一个Lock),之后的ST等存储指令用于Link Loss才是有意义的。也就是只有GetSpinlock成功之后才能ReleaseSpinlock.
通过使用LDL.W和STC.W指令执行的自旋锁的示例代码如下所示。
一行一行的来分析这段汇编代码:
MOV lock_adr, r20 //lock_adr这个地址值赋值给r20寄存器,lock_adr可以理解为一个存在于RAM的全局变量的地址。
LDL.W [r20], r21 //以原子操作的方式加载r20寄存器保存的地址所在的值给r21寄存器。这个指令执行完后,r20存储lock_adr地址值(全局变量的地址),r21保存了lock_adr地址指向的具体变量值(全局变量的值)。Link Generation.
CMP r0, r21 //r0寄存器中值与r21寄存器中的值进行比较。
Note 1: r0是Zero寄存器,其值永远为0.
Note 2: CMP指令的结果在程序状态字寄存器的PSW.Z bit上体现,比较的两个值如果相等则PSW.Z =1;反之,比较的两个值不相等,则PSW.Z = 0.
BNZ lock_wait //如果上一次的cmp结果不为0,则跳转到lock_wait标识符地址处往下执行。
MOV 1, r21 //将1赋值给r21寄存器。r21寄存器中保存的值为1.
STC.W r21, [r20] //将r21寄存器保存的值(1)赋值给r20保存的地址指向的变量。Success in storing.
CMP r0, r21 //比较r0(always retains 0)和r21寄存器中保存的值(也就是比较0和1)。
BNZ lock_success //如果上一次的cmp结果不为0,则跳转到lock_success标识符地址处往下执行。
Lock_wait: SNOOZE
Note: SNOOZE指令是一种在自旋锁期间减少总线带宽使用的指令。该指令完成后,CPU核心进入临时停止状态,以限制后续指令的执行。程序员可以通过将此指令插入到一个自旋锁循环中,从而避免由于短期重复锁定过程而导致的不必要的总线带宽的使用。
BR Lock //无条件跳转到Lock标识符处
Lock_success: //一个标识符,运行到这里表明get spinlock成功,继续往下执行。
ST.W r0, 0[r21] //王r21寄存器保存的地址值指向的变量写入0值。Release spinlock.
准备获取Spinlock的时候,外部就是一个While循环,直到成功获取到Spinlock,否则就会“自旋”。
释放Spinlock对应的C代码,只需将标识Spinlock的全局变量赋值为0即可(对应ST.W r0, 0[r21]的汇编代码)。
本文详细分析了Spinlock在RH850U2A芯片平台上的底层实现,着重需要理解RH850U2A芯片架构中的Link概念。Spinlock对应的底层两个特殊的汇编指令:LDL.W和STC.W. 在C语言环境下调用GetSpinlock()的具体实现也就是调用OS_LDLW()和STC_STCW()。值得注意的是,Spinlock的底层实现和具体芯片特性相关,其他芯片平台(比如Tricore芯片)的底层具体实现可能就不一样了,需要具体分析。
问题:如何理解Spinlok自旋锁中的”自旋“的含义?
答:“自旋”对应底层的SNOOZE指令。当前CPU(Core x)执行LDL.W没有建立Link后,CPU执行SNOOZE指令暂停一个机器周期,随后再次尝试去执行LDL.W指令,直到建立Link成功(其他CPU释放Spinlock),这个过程对应“自旋”的含义。
参考文档:
1.RH850/U2A-EVA Group: User’s Manual: Hardware
2.RH850G4MH: User’s Manual: Software
3.MULTI: Building Applications for Embedded V850 and RH850
End
「汽车电子嵌入式在CSDN上同步推出AUTOSAR精进之路专栏,本专栏每个模块完全按实际项目中开发及维护过程来详细介绍。模块核心概念介绍、实际需求描述、实际工程配置、特殊需求介绍及背后原理、实际工程使用经验总结。目的是让读者看完每一个章节后能理解原理后根据需求完成一个模块的配置或者解决一个问题。」
点击文章最后左下角的阅读原文可以获取更多信息
或者复制如下链接到浏览器获取更多信息
https://blog.csdn.net/qq_36056498/article/details/132125693
文末福利
2.为便于技术交流,创建了汽车电子嵌入式技术交流群,可尽情探讨AP,CP,DDS,SOME/IP等前沿热点话题,后台回复“加群”即可加入;
注:本文引用了一些第三方工具和文档,若有侵权,请联系作者删除!
推荐阅读
汽车电子嵌入式精彩文章汇总第一期:20210530-20230703
AUTOSAR 架构下EcuM唤醒源事件详解
AUTOSAR架构下NVM Block连续写及Default Value问题分析
AUTOSAR架构下NvM模块详细分析
AUTOSAR架构下报文掉线超时不上报问题分析
Classic Autosar下的以太网通讯架构概览
通信中间件Someip服务化通信
AUTOSAR架构下Fee详细分析
TC37x芯片FLASH基本概念介绍
AUTOSAR架构下Fls详细分析
TC3xx芯片DMU介绍
TC3xx芯片MPU介绍
TC3xx芯片的Trap详解
AUTOSAR架构下的OS错误处理
AUTOSAR架构下QM Application如何访问ASIL Application
AUTOSAR架构下多核启动
TC3xx芯片的Trap详解(二)
AUTOSAR架构下多核Shutdown
AUTOSAR架构下多核通信
End
欢迎点赞,关注,转发,在看,您的每一次鼓励,都是我最大的动力!
汽车电子嵌入式
微信扫描二维码,关注我的公众号