首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Microblaze嵌入式开发——又见bug(已经解决)

Microblaze嵌入式开发——又见bug(已经解决)

得上帝垂怜,使我遇到了各种各样奇怪的现象。
转入正题,有这样一个很简单的函数,C代码和汇编指令如下:
static u16 i2u16(u16 *src)
{ u8 *low = ((u8 *)src)+1;
9000ee10: e0650001 lbui r3, r5, 1
9000ee14: e0850000 lbui r4, r5, 0
9000ee18: 64630408 bslli r3, r3, 8
9000ee1c: 10632000 addk r3, r3, r4
u8 *high = (u8 *)src;
return (((u16)(*low))<<8) + (u16)(*high);
}
9000ee20: b0000000 imm 0
9000ee24: a463ffff andi r3, r3, -19000ee28: b60f0008 rtsd r15, 8
9000ee2c: 80000000 or r0, r0, r0
函数的功能就是将读到的16bit数据的高8位和低8位进行互换

奇怪的是:我运行在FPGA开发板上之后,单独测试该函数的时候所得到的结果完全正确,但是一旦放到一个大的工程中,运行的结果完全不是一回事了。例如,我输入*src的值是0x0600,给我的返回值却是0x040e,而不是我期望的结果0x0006。
下面是调试的时候记录下的信息
--------------------------------------------------------------------------------------------------
设置断点
XMD% bps 0x9000ee10
Setting breakpoint at 0x9000ee10
运行
XMD% run
Inforocessor started. Type "stop" to stop processor

RUNNING> System Reset .... DONE
程序运行到断点处停止
XMD% Info:Software Breakpoint 0 Hit, Processor Stopped at 0x9000ee10
读取同样寄存器信息
XMD% rrd
r0: 00000000 r8: 0000002c r16: 9000ee10 r24: 90fddce0
r1: 91efdb84 r9: 90fdde0b r17: 00000000 r25: 91efd54c
r2: 900f6af0 r10: 90186e14 r18: ffffffd3 r26: 00000000
r3: 0000002c r11: 00000019 r19: 9000ee10 r27: 900f323e
r4: 00000000 r12: 00000000 r20: 00000000 r28: 91efd510
r5: 90178be6 r13: 90187238 r21: 00000000 r29: 00000001
r6: 90fdde24 r14: 00000000 r22: 00000013 r30: 90fddce0
r7: ffffffff r15: 9000f080 r23: 90178bb4 r31: 900f323e
pc: 9000ee10 msr: 000000a2

读取以R5值为地址的内存上的数据
注意mrd的命令是按照32bit读取的
用mrd 读取地址0x90178be4, 0x90178be5,0x90178be6和
0x90178be7所得到的结果是一样的。

XMD% mrd 0x90178be6 8
90178BE6: 03000600
90178BEA: 06000100
90178BEE: 04000100
90178BF2: 01005555
90178BF6: 55550800
90178BFA: 58000000
90178BFE: 58000000
90178C02: 5A020000

XMD% stp
9000EE14: E0850000 lbui r4 , r5 , 0

运行完的指令是: lbui r3, r5,1
即:Addr:=r5+1=0x90178be7
*(Addr)=0x00060001;
r3[24:31]:=*(Addr)[0:7]=0x00;
r3[0:15] :=0;
故r3=0;看rrd所运行的结果
单步跟踪
下一步的指令是: lbui r4,r5,0

XMD% rrd
r0: 00000000 r8: 0000002c r16: 9000ee10 r24: 90fddce0
r1: 91efdb84 r9: 90fdde0b r17: 00000000 r25: 91efd54c
r2: 900f6af0 r10: 90186e14 r18: ffffffd3 r26: 00000000
r3: 00000000 r11: 00000019 r19: 9000ee10 r27: 900f323e
r4: 00000000 r12: 00000000 r20: 00000000 r28: 91efd510
r5: 90178be6 r13: 90187238 r21: 00000000 r29: 00000001
r6: 90fdde24 r14: 00000000 r22: 00000013 r30: 90fddce0
r7: ffffffff r15: 9000f080 r23: 90178bb4 r31: 900f323e
pc: 9000ee14 msr: 000000a2
XMD% stp
9000EE18: 64630408 bslli r3 , r3 , 8
<>
运行完的指令是: lbui r4, r5,0即:Addr:=r5+1=0x90178be6
*(Addr)=0x06000600;
r4[24:31]:=*(Addr)[0:7]=0x06;
r4[0:15] :=0;
故r4=0x06;看rrd所运行的结果
单步跟踪
下一步的指令是: bslli r3,r3,8

XMD% rrd
r0: 00000000 r8: 0000002c r16: 9000ee10 r24: 90fddce0
r1: 91efdb84 r9: 90fdde0b r17: 00000000 r25: 91efd54c
r2: 900f6af0 r10: 90186e14 r18: ffffffd3 r26: 00000000
r3: 00000000 r11: 00000019 r19: 9000ee10 r27: 900f323e
r4: 00000006 r12: 00000000 r20: 00000000 r28: 91efd510
r5: 90178be6 r13: 90187238 r21: 00000000 r29: 00000001
r6: 90fdde24 r14: 00000000 r22: 00000013 r30: 90fddce0
r7: ffffffff r15: 9000f080 r23: 90178bb4 r31: 900f323e
pc: 9000ee18 msr: 000000a2

XMD% stp
9000EE1C: 10632000 addk r3 , r3 , r4

运行完的指令是: bslli, r3, r3,8即:
r3:=(r3<<8)&0; r3左移8位,用零补齐
故r3=0;看rrd所运行的结果却是
0x00000408,这个就奇怪了
单步跟踪
下一步的指令是:addk r3,r3,r4
XMD% rrd
r0: 00000000 r8: 0000002c r16: 9000ee10 r24: 90fddce0
r1: 91efdb84 r9: 90fdde0b r17: 00000000 r25: 91efd54c
r2: 900f6af0 r10: 90186e14 r18: ffffffd3 r26: 00000000
r3: 00000408 r11: 00000019 r19: 9000ee10 r27: 900f323e
r4: 00000006 r12: 00000000 r20: 00000000 r28: 91efd510
r5: 90178be6 r13: 90187238 r21: 00000000 r29: 00000001
r6: 90fdde24 r14: 00000000 r22: 00000013 r30: 90fddce0
r7: ffffffff r15: 9000f080 r23: 90178bb4 r31: 900f323e
pc: 9000ee1c msr: 000000a2
XMD% stp
9000EE20: B0000000 imm 0
9000EE24: A463FFFF andi r3 , r3 , -1

XMD% rrd
r0: 00000000 r8: 0000002c r16: 9000ee10 r24: 90fddce0
r1: 91efdb84 r9: 90fdde0b r17: 00000000 r25: 91efd54c
r2: 900f6af0 r10: 90186e14 r18: ffffffd3 r26: 00000000
r3: 0000040e r11: 00000019 r19: 9000ee10 r27: 900f323e
r4: 00000006 r12: 00000000 r20: 00000000 r28: 91efd510
r5: 90178be6 r13: 90187238 r21: 00000000 r29: 00000001
r6: 90fdde24 r14: 00000000 r22: 00000013 r30: 90fddce0
r7: ffffffff r15: 9000f080 r23: 90178bb4 r31: 900f323e
pc: 9000ee20 msr: 000000a2
XMD% con
Inforocessor started. Type "stop" to stop processor

在Xilinx forums 也发了这个问题,一人提示道:是否将barrel shifter配置到了MicroBlaze中。果然,检查了MicroBlaze的配置,没有将barrel shifter添加进去。
最后总结一下问题:
问题:MicroBlaze 指令其中bslli等移位操作指令失效。
原因:在MicroBlaze默认的配置中没有将barrel shifter配置进去,才导致移位操作指令失效
解决方案:通过MicroBlaze配置界面将Enable Barrel Shifter 选中;或者在system.mhs文件中添加:
BEGIN microblaze
. . .  

  PARAMETER C_USE_BARREL = 1      #enable barrel shifter
. . .
END
记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表