Zlg的easyarm1138使用了lm3s1138作为主芯片。LM3S1138以cortex-m3为内核,和STM32类似。这里只关注cortex-m3的存储器系统。
下面是cortex-m3的存储空间分布图。
Cortex-m3对所有的地址空间使用统一编址的方式,即都可由存储映射访问。而不像8086那样内存空间和IO空间分离。
其中最有特点的是所谓的位带访问。这跟8051中的SFR存储空间的访问有些类似。也即可以使用某个地址对字/半字/字进行整体的访问,也可以使用其它地址对仅仅对特定字的某一位进行读写。
比方说51中的P1寄存器。即可以 i = P1来读取P1的整个值,也可以用j = P1_1来读取P1寄存器的第1位。
这样的好处是,当需要寄存器的某一位时不需要进行读-改-写的操作。比如要设置P1的0号端口为1,可以这样写P1 |= 0x1。实际执行的操作肯定是先读P1的值,再将第0位写1,再将改后的值写回P1。而如果用P1=0x1的话,则肯定会影响P1寄存器的其它位。但如果用P1_1 = 0x1,则相当于直接给该位为1,只需要写就可以了。
据说,还可在多任务下实现互斥访问。访问共享资源时不会发生冲突。这一点我还有待学习。
Cortex-m3存储系统有两块位带区。一块是0x20000000开始的1M空间,另一块是0x40000000开始的1M空间。这两块地址空间的存储访问,是以字节/半字/字的访问访问的。用汇编指令来说就是LDR R0, =0x20000000; LDR R0, [R0]。而0x2200000开始的32M和0x4200000开始的32M,称位带别名区,即分别是前两块存储空间的别名。也就是说0x20000000和0x2200000实际上是映射到相同的存储空间内。不同的是,0x20000000开始的1M地址,每个地址对就于这块存储空间的1个字节。而0x2200000开始的32M每个字地址对应于这块存储空间的每位。1M的字,正好是8M的位,每个位用字地址表示,也就是8*4 = 32M的位带别名地址大小了。
当然其二者之间的地址存在一定关系,可以由公式表示。
LM3S1138的存储映射如图:
其存储空间为FLASH 64K, RAM 16K.
对比cortex-m3与下表可以看出.1138的片内RAM和片上外设地址空间均在位带区。也就是说,无论是RAM还是片上外设的寄存器都可以进行单个位的位操作。
存储访问的C函数接口:
官方提供的库中提供了相应的C函数来进行直接的存储访问。在hw_types.h文件中包含了相应的宏。另外还定义了布尔类型。我估计布尔类型用于支持位带操作用的。
HWREG(X)用于访问存储空间的一个字。不限于访问片上RAM,也可用于FLASH,内部的寄存器。
HWREGH(X)用于访问存储空间的一个半节
HWREGB(X)用于访问存储空间的一个字节
HWREGBITW(x,b)则仅适用于对位带区中的地址为X的字的第b位进行访问。
HWREGBITH(x,b)则仅适用于对位带区中的地址为X的半的第b位进行访问。
HWREGBITB(x,b)则仅适用于对位带区中的地址为X的字节的第b位进行访问。
以访问地址为0x20000000一个字为例:
读字:variable = HWREG( 0x20000000 ), 写字 HWREG( 0x20000000 ) = 数值.
读写0x20000000字单元中的第1位:
读Variable = HWREGBITW( 0x20000000, 1 ); 读得值为0或1
写:HWREGBITW(0x20000000, 1) = 0x1;
至于那个计算公式,我觉得就不必深究了。可以自己推导的。
在KEIL下自己写的一个简单的示例为下图:
文章评论(0条评论)
登录后参与讨论