打印

ARM系统编程

[复制链接]
楼主: xinzha
手机看帖
扫描二维码
随时随地手机跟帖
81
野猪人| | 2013-1-21 22:59 | 只看该作者 回帖奖励 |倒序浏览
学习一下

使用特权

评论回复
82
rhythm92| | 2013-2-1 14:49 | 只看该作者
mark~

使用特权

评论回复
83
samhost| | 2013-2-1 23:19 | 只看该作者
xuexil,zheshi bucuo

使用特权

评论回复
84
goldsunking| | 2013-2-2 11:05 | 只看该作者
顶,写的不错。非常好。

使用特权

评论回复
85
sfesdm| | 2013-2-27 19:01 | 只看该作者
mark

使用特权

评论回复
86
Andylue| | 2013-2-28 18:40 | 只看该作者
还有更更新吗

使用特权

评论回复
87
xinzha|  楼主 | 2013-2-28 20:26 | 只看该作者
还会有,但是现在实在没时间,生活所迫,还要陪闺女玩,等工作稍微闲点一定要更新。

使用特权

评论回复
88
yuan1089| | 2013-3-3 21:06 | 只看该作者
楼主啊,我现在在学STM32啊,不知道要不要学跑Linux的ARM11。可以加个Q吗,我在读研,576152389

使用特权

评论回复
89
wwhhjj1| | 2013-3-12 21:28 | 只看该作者
好好的帖子

使用特权

评论回复
90
xinzha|  楼主 | 2013-3-12 22:36 | 只看该作者
yuan1089 发表于 2013-3-3 21:06
楼主啊,我现在在学STM32啊,不知道要不要学跑Linux的ARM11。可以加个Q吗,我在读研,576152389 ...

我没有时间上q啊,白天太忙不开IM,晚上回家要跟娃玩。。。,有问题还是站内联系吧。

使用特权

评论回复
91
Seawin龙| | 2013-4-19 09:02 | 只看该作者

使用特权

评论回复
92
coc| | 2013-5-21 22:20 | 只看该作者
感谢楼主的无私奉献!论坛里真正有质量水平的帖子不太多,楼主的是一篇,读之受益良深。本人刚从事arm研究,也欢迎同道的能和我交流探讨(QQ:39158405,注明21ic即可谢谢)

使用特权

评论回复
93
xinzha|  楼主 | 2013-6-19 16:06 | 只看该作者
bug终于收敛了,用了三个月时间完成了个人这些年对驱动的最后一个梦想,同时考了个驾*,再把帮朋友做的一个vlc的小功能弄完,就可以脱身出来干点自己喜欢的事了。
期待尽快完事,回来继续更新。

使用特权

评论回复
94
siuwash| | 2013-8-2 14:30 | 只看该作者
写得真心好

使用特权

评论回复
95
luling5897| | 2013-8-4 23:28 | 只看该作者
刚刚接触ARM,学习了,期待更新!

使用特权

评论回复
96
xinzha|  楼主 | 2013-9-9 21:28 | 只看该作者
本帖最后由 xinzha 于 2013-9-11 22:53 编辑

ARM的信号量机制
信号量的需求来自于多线程或者多核环境中,对于共享资源操作的竞争冒险(race condition)问题,如果有一个资源是多个线程(或者多cpu)共享的,这就需要我们有一种机制保证这个资源的原子性(所谓的原子性就是指针对某一资源的一系列操作不会被其他指令序列干扰,一定会按照既定的流程走下去),以防止多个线程交叉运行造成非一致性甚至是硬件模块无法工作,比如用GPIO模拟IIC通信,在运行到一半的时候被另外一个线程抢走,而这个线程也要去操作IIC,这样就会导致整个时序出错。
原子性是一个相对复杂的概念,简单来说就是你预想的操作不会由于被打断或者插入而造成其他的后果,我们不能说原子性就是操作不会被打断,因为在单就arm来说,目前的机制保证了即使被打断了,但是cpu会马上得知自己没有拿到想要的结果,再去重新尝试。
ARM中的原子性分为单拷贝原子性和多拷贝原子性。
需要满足下列所有条件,一次读写才可以称为是单拷贝原子的:
        任意次对某一操作数的读写之后,该操作数的值为某一次写操作写入的值,而不可能是某几次写操作结果的组合。
        如果一个读指令和一个写指令都对一个操作数进行操作,那么读指令得到的数据只能是以下两种情况之一:
1.        写操作执行前的值
2.        写操作执行后的值
永远不可能出现一部分是写操作之前的值,一部分是写操作之后的值的情况。
  在ARMv7中,单拷贝原子的处理器读写包括以下种类:
        所有的字节操作
        所有半字边界上的半字操作
        所有字边界上的字操作
        所有应用了LDREXD和STREXD,并且在双字边界上的双字操作。
在SIMD指令中的操作也和上面这些规定类似,也是要求数据小于或等于32bit,并且自然对齐才能保证其原子性。

使用特权

评论回复
97
xinzha|  楼主 | 2013-9-11 22:54 | 只看该作者
简单地讲,竞争冒险可以用如下的例子来说明,当两个线程都需要对某一临界资源进行操作时:
Thread A:
while(0 == semaphore)
{
/* 问题点A */
    semaphore = 1;
}
/* 后续对共享资源的处理 */

Thread B:
while(0 == semaphore)
{
/* 问题点B */
    semaphore = 1;
}
/* 后续对共享资源的处理 */
假设线程A运行到问题点A,此时正好发生了线程的切换,线程B获得了执行权,此时semaphore的值还是为0,于是线程B认为自己获得对共享资源的控制,而之后一旦线程A获得执行权,又会认为自己也获得了执行权,于是就出现了对共享资源的竞争冒险。

而解决这种竞争冒险的问题,一种办法是应用图灵奖获得者Edsger Dijkstra设计的软件信号量,一种办法是使用体系结构提供的类似于test and increase这样的原子操作,还有一种办法稍微傻点(当初我刚做arm的时候不知道swp这条指令),于是就用了关中断-获取变量-修改变量-开中断这种方法,在单核的cpu中也能实现类似于信号量的操作,但是在多核系统中完全失去作用了。
在ARMv6之前信号量的实现由SWP和SWPB指令来实现,而在ARMv6及之后的kernel中则推荐使用LDREX和STREX命令对来实现信号量。


ARM体系结构提供的原子操作就是SWP(B),SWP的语法如下:
SWP rd,rm,[rs]
这条语句会将总线锁住,完成如下两步操作:
1、        rd = [rs]
2、        [rs] = rm
也许你会问,这怎么实现信号量操作啊?请看如下示例代码:
sem_lock;
swp rd,rm,[rs]
cmp rd,#0x0
jne sem_lock

比如说锁打开的时候为0,关闭为1,那么如果在锁打开时,执行sem_lock就会使rd = 0,而锁的值变为1,实现了关锁。因为swp是原子操作,所以不用担心执行过程中锁的值放生改变。
而如果此时锁为关闭状态,那么执行sem_lock就会是rd的值为1,软件此时就应该认为获取锁失败,不断循环以等待其持有者释放。
在新的架构中使用LDREX和STREX对来实现信号量,关于这两个指令比较复杂,需要更多的时间去讨论和理解,这两个指令的一个好处是从架构级别对共享资源进行保护,而不是以前的那种需要软件协商的方式,在swp这种模式中,只要有一个线程不遵守规则,那么一切保护都将成为空谈,而LDREX/STREX方式中,可以由硬件机制作出一定程度的保证。

使用特权

评论回复
98
原野牧歌| | 2013-9-12 10:15 | 只看该作者
没有想到,无意看到这帖子,蛮有收获,谢谢分享。

使用特权

评论回复
99
xinzha|  楼主 | 2013-9-15 23:18 | 只看该作者
这种针对共享资源的保护,是基于所有的使用者都遵循这种获取许可然后再操作的模式,可一旦有某个使用者不遵守规则,那么其他所有使用者所做的努力都成为空谈。
在新的架构中使用LDREX和STREX指令对来实现信号量,关于这两个指令比较复杂,需要更多的时间去讨论和理解,这两个指令留下了很多implementation defined的空间,为从架构级别对共享资源进行保护留下了很多遐想,而不是一定要按照以前的那种需要软件协商的方式。比如说ARM公司允许如下的设计,当一个线程对某一块内存使用了LDREX操作之后,这之后只有当前CPU的STREX操作可以将此内存解锁,其他CPU的STREX会失败,而所有CPU的STR会将锁状态清除,这样当这个线程再调用STREX时会失败,此线程也就知道这个区域在此过程中被改写,相当大程度地减轻了软件在锁问题上的烦恼。

使用特权

评论回复
100
shuidi_wangdan| | 2013-9-21 09:37 | 只看该作者
关注中!!好**!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则