你好,
我正在将一个Keil uVision项目移植到GNU工具链中,仔细遵循AN-B-024文档,可以成功构建十六进制文件(out/ full_emb_syram .hex)。但是,固件不稳定(HW RESET后,固件可能工作,成功率约为1/20)。我的源代码(基于DSPS参考设计)运行良好,如果从Keil uVision构建。
我考虑是否移植部分的“在”__attribute__(见4.4,Keil编译器扩展)是正确的移植或不?
我们可以在pwm.c中找到相关的部分(src/plf/refip/src/driver/pwm/pwm.c)
volatile struct __CLK_PER_REG __attribute__((在(clk_per_reg)));
volatile struct __TIMER0_CTRL_REG timer0_ctrl_reg __attribute__(((at(timer0_ctrl_reg)));
triple_pwm_ctrl_reg属性((at(triple_pwm_ctrl_reg)));
代码修改为:
volatile struct __CLK_PER_REG clk_per_reg __attribute__((section("atCLK_PER_REG")));
volatile struct __TIMER0_CTRL_REG timer0_ctrl_reg __attribute__(((section(“atTIMER0_CTRL_REG”)));
triple_pwm_ctrl_reg __attribute__((section(" section "))))
在链接器脚本中,我添加了一些相关的部分在MEMORY和SECTIONS如下所示
内存{
...
MCU_REGS (rw): ORIGIN = 0x50000000, LENGTH = 0x4000
}
部分
{
/* atCLK_PER_REG 0x50000004:
{
保持(* (atCLK_PER_REG))
} > MCU_REGS
atTIMER0_CTRL_REG 0 x50003400:
{
保持(* (atTIMER0_CTRL_REG))
} > MCU_REGS
atTRIPLE_PWM_CTRL_REG 0 x50003410:
{
保持(* (atTRIPLE_PWM_CTRL_REG))
} > MCU_REGS
...
}
十六进制文件已成功构建,但我无法在out/lst/ full_emb_syram .map中看到预期的正确地址。
atCLK_PER_REG
* (atCLK_PER_REG)
atTIMER0_CTRL_REG
* (atTIMER0_CTRL_REG)
atTRIPLE_PWM_CTRL_REG
* (atTRIPLE_PWM_CTRL_REG)
所以,我假设“at”__attribute__不能通过这种方法移植(使用特定节和相关的链接器脚本部分),如果代码访问MCU寄存器。
然后,我试图将位域结构映射到易失性寄存器,像这样:
struct __CLK_PER_REG* clk_per_reg = (__CLK_PER_REG*) (clk_per_reg);
struct __TIMER0_CTRL_REG* timer0_ctrl_reg = (__TIMER0_CTRL_REG*) (timer0_ctrl_reg);
volatile struct __TRIPLE_PWM_CTRL_REG* triple_pwm_ctrl_reg = (__TRIPLE_PWM_CTRL_REG*) (triple_pwm_ctrl_reg);
...
但是,这也没有用。
我现在需要来自Dialog的GNU专家的支持。
非常感谢论坛中GNU专家的任何帮助!
你真的!
你好南Hau
我以前没有见过这个问题。
我试着重现一下,然后给你们答复。
问候
TN_Dialog
你好南Hau
我认为凯尔法则是
volatile struct __CLK_PER_REG __attribute__((在(clk_per_reg)));
volatile struct __TIMER0_CTRL_REG timer0_ctrl_reg __attribute__(((at(timer0_ctrl_reg)));
triple_pwm_ctrl_reg属性((at(triple_pwm_ctrl_reg)));
它可以被转换成标准的C代码(在Keil和gcc中都可以使用),如下所示:
struct __CLK_PER_REG* clk_per_reg = (volatile struct __CLK_PER_REG*) (clk_per_reg);
volatile struct __TIMER0_CTRL_REG* timer0_ctrl_reg = (volatile struct __TIMER0_CTRL_REG*) (timer0_ctrl_reg);
volatile struct __TRIPLE_PWM_CTRL_REG* triple_pwm_ctrl_reg = (volatile struct __TRIPLE_PWM_CTRL_REG*) (triple_pwm_ctrl_reg);
不同的是,现在这3个变量实际上是指向结构的指针,而不是结构本身。
所以,使用这些寄存器的代码必须从,例如,
clk_per_reg。some_field = 12345;
来
clk_per_reg - > some_field = 12345;
这个想法是使用标准的C代码,使它在不带“at”属性的情况下与Keil一起工作。
那么它也应该适用于gcc。
问候
TN