stm32 build from scratch 刷机成功但板子上没有运行
stm32 build from scratch successfully flashes but doesn not run on the board
我不熟悉使用 MCU 从头开始构建项目。我使用了一个旧项目文件,它在 eclipse/gdb 构建环境中成功 运行s,其中 IDE 为我完成了所有构建,并尝试使用 open-ocd 和工具链实现我自己的构建:手臂-none-eabi。我成功地刷新了设备,但是电路板没有 运行 代码。我希望我可能会遗漏一些明显的重要文件,但我还没有得出那个结论。
我主要担心的是我的 start_up.c 文件或 linker.ld[=22 没有正确设置=] 文件,虽然我还没有找到相信的理由。我正在使用 stm32L476 探索板。如果有人感兴趣,这里是数据 sheet 的 link:https://www.st.com/resource/en/reference_manual/dm00083560-stm32l47xxx-stm32l48xxx-stm32l49xxx-and-stm32l4axxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
我的问题来源在github:https://github.com/landonbr/stm32-fun
我强烈建议你不要使用 C 到 bootstrap C。并且强烈建议不要使用跨编译域的结构。
• 96 Kbyte mapped at address 0x2000 0000 (SRAM1)
• 32 Kbyte located at address 0x1000 0000 with hardware parity check (SRAM2).
On STM32L49x/L4Ax devices, the SRAM2 is aliased at address 0x2004 0000, offering a
continuous address space with the SRAM1.
这是STM32L47 是吗?所以这不适用。
08000000 <vector>:
8000000: 20020000 andcs r0, r2, r0
8000004: 0800043b stmdaeq r0, {r0, r1, r3, r4, r5, r10}
8000008: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
800000c: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
0x200000 = 128KB。尝试一些小的东西来开始 0x20001000。或者选择 96K。 0x20018000
它没有损坏(好吧,它可能取决于寄存器和字段)但更清晰地执行与寄存器分开的读取-修改-写入,因此寄存器仅从一种模式切换到另一种模式,而不是两次切换模式.
GPIOB->MODER &= ~(3UL<<4); // Clear mode bits
GPIOB->MODER |= 1UL<<4; // Set mode to output
tmp = GPIOB->MODER
tmp &= ~(3UL<<4); // Clear mode bits
tmp |= 1UL<<4; // Set mode to output
GPIOB->MODER = tmp
一次只做一件事可能是个好主意。使用基于计数器的延迟(这不是死代码)打开 LED 或使 LED 闪烁。然后再弄乱按钮或计时器或其他东西。
查看 gpio BSRR 寄存器而不是 ODR。让生活更轻松。
这是死代码,
if(Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
for(int i=125000; i!=0; i--){}
GPIOE->ODR |= (1UL << 8);
for (int i=125000; i!=0; i--){}
}
基本编译成这样
if(Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
GPIOE->ODR |= (1UL << 8);
}
如果没有瞄准镜,速度太快了。而且您无法真正确定循环中的时间,因此它不是 2 Hz。
在你的情况下,你没有优化,所以循环在那里,它至少在我使用的 gnu 中出现。
当然你应该从这个开始:
while(1){
GPIOE->BSRR = 1<<(8+16);
for(volatile int i=125000; i!=0; i--){}
GPIOE->BSRR = 1<<(8+ 0);
for (volatile int i=125000; i!=0; i--){}
}
作为你的主程序,在初始化那个 gpio 引脚之后。没有任何操纵杆按钮的东西。让它工作并确保你的基本骨架是好的,然后向它添加东西。 (注意按钮是 tricky/painful,因为您经常想要对它们进行去抖动。在这种情况下可能不会,但通常情况下)
我不熟悉使用 MCU 从头开始构建项目。我使用了一个旧项目文件,它在 eclipse/gdb 构建环境中成功 运行s,其中 IDE 为我完成了所有构建,并尝试使用 open-ocd 和工具链实现我自己的构建:手臂-none-eabi。我成功地刷新了设备,但是电路板没有 运行 代码。我希望我可能会遗漏一些明显的重要文件,但我还没有得出那个结论。
我主要担心的是我的 start_up.c 文件或 linker.ld[=22 没有正确设置=] 文件,虽然我还没有找到相信的理由。我正在使用 stm32L476 探索板。如果有人感兴趣,这里是数据 sheet 的 link:https://www.st.com/resource/en/reference_manual/dm00083560-stm32l47xxx-stm32l48xxx-stm32l49xxx-and-stm32l4axxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
我的问题来源在github:https://github.com/landonbr/stm32-fun
我强烈建议你不要使用 C 到 bootstrap C。并且强烈建议不要使用跨编译域的结构。
• 96 Kbyte mapped at address 0x2000 0000 (SRAM1) • 32 Kbyte located at address 0x1000 0000 with hardware parity check (SRAM2).
On STM32L49x/L4Ax devices, the SRAM2 is aliased at address 0x2004 0000, offering a continuous address space with the SRAM1.
这是STM32L47 是吗?所以这不适用。
08000000 <vector>:
8000000: 20020000 andcs r0, r2, r0
8000004: 0800043b stmdaeq r0, {r0, r1, r3, r4, r5, r10}
8000008: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
800000c: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
0x200000 = 128KB。尝试一些小的东西来开始 0x20001000。或者选择 96K。 0x20018000
它没有损坏(好吧,它可能取决于寄存器和字段)但更清晰地执行与寄存器分开的读取-修改-写入,因此寄存器仅从一种模式切换到另一种模式,而不是两次切换模式.
GPIOB->MODER &= ~(3UL<<4); // Clear mode bits
GPIOB->MODER |= 1UL<<4; // Set mode to output
tmp = GPIOB->MODER
tmp &= ~(3UL<<4); // Clear mode bits
tmp |= 1UL<<4; // Set mode to output
GPIOB->MODER = tmp
一次只做一件事可能是个好主意。使用基于计数器的延迟(这不是死代码)打开 LED 或使 LED 闪烁。然后再弄乱按钮或计时器或其他东西。
查看 gpio BSRR 寄存器而不是 ODR。让生活更轻松。
这是死代码,
if(Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
for(int i=125000; i!=0; i--){}
GPIOE->ODR |= (1UL << 8);
for (int i=125000; i!=0; i--){}
}
基本编译成这样
if(Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
GPIOE->ODR |= (1UL << 8);
}
如果没有瞄准镜,速度太快了。而且您无法真正确定循环中的时间,因此它不是 2 Hz。
在你的情况下,你没有优化,所以循环在那里,它至少在我使用的 gnu 中出现。
当然你应该从这个开始:
while(1){
GPIOE->BSRR = 1<<(8+16);
for(volatile int i=125000; i!=0; i--){}
GPIOE->BSRR = 1<<(8+ 0);
for (volatile int i=125000; i!=0; i--){}
}
作为你的主程序,在初始化那个 gpio 引脚之后。没有任何操纵杆按钮的东西。让它工作并确保你的基本骨架是好的,然后向它添加东西。 (注意按钮是 tricky/painful,因为您经常想要对它们进行去抖动。在这种情况下可能不会,但通常情况下)