Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将结构的地址添加到二进制链接器输出_C_Gcc_Linker_Arm_Bare Metal - Fatal编程技术网

C 如何将结构的地址添加到二进制链接器输出

C 如何将结构的地址添加到二进制链接器输出,c,gcc,linker,arm,bare-metal,C,Gcc,Linker,Arm,Bare Metal,这似乎是一个奇怪的问题,但我正在生成一个二进制文件,需要在头中放入一些数据 我正在使用gcc和一个相当标准的Cortex M4裸体链接器脚本 我没有将ISR向量放在二进制文件的第一位,而是放在我自己的头上。二进制文件将被复制到预先确定的内存位置(0x20008000,它已链接到该位置)并从那里运行 我的startup.s包含以下内容: .section .isr_vector,"a",%progbits .type g_pfnVectors, %object .size g_pfnVect

这似乎是一个奇怪的问题,但我正在生成一个二进制文件,需要在头中放入一些数据

我正在使用gcc和一个相当标准的Cortex M4裸体链接器脚本

我没有将ISR向量放在二进制文件的第一位,而是放在我自己的头上。二进制文件将被复制到预先确定的内存位置(0x20008000,它已链接到该位置)并从那里运行

我的startup.s包含以下内容:

.section  .isr_vector,"a",%progbits
.type  g_pfnVectors, %object
.size  g_pfnVectors, .-g_pfnVectors    

g_pfnVectors:
  .word 0xDADAC0DE       /* magic number */
  .word .isr_vector      /* link base address */
  .word Reset_Handler    /* code entry point */
  .word _end             /* stack start */
  .word _estack          /* stack end */
  .word ProgramVector    /* pointer to shared memory block */
除了ProgramVector之外,这一切都很好。我在main.c中对其定义如下:

 typedef struct {
     uint8_t checksum;
     int16_t* audio_input;
     int16_t* audio_output;
...
   } SharedMemory;

  SharedMemory ProgramVector;
我希望二进制文件包含ProgramVector的地址。如果将输出与链接器映射文件中的内容进行比较,则所有内容都匹配(Reset\u Handler、\u end、\u estack),但不匹配ProgramVector

我的二进制文件
app.bin

00000000  de c0 da da 00 80 00 20  0d 9a 00 20 d8 ce 00 20  |....... ... ... |
00000010  00 c0 01 20 60 ce 00 20  60 ce 00 20 4f 57 4c 20  |... `.. `.. OWL |
00000020  50 72 6f 67 72 61 6d 00  10 b5 05 4c 23 78 33 b9  |Program....L#x3.|
从中我们可以确定
ProgramVector
为0x2000ce60,而我的地图文件显示:

                0x2001c000                _estack = 0x2001c000
...
     .bss           0x2000ae28       0x38 Build/main.o
                    0x2000ae28                ProgramVector
...
                0x2000ced8                PROVIDE (_end, .)
现在您可能会说ProgramVector不是指针,这是正确的。但是我希望链接器输出它所在的地址。如果将其设置为
SharedMemory*
指针,则输出具有指针的正确地址。问题是我需要结构的地址,在程序初始化之前我需要它

我尝试过使用各种编译器和链接器标志,但没有效果。当前编译如下所示:

arm-none-eabi-gcc -Wl,--gc-sections -TSource/flash.ld -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -o Build/app.elf Build/sta./Build/libnosys_gnu.o -lm
arm-none-eabi-objcopy -O binary Build/solo.elf Build/solo.bin

我可能错过了一些明显的东西,但我想弄清楚是什么让我发疯了。感谢您的帮助、指点或建议

您是否知道可以在
NVIC->VTOR
中更改向量表的基址?因此,您可以使用普通verctor表,只需在启动时重新映射即可。然而,我不得不猜测,因为问题不太清楚。如果您打算以另一种方式调用二进制文件,则需要一个调用实际程序代码的引导加载程序。这将驻留在不同的Flash secotr中,因此它不会受到更新常规固件的影响。它还会将
VTOR
设置为新条目(您需要该向量表,因为某些向量无法禁用(例如,硬故障)而且确实需要一个有效的矢量。感谢Olaf,并为缺少背景信息表示歉意-我不想把这个问题变成一本书!我确实有一个引导加载程序和固件,在一个单独的闪存扇区中有一个矢量表。该部分还使用单独的RAM;它加载并运行二进制文件。到目前为止,我一直保留着ProgramVectorNVRAM中的数据从两个程序访问:从一个程序运行的中断,从另一个程序运行的主线程。我想把它放在动态加载的程序中,部分是为了性能和方便,部分是为了更容易设置MPU。听起来对我来说太复杂了,但嘿,这是你的项目(我目前在M4上有一个类似的版本,并且使用了大量MPU).但我只是使用矢量重新定位;引导加载程序一旦通过控制就会处于非活动状态。这很复杂,但这是我能看到的唯一方法,它允许我在动态加载和运行DSP代码时保持USB连接和音频处理。嗯……所以你不需要更改中断矢量,只需动态加载/卸载DSP功能即可s?我希望典型的Cortex-M3的闪存足够大,可以一次存储所有数据;否则我更喜欢Cortex-A5或A7,这两个版本的容量不会太大。顺便说一句:对于DSP来说,M4可能更适合。这不仅是因为它的SIMD指令(对于分数大于16位的音频来说可能毫无价值),也因为它的FPU。