在Linux上编译c ++应用程序并在TI TIVA TM4C123GH6PM上进行闪存

时间:2017-05-18 09:52:33

标签: c++ linux makefile arm texas-instruments

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

我的Makefile看起来像这样:

/////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// //////////////////

IMPERAS_HOME:= $(shell getpath.exe“$(IMPERAS_HOME)”) 包括$(IMPERAS_HOME)/bin/Makefile.include

ifndef IMPERAS_HOME   IMPERAS_ERROR:= $(错误“IMPERAS_HOME未定义”) ENDIF

CROSS = ARM_CORTEX_M4F

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

优化= -Os

SRC = $(sort $(wildcard main.cpp))$(sort $(通配符Configuration / Configuration.cpp))$(sort $(通配符Segway / Simulation.cpp))$(sort $(通配符Segway / Segway.cpp))$(排序$(通配符传感器/ ADC.cpp))$(排序$(通配符传感器/ ADCSensor.cpp))$(排序$(通配符Antrieb / Motor.cpp))$(排序$(通配符)传感器/ GPIOSensor.cpp))$(排序$(通配符Timer / Timer.cpp))$(排序$(通配符Antrieb / PWM.cpp))

EXE = application.ARM_CORTEX_M4F.elf

全部:$(EXE)

%。elf:main.o Segway / Segway.o定时器/定时器传感器/ ADC.o传感器/ ADCSensor.o传感器/ GPIOSensor.o配置/配置.o Antrieb / Motor.o Antrieb / PWM.o     $(V)echo“#Linking $ @”     $(V)$(IMPERAS_LINKXX)-o $ @ $ ^ $(IMPERAS_LDFLAGS)

%。o:%。cpp     $(V)echo“#Compiling $<”     $(V)$(IMPERAS_CXX)-g -c -o $ @ $< $(OPTIMIZATION)-lm

清洁:     -rm -f * .elf * .o

realclean:干净     -rm -f * .log

/////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// //////////////////

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

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

如果您需要任何进一步的信息,请与我们联系。

谢谢!

约翰

1 个答案:

答案 0 :(得分:1)

生成文件

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

flash.ld

MEMORY
{
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

flash.s

.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

so.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或更小,同样在命令行而不是m4指定cortex-m0使其成为更通用,在这种情况下,它没有生成任何armv7-m thumb2扩展。

看看你的工具对于生成的so.eelf文件的说法,它确实比这更简单(删除bl notmain)并且只将flash.s链接到elf,但不比这简单得多。如果它不起作用,那么问题可能是别的,该工具可能正在寻找一些东西。如果这真的是一个tiva部分,那么也许lm4flash工具可以工作,你不需要任何guis,否则openocd应该工作,如果你有一个SWD解决方案(st核或发现板,或你在ti启动板上运行,或一个带有正确ftdi部分的jlink或ftdi breakoutboard(一个支持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会给你第一级帮助,然后他们会展示你可以获得帮助和挖掘的其他东西(比如将参数传递给链接器或汇编器)。