在 Linux 上编译一个 c++ 应用程序,并在 TI TIVA TM4C123GH6PM上刷新它

Compiling an c++ application on Linux and flash it on the TI TIVA TM4C123GH6PM

本文关键字:TI 并在 TIVA TM4C123GH6PM 刷新 应用程序 一个 编译 Linux c++      更新时间:2023-10-16

我正在使用Makefile在Linux中编译一个应用程序。我的编译器来自Imperas(ovp世界)。编译应用程序后,我得到一个 *.elf 文件,我想使用 TI 的 Uniflash 软件在 TI TIVA TM4C123GH6PM上刷新该文件。 当我尝试验证图像时,我总是收到此错误:" [错误] CORTEX_M4_0:文件加载程序:验证失败:地址 0x00008000 处的值不匹配,请验证目标内存和内存映射。

我的生成文件如下所示:

//

IMPERAS_HOME := $(shell getpath.exe "$(IMPERAS_HOME)") include $(IMPERAS_HOME)/bin/Makefile.include

IFNDEF IMPERAS_HOME IMPERAS_ERROR := $(错误"未定义IMPERAS_HOME") 恩迪夫

交叉=ARM_CORTEX_M4F

-include $(IMPERAS_HOME)/lib/$(IMPERAS_ARCH)/CrossCompiler/$(CROSS).makefile.include ifeq ($(CROSS)_CXX),) IMPERAS_ERROR := $(错误"请安装工具链以支持 $(CROSS) ") 恩迪夫

优化=-O

SRC = $(排序 $(通配符主.cpp)) $(排序 $(通配符配置/配置.cpp)) $(排序 $(通配符 Segway/Simulation.cpp)) $(排序 $(通配符 Segway/Segway.cpp)) $(排序 $(通配符传感器/ADC.cpp)) $(排序 $(通配符传感器/ADCSensor.cpp)) $(排序 $(通配符 Antrieb/Motor.cpp)) $(排序 $(通配符传感器/GPIOSensor.cpp)) $(排序 $(通配符计时器/计时器.cpp)) $(排序 $(通配符 Antrieb/PWM.cpp))

EXE = 应用程序。ARM_CORTEX_M4F.精灵

全部: $(EXE)

%.elf: main.o Segway/Segway.o Timer/Timer.o Sensor/ADC.o Sensor/ADCSensor.o Sensor/GPIOSensor.o Configuration/Configuration.o Antrieb/Motor.o Antrieb/PWM.o $(V) echo "# Linked $@" $(V) $(IMPERAS_LINKXX) -o $@ $^ $(IMPERAS_LDFLAGS)

%.o: %.cpp $(V) echo "# 编译 $<" $(V) $(IMPERAS_CXX) -g -c -o $@ $<$(优化) -lm

干净: -rm -f *.elf *.o

真正的清洁:干净 -rm -f *.log

//

如何将内存映射包含在我的生成文件中?内存映射在 *.cmd 文件中定义。这是该文件的链接:https://github.com/LuisAfonso95/TM4C123-Launchpad-Examples/blob/master/srf04/tm4c123gh6pm.cmd

有没有人能解决我的问题并可以帮助我?

如果您需要任何进一步的信息,请告诉我。

谢谢!

Johannes

makefile

ARMGNU = arm-none-eabi
AOPS = --warn --fatal-warnings -mcpu=cortex-m4
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mcpu=cortex-m4
all : so.bin
clean:
rm -f *.bin
rm -f *.o
rm -f *.elf
rm -f *.list
flash.o : flash.s
$(ARMGNU)-as $(AOPS) flash.s -o flash.o
so.o : so.c
$(ARMGNU)-gcc $(COPS) -mthumb -c so.c -o so.o
so.bin : flash.ld flash.o so.o
$(ARMGNU)-ld -o so.elf -T flash.ld flash.o so.o
$(ARMGNU)-objdump -D so.elf > so.list
$(ARMGNU)-objcopy so.elf so.bin -O binary

闪存

MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}

闪光灯

.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
bl notmain
b hang
.thumb_func
hang:   b .
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr

所以.c

extern void PUT32 ( unsigned int, unsigned int );
int notmain ( void )
{
PUT32(0x20000400,0x12345678);
return(0);
}

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m4 flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mcpu=cortex-m4 -mthumb -c so.c -o so.o
arm-none-eabi-ld -o so.elf -T flash.ld flash.o so.o
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy so.elf so.bin -O binary

检查反汇编以查看向量表是否位于正确的位置并正确构建,可以抛出一个全局变量并将其保存一个值(运行时),以查看该变量是否也在正确的位置(如果需要)。

Disassembly of section .text:
00000000 <_start>:
0:   20001000    andcs   r1, r0, r0
4:   00000041    andeq   r0, r0, r1, asr #32
8:   00000047    andeq   r0, r0, r7, asr #32
c:   00000047    andeq   r0, r0, r7, asr #32
10:   00000047    andeq   r0, r0, r7, asr #32
14:   00000047    andeq   r0, r0, r7, asr #32
18:   00000047    andeq   r0, r0, r7, asr #32
1c:   00000047    andeq   r0, r0, r7, asr #32
20:   00000047    andeq   r0, r0, r7, asr #32
24:   00000047    andeq   r0, r0, r7, asr #32
28:   00000047    andeq   r0, r0, r7, asr #32
2c:   00000047    andeq   r0, r0, r7, asr #32
30:   00000047    andeq   r0, r0, r7, asr #32
34:   00000047    andeq   r0, r0, r7, asr #32
38:   00000047    andeq   r0, r0, r7, asr #32
3c:   00000047    andeq   r0, r0, r7, asr #32
00000040 <reset>:
40:   f000 f804   bl  4c <notmain>
44:   e7ff        b.n 46 <hang>
00000046 <hang>:
46:   e7fe        b.n 46 <hang>
00000048 <PUT32>:
48:   6001        str r1, [r0, #0]
4a:   4770        bx  lr
0000004c <notmain>:
4c:   b508        push    {r3, lr}
4e:   4903        ldr r1, [pc, #12]   ; (5c <notmain+0x10>)
50:   4803        ldr r0, [pc, #12]   ; (60 <notmain+0x14>)
52:   f7ff fff9   bl  48 <PUT32>
56:   2000        movs    r0, #0
58:   bd08        pop {r3, pc}
5a:   bf00        nop
5c:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000
60:   20000400    andcs   r0, r0, r0, lsl #8

在正确的位置看起来不错矢量表,在矢量表地址上设置lsbit等。

这是一个非常通用的 cortex-m 程序,应该适用于几乎所有内核,您可能需要将堆栈指针 init 减少到 0x20000800 或更小,同样在命令行上指定 cortex-m0 而不是 m4 以使其更加通用,在这种情况下,它没有生成任何 armv7-m thumb2 扩展。

看看你的工具对生成的这个so.elf文件有什么看法,它确实比这更简单(删除bl notmain),并且只将flash.s链接到elf,但不会比这简单多少。 如果它不起作用,那么问题可能是其他原因,该工具可能正在寻找某些东西。 如果这真的是一个tiva c部件,那么也许lm4flash工具可以工作,你不需要任何GUIS,否则如果你有一个SWD解决方案(一个st核或发现板,或者你正在运行一个ti launchpad,或者一个jlink或ftdi分线板与正确的ftdi部分(一个支持mpsse并且电压是适合你的目标的水平)。 如果它不起作用,那么该工具可能正在 elf 文件中寻找通常不需要的特殊内容。 我想在问这里之前你查了那个错误消息?

如果它确实加载并似乎正在运行,并且您有调试器,则可以停止 CPU 并读取0x20000400,并且应该看到程序编写的0x12345678,以进一步确认程序确实加载并运行。 然后检查我的 makefile、链接器脚本以及它在编译过程中的使用位置,而不是你的。

如果您尝试使用 gcc 调用所有工具链,那么还需要了解其他事项,例如

arm-whatever-gcc other flags, -Xlinker '-T flash.ld' flash.s so.c -o so.elf

基本上一个或两个 -Xlinker 或任何正确的命令行选项,我想我为每个 ld 选项使用一个 -Xlinker(-Xlinker -T -Xlinker flash.ld,但是 YMMV,我几乎从来没有让 gcc 做这个额外的工作,如果我能避免它更喜欢直接调用它们,我让 gcc 调用汇编程序以使编译后的输出成为一个对象, 但除此之外... 只需在没有选项的情况下运行 gcc 即可为您提供第一级帮助,然后它们会显示您可以获得帮助并深入研究的其他内容(例如将参数传递给链接器或汇编器)。

相关文章: