各位看官,请看以下代码:
pdata指向一个并非字对齐的地址空间,也是本博客提醒各看官的地方,如果对非对齐的地址访问,请不要使用指针形式,代为使用数据方式访问。
float* pdataf;
pdataf = (float*)pdata;
for(i=0;i<16;i++)
{
*pdataf++ = get_keepad(i+1);
}
上述代码是想通过一个浮点数指针来修改当前内存中的数据,然后将指针向后加。
此代码在监控是生成数据协议用,但这段代码在通过JTAT调试时,如果单步执行不会有问题,直接运行就会出现死机【HardFault】并复位的现象,不得解,后查看原来处理的代码,发现如果按此处理却没有问题:
float* pdataf;
pdataf = (float*)pdata;
for(i=0;i<16;i++)
{
pdataf[i] = get_keepad(i+1);
}
通过数组方式访问却没有问题。
比较了两种写法的指令如下:
下图为指针写法,
下图为数组写法
关键点在于:
STM r7!,{r0} ;用于将数据写入内存地址
与
STR r0, [r8, r5, LSL #2] ;用于寄存器操作指令,相当于 r8[r5*4] = r0, r5为循环变量,相当于r8[i*4] = r0, 即数据访问的形式,4个字节的长度
指令说明文档:
STM<c><q> <Rn>{!}, <registers>
Operation
if ConditionPassed() then
EncodingSpecificOperations();
address = R[n];
for i = 0 to 14
if registers<i> == ‘1’ then
if i == n && wback && i != LowestSetBit(registers) then
MemA[address,4] = bits(32) UNKNOWN; // encoding T1 only
else
MemA[address,4] = R[i];
address = address + 4;
if wback then R[n] = R[n] + 4*BitCount(registers);
Exceptions
UsageFault, MemManage, BusFault.
从文档的指令对齐信息来看:
Alignment and data access
The following data accesses always generate an alignment fault:
• Non halfword-aligned LDREXH and STREXH
• Non word-aligned LDREX and STREX
• Non word-aligned LDRD, LDMIA, LDMDB, POP , LDC , VLDR, VLDM, and VPOP
• Non word-aligned STRD, STMIA, STMDB, PUSH, STC , VSTR, VSTM, and VPUSH.
STM不包括其中,但STMIA,STMDB包括在其中,难道是对齐问题?
这里数据的确不是字对齐的,我只能怀疑他了。