在ETAS的AUTOSAR中实现Spinlock的设计

描述

现在的车载控制器,多核的MCU用的是越来越多了,对于不同核之间的共享数据保护,也是必须的,其中Spinlock就是常用的一种。

01.

Spinlock介绍

Spinlock也即自旋锁,是一种轻量级的多核间的数据同步机制。一个任务想要访问被Spinlock保护的共享资源,必须先得到锁,在访问完共享资源后释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有持有者, 那么需要自旋等待该锁的保持者释放了锁。

在ETAS的AUTOSAR中,实现Spinlock的两个基本操作获取锁xx_GetLockInternal()和释放锁xx_ReleaseLockInternal()。

对于获取锁接口,其内部的实现原理如下:

第一步先判断是哪个核上的任务正在使用xx_GetLockInternal();

判断锁是否已经被同当前核获取过但没有释放,如果是的话,就进行锁嵌套累加, 继续执行代码,如果没有被当前核获取过再进行下一步判断;

挂起正在使用xx_GetLockInternal()的当前核的中断,确保当前任务不被切换,也就是说不被高优先级任务或者中断任务打断;

测试锁的状态,该才做必须以原子操作访问Spinlock的锁标志。

如果锁状态被本核占用则进行锁嵌套,如果是其他核占用则首先释放该核中断, 然后重复执行上面两步测试锁的状态,直到其他核释放了锁。如果锁状态为空闲, 则设置其为占用状态,这就成功地抢占了锁。

对于释放锁接口,其内部的实现原理如下:

首先判断是哪个核上的线程正在使用xx_ReleaseLockInternal();

判断当前锁是否被该核占用,如果不是说明接口调用不匹配则复位,如果是则进行 下一步的判断;

判断锁是否被本核嵌套, 如果是则嵌套次数减减, 如果没有则清除锁的状态;

释放该核的中断。

02.

Spinlock使用原则

所有临界区代码都需要加锁保护,否则就达不到保护效果。也就是,访问共享资源的多个任务需要协同工作共同加锁才能保证不出错。在实际写代码时,有时会忘掉这个,导致出现各种稀奇古怪的问题,并且很难排查。

Spinlock保护的代码执行时间要尽量短, 因为临界区太大,持有时间太长,其他任务可能面临长时间等待,降低了系统性能。

Spinlock 所保护的代码在执行过程中不能睡眠, 任务在持有自旋锁时如果进入 Sleep状态,则可能导致死锁。








审核编辑:刘清

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

全部0条评论

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

×
20
完善资料,
赚取积分