GNU LD 链接器命令语言有条件语句吗?
背景:我正在为 ARM Cortex m0+ 开发固件,它由引导加载程序和应用程序组成。两者都在单独的项目中进行编译和刷新以定位目标,但我使用一个带有驱动程序、makefile 和加载器脚本符号链接的框架,这样我就可以为我制作的每个应用程序重复使用这些文件,而无需为每个应用程序复制这些文件。目前我有两个加载程序文件,分别用于引导加载程序和应用程序(makefile 自动指定相应的文件),内存分配如下:
引导装载程序
MEMORY {
flash (rx) : ORIGIN = 0x00000000, LENGTH = 16K
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
Run Code Online (Sandbox Code Playgroud)
应用程序
MEMORY {
flash (rx) : ORIGIN = 0x00004000, LENGTH = 112K
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
Run Code Online (Sandbox Code Playgroud)
就像 makefile 一样,我想将它们合并为类似的内容(使用 C 表达式来澄清)
MEMORY {
#ifdef(bootloaderSymbol)
flash (rx) : ORIGIN = 0x00000000, LENGTH = 16K
#else
flash (rx) : ORIGIN = 0x00004000, LENGTH = …Run Code Online (Sandbox Code Playgroud) Cortex M3处理器有两个堆栈指针:PSP、MSP。在一些复杂的应用中,用户程序使用PSP指向用户程序堆栈。异常处理程序使用 MSP 指向主堆栈。
问题是:用户程序运行时发生中断。在进入中断处理程序之前,R0-R3、R12、LR、PC 和 xPSR 寄存器将被压入堆栈。但是使用哪个堆栈来存储这些寄存器呢?
我试图找到一种好方法来将变量与32位或16位的GCC对齐.
我正在研究一种不支持未对齐数据访问的Cortex-M0.我使用时遇到这个问题-Os.我使用arm-none-eabi版本4.6.2.我有这个小测试用例:
#include "stdint.h"
typedef struct Struct_HdrPrefix{
uint8_t Prefix;
uint16_t Type;
}__attribute((packed))Struct_HdrPrefix;
volatile Struct_HdrPrefix test;
volatile Struct_HdrPrefix test1;
int main(void)
{
test.Type = 0;
while(1)
__asm("nop");
}
void HardFault_Handler(void)
{
while(1)
__asm("nop");
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,我得到一个非对齐的变量测试.
这是地图文件中的结果:
COMMON 0x20000000 0x6 ./SRC/main.o
0x20000000 test1
0x20000003 test
Run Code Online (Sandbox Code Playgroud)
所以现在我陷入了困境.如果我将此添加到vars:
volatile Struct_HdrPrefix test __attribute((aligned (4)));
volatile Struct_HdrPrefix test1 __attribute((aligned (4)));
Run Code Online (Sandbox Code Playgroud)
这是按预期工作的,因为test现在已经调整好了.
我不能在结构上使用align属性,因为这个结构也可能是另一个结构的一部分.
有没有办法告诉GCC或LD在32位边界上对齐打包变量?
问候
我正在尝试调试我为恩智浦LPC1850评估板编写的一些软件.此刻,当我暂停我的代码时,我无法看到它在我的C代码中的位置,但我可以在反汇编窗口中.
它挂在的线是地址0x40.指令是BN.我在ARM信息中心查了一下,但我对汇编程序一无所知,我担心即使在阅读它之后对我来说也没什么意义.
0x0: 0x9ff0 LDR R7, [SP, #0x3c0]
0x2: 0x1008 ASRS R0, R1, #32
0x4: 0x2bad CMP R3, #173 ; 0xad
0x6: 0x1040 ASRS R0, R0, #1
0x8: 0x0041 LSLS R1, R0, #1
0xa: 0x1040 ASRS R0, R0, #1
0xc: 0x0043 LSLS R3, R0, #1
0xe: 0x1040 ASRS R0, R0, #1
0x10: 0x0045 LSLS R5, R0, #1
0x12: 0x1040 ASRS R0, R0, #1
0x14: 0x0047 LSLS R7, R0, #1
0x16: 0x1040 ASRS R0, R0, #1
0x18: 0x0049 LSLS R1, R1, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用STM32F030K6T6微控制器创建电路,但我不确定一件事。
只有BOOT0引脚(没有BOOT1),也许我是盲目的,但是我在ST文档中找不到关于此引脚的描述(我在“ DoclD024849 Rev 1”文档中查找该文档,该文档是上述uC的数据表)。
我发现的一件事是关于一对BOOT引脚的描述,如下所示(基于“ DoclD018940 Rev 5”-RM0091参考手册文档):
BOOT0 = 0 BOOT1 = x-主闪存启动
BOOT0 = 1 BOOT1 = 0-系统存储器启动(引导加载程序)
BOOT0 = 1 BOOT1 = 1-RAM存储器
我想做的是通过SWD编程芯片,我不确定要用BOOT0引脚做什么。
问题是:我应该上拉该引脚吗?在这种情况下,BOOT1的默认值是多少?
.syntax unified
.thumb
.cpu cortex-m4
.arch armv7e-m
.fpu fpv4-sp-d16
/* Changes from unprivileged to privileged mode. */
.thumb_func
.section .kernel
.global raise_privilege
.type raise_privilege, %function
raise_privilege:
mrs r0, control
bic r0, r0, #1
msr control, r0
dsb
isb
bx lr
Run Code Online (Sandbox Code Playgroud)
这是手臂组装代码的一部分.我可以查看芯片手册来弄清楚说明的含义.但我不知道如何弄清楚汇编程序指令的行为.thumb_func.更重要的是,我也不知道如何使用这部分代码,它看起来不像常规功能.所以我不知道如何"召唤"它.
是否可以在ARM Cortex-M4架构(例如STM32 F4)上分离基本FW和应用程序代码.我想做的是从外部闪存运行应用程序和从内部闪存基础FW.应用程序都实现相同的"API"(单头文件),但功能不同.
想法是基础FW提供驱动程序,引擎和UI,并且可以作为独立工作.应用程序将在需要时为FW提供额外的功能.由于所有应用程序的总代码大小对于内部闪存而言太大,因此无法在内部闪存上刷新所有应用程序.另一个原因是我们想要在不重新刷新设备的情况下即时更新/添加应用程序.
所以,到目前为止我几乎没有想法如何做到这一点,但这些是否可行或有其他选择吗?
所有提示,提示和示例代码均受到赞赏!
编辑:谢谢你的答案,需要一些时间来消化这些.
此试验的主要原因是允许在不刷新基本FW的情况下更新设备功能,而不是保存SRAM /内部闪存.一种插件架构,提供简单的界面来扩展系统功能,而无需改变底层系统.如果我无法从外部闪存(SD卡,NAND)构建系统执行代码,我将尝试首先将应用程序加载到SRAM /内部闪存.但我也会深入挖掘emcraft解决方案.
没有必要坚持STM芯片,我恰好在我的桌子上有他们的devkits.最终目标是从SD卡或NAND内存加载应用程序,所以在这一点上我不想限制实现仅适用于NOR闪存.
我将通过使用STM32 F4 devkit开始使用最少的实现.首先,我需要在其上包装一些NAND/SD卡.我将尝试将应用程序加载到SRAM和内部闪存的两个选项,以查看它们的工作原理以及对性能的影响.正如Clifford所说,在链接,构建和工具集设置方面将面临更多挑战.即使是强硬的我也可以强迫应用程序在内存中始终保持相同的位置,功能将在不同的地方,需要弄清楚如何处理这个问题.示例/演示将有所帮助.
我最小化实现的规范.
Project 1: Base FW
Driver for accessing applications from external flash
Minimal filesystem to write and read applications to/from external flash
UART commands -- Write applications to external flash -- Load applications from external flash to SRAM/Internal flash -- Execute application and print result to UART
Interface.h
int functionWrapper(int functionNumber)
bool initApplication()
int executeMathOperation1(int a, int …Run Code Online (Sandbox Code Playgroud) 我想知道ARM Cortex-M4内部是否有缓存。
我在技术参考手册中没有找到任何线索,但这是官方的还是隐藏的?我知道有些微控制器有缓存,但它位于总线和 RAM 之间,而不是内核内部。
你知道有什么文件可以澄清这一点吗?
我使用DWT-> CYCCNT检查了核心周期计数。但与我的预测不同。你能告诉我原因吗?
我的设备是STM32 NUCLEO-L476RG。我只是检查DWT-> CYCCNT。并且只更改了整数分配的次数。
m_nStart = DWT->CYCCNT;
m_nStop = DWT->CYCCNT;
printf("Cycle diff - assign 0 : %lu\n", m_nStop - m_nStart);
m_nStart = DWT->CYCCNT;
i = 10;
m_nStop = DWT->CYCCNT;
printf("Cycle diff - assign 1 : %lu\n", m_nStop - m_nStart);
m_nStart = DWT->CYCCNT;
i = 10;
i = 20;
m_nStop = DWT->CYCCNT;
printf("Cycle diff - assign 2 : %lu\n", m_nStop - m_nStart);
m_nStart = DWT->CYCCNT;
i = 10;
i = 20;
i = 30;
m_nStop = DWT->CYCCNT;
printf("Cycle diff - …Run Code Online (Sandbox Code Playgroud) 我正在使用IAR Embedded Workbench开发ARM Cortex-M4处理器。当主堆栈溢出时,我会遇到总线故障。因此,我在汇编中编写了一个小函数来检查总线故障是否是由堆栈溢出引起的,设置堆栈指针并调用专用的堆栈溢出处理程序。
以下代码显示了该功能,并且可以正常工作。我的问题是我必须从两个LDR指令的标签中减去1,但我不明白为什么。
StackBegin: DC32 SFB(CSTACK) ; Start of main stack
StackEnd: DC32 SFE(CSTACK) ; End of main stack
BusFault_Handler:
LDR R0, StackBegin-1 ; No idea why we need to subtract 1
CMP SP, R0
IT GT
BGT BusFault_Post_Handler ; Call if SP is OK
LDR SP, StackEnd-1 ; On stack overflow, set SP to top of main stack; No idea why we need to subtract 1
B MainStackOverflow_Handler
Run Code Online (Sandbox Code Playgroud)
如果我不减去1,LDR指令将在标签后的一个字节加载数据。StackEnd包含值0x20000400,但是SP加载了0x5F200004,除非我从标签中减去1。0x5F是BusFault_Handler中的第一个字节。
谁能解释为什么我需要减去1.我配置错误吗?我检查了数据是否已字(4字节)对齐。