本文首发于稀土掘金。该平台的作者 逐光而行 也是本人。
位带操作
什么是位带操作?
- 对32MB SRAM 别名区的访问映射为对1MB SRAM的bit-band 区的访问。
- 对32MB 外设别名区的访问映射为对1MB 外设bit-band 区的访问。
即下图:
以SRAM区的映射为例:
总结来说cortex-M3内核的位带映射就两块:
- 0x20000000 左右的,位带映射的基址地址是0x22000000
- 0x40000000 左右的,位带映射的基址地址是0x42000000
位带操作计算
公式:
$$ bit\_word\_addr = bit\_band\_alias\_base + (byte\_offset×32) + (bit\_number×4) $$
怎么计算?来看个具体例子:
地址? 的别名字映射为0x200FFFFF的bit-band字节的位0
$?=0x22000000+0xFFFFF*32+0*4$
结果为0x23FFFFE0
注意事项:
- *32:可以先转为二进制表示,再左移五位,再重新转为十六进制
- 所有数必须化为相同进制去算
位带操作有什么用?
课程参考答案:
- 方便对串行接口器件的操作。尤其是对硬件I/O 密集型的底层程序,如GPIO接口的bit位控制。
(想要修改时,不需要读取寄存器里的值,修改,然后再送回去;只需要读取别名区的值然后改)
- 简化跳转的判断
(大致原理同上)
- 并发控制
(个人的一点碎碎念:其实我看上面那个图,感觉是把小小的一块映射到了一块更大的地址空间去,有种扩充对有限空间的利用的意味吧,不知道我有没有理解错)
中断的两种处理方式
- 本质上是两个中断接连到来,两者优先级不同,但前者已经准备或正在被响应,此时应该怎么处理后者的问题。
咬尾中断
系统正在处理当前中断,后到的中断优先级不如先到的,它需要等待前者被执行后才执行。
原本前后衔接的过程是需要先出栈,再入栈。但实际上这出栈又入栈的是同一批寄存器等,很耗时,所以就省掉了这一步,称为“咬尾”(后者咬掉了前者留下的小尾巴直接继续)。
晚到中断
系统正打算处理当前中断(已经入好栈准备保护现场了),后到的优先级更高,因此这次的入栈就相当于是为后者准备的,先响应后者的中断。
后者虽然晚到,但它的待遇是不差的,其他的得为它让路。
- 注意:如果后者来得太晚,中断服务程序(ISR)已经开始执行,那就按普通的抢占处理。