标签: cortex-m3

将arm cm3汇编代码从flash重新定位到ram

我有一个带有特殊类型FLASH存储器的Cortex M3部件.该部分在此FLASH上启动,但我需要运行一个函数来优化FLASH的速度.执行此操作的唯一方法是跳转到RAM并在那里执行这些功能(因为如果在正在优化的FLASH上运行,函数将崩溃).

ARM允许分散加载.这是一个解决方案,因为我可以将函数放入RAM并在我到达main后运行它们.但是我不想在没有优化的FLASH的情况下执行所有的分散加载.所以我想在main之前运行该函数,这意味着从重置处理程序,或从SystemInit(从重置处理程序调用).

我写了一些位于ROM中的汇编函数.在启动时,我调用我写的Relocate函数,然后将其他函数复制到RAM,然后我跳转到它们.这很有效.

我的问题是:

  1. 这听起来很疯狂吗?有没有更简单的方法来实现这一点(无需等待分散加载)?
  2. 在.s文件中,我有我将重新定位的函数.要使用这些重定位函数,我加载PROC标签,然后减去(FLASH - RAM)的偏移量.这感觉不便携.是否有另一种方法来计算重定位函数的正确PROC地址?例如:

    foo     PROC
            ...
            ...
            ENDP
    
    Run Code Online (Sandbox Code Playgroud)

foo从0x24000000的ROM开始,我需要将其移动到0x8000的RAM.有没有办法声明foo存在于0x8000,即使它必须存储在ROM中?或者有没有办法声明foo_reloc生活在0x8000?这也适用于THUMB代码,因为foo可能从0x24000001开始,需要在0x8001处调用.

谢谢,Nachum

assembly arm cortex-m3

3
推荐指数
1
解决办法
1688
查看次数

如何使用uvision(Keil)在cortexm3中重新定位向量表并更改起始地址?

我正在使用STM32F107 cortex m3微控制器。我正在为项目使用Keil uvision IDE。我有一个在起始位置即正确运行的应用程序0x0800 0000。如果我将起始位置更改0x0800 4000为应用程序,则无法正常工作。我使用此函数对向量表的位置进行了如下更改:

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8004000)
Run Code Online (Sandbox Code Playgroud)

即更改SCB->VTOR = 0x8004000到此位置。

但是即使执行完此中断也不会发生。我应该做更多的事情来使这个项目起作用吗?

arm cortex-m3 keil

3
推荐指数
1
解决办法
2万
查看次数

如何检查Cortex M3中是否启用了中断?

在Cortex M3上,一段代码如何确定是否启用了中断,即I程序状态寄存器中的位状态(由cpsid和操纵cpsie)?在较旧的ARM上,我能够读取cpsr寄存器,但似乎不再可能.

我需要这些信息,因为我有一个从main和中断调用的函数,它需要以原子方式执行某个操作,而中断则被禁用.实质上:

bool interrupts_enabled = InterruptsEnabled();
if (interrupts_enabled) {
    __disable_irq();
}
Critical Code;
if (interrupts_enabled) {
    __enable_irq();
}
Run Code Online (Sandbox Code Playgroud)

另外,我想知道I执行中断时标志的行为.执行中断是否会设置I标志,以防止嵌套?默认情况下是否启用了中断嵌套,如何防止嵌套?

embedded assembly arm interrupt cortex-m3

3
推荐指数
1
解决办法
3104
查看次数

为什么复位处理程序位于Cortex-A的0x0而不是Cortex-M3

是什么原因Cortex-M3的初始堆栈指针值位于0x0,复位处理程序位于0x4?这个的设计理由是什么?

为什么ARM人员不能像重置处理器那样将0x0留给重置处理程序,然后在重置处理程序内初始化SP?

microcontroller arm cortex-m3 cortex-a

3
推荐指数
1
解决办法
1097
查看次数

系统内存在 ARM 内存映射上的 STM32F103 中实际工作是什么?

现在我正在尝试了解 STM32F103x 的启动顺序。如您所知,这是基于 cortex-m3。所以我试图找到这个启动的概念,比如 STM32F103x .. 但是我在文档中找不到任何地方我在哪里可以在ARM 内存映射上找到作为 STM32 的启动序列?

因为我想知道系统内存实际上是做什么的?

目前。我试图了解 cortex m3 地址映射中的系统内存。大多数示例都说“有 2 个区域,例如 0x08000000 闪存区域和 0x1FFFF000 系统内存区域。

我知道闪存区域正在为执行文件保存,而系统内存正在为引导加载程序保存。

例如,我可以从在 Keil uVision 中使用 startup_CMSDK_CM3.s 和 startup_CMSDK_CM3.c 的构建生成一个十六进制二进制文件。然后我通过使用JTEG将一个十六进制二进制文件放入STM32 MCU中到闪存区域的0x0800_0000而不是系统内存区域。

我不确定系统内存和闪存之间的区别,我想知道“系统内存和区域实际上有什么作用?”

cortex-m3

3
推荐指数
1
解决办法
6453
查看次数

使用USB Bootloader时如何设置ARM用户应用程序起始地址?

刚刚从eBay上购买了这些ARM Cortex-M3 LPC1768迷你主板之一.它基本上是一个突破板.

但是,基于它带来的小文档,我已经确定它有一个类似于恩智浦 LPC1700辅助USB引导加载程序(AN10866)应用笔记所描述的USB引导加载程序.

这两个文档(应用笔记和电路板文档)都表明要构建用户程序,使其起始地址为0x2000.因为USB引导加载程序已经是0x0并占用8K.

这两个文档还显示了如何在Keil uVision中执行此操作的屏幕截图(请参阅应用说明的第14页),但我计划使用GNU工具链(Yagarto + Eclipse + OpenOCD).

在使用GNU工具链进行编译时,如何指定起始地址0x2000,以便它能够与USB引导程序一起正常工作?

embedded arm cortex-m3 bootloader

2
推荐指数
1
解决办法
1838
查看次数

ARM cortex m3 中的调用堆栈展开

我想创建一个调试工具来帮助我更好地调试我的应用程序。我正在工作(没有操作系统)。在 Atmel 的 SAM3 上使用 IAR 嵌入式工作台。

我有一个看门狗定时器,它会在超时的情况下调用特定的 IRQ(这将在发布时被软件重置替换)。在 IRQ 处理程序中,我想打印出(UART)堆栈跟踪,看门狗超时发生的确切位置。

我查看了网络,并没有找到该功能的任何实现。

任何人都知道如何处理这种事情?

编辑:好的,我设法从堆栈中获取返回地址,所以我确切地知道 WDT 超时发生的位置。展开整个堆栈并不像最初出现的那样简单,因为每个函数将不同数量的局部变量压入堆栈。

我最终得到的代码是这样的(对于其他人,可能会发现它有用)

void WDT_IrqHandler( void )
{
    uint32_t * WDT_Address;
    Wdt *pWdt = WDT ;
    volatile uint32_t dummy ;
    WDT_Address = (uint32_t *) __get_MSP() + 16 ;
    LogFatal ("Watchdog Timer timeout,The Return Address is %#X", *WDT_Address);
    /* Clear status bit to acknowledge interrupt */
    dummy = pWdt->WDT_SR ;

}
Run Code Online (Sandbox Code Playgroud)

c arm cortex-m3 stack-trace iar

2
推荐指数
1
解决办法
9411
查看次数

ARM Cortex-M3启动代码

我正在尝试理解初始化代码如何与Keil(realview v4)一起用于STM32微控制器.具体来说,我试图了解堆栈是如何初始化的.

在ARM网站上的文档中,它提到startup_xxx.s中的一个例程,__user_initial_stack_heap不应该使用超过88个字节的堆栈.你知道这个限制来自哪里吗?

似乎当重置处理程序调用System_Init时,它正在C环境中执行一些函数,我相信这意味着它正在使用某种形式的临时堆栈(它分配了一些自动变量).但是,所有这些堆栈项目一旦返回就应该超出范围,然后调用从__main哪里__user_initial_stack_heap调用.

那么为什么__user_initial_stack_heap不要使用超过88个字节的这个要求呢?剩下的__main使用了大量的堆栈还是什么?

任何与启动序列相关的cortex-m3堆栈架构的解释都会很棒.

embedded arm cpu-architecture cortex-m3

2
推荐指数
1
解决办法
2458
查看次数

在复位皮质 m3 上保留一些 RAM 值

单击板上或 Kiel 上的重置按钮后,有没有办法保留一些 ram 值或全局变量

我正在使用 STM32L152ZE

embedded microcontroller cortex-m3 stm32 stm32l152

2
推荐指数
1
解决办法
5480
查看次数

发生异常时如何设置回调函数?

在发生异常时,我已经停留了一段时间来设置回调.

我有这个测试代码:

void main()
{
    long * bad = (long*)0x0A000000; //Invalid address

    //When the following line gets executed 
    //it causes an error and the debugger sends me to an assembly file. 
    *bad = 123456789; 
}
Run Code Online (Sandbox Code Playgroud)

我发送的程序集文件看起来像这样(真实文件的片段):

.macro DEFAULT_ISR_HANDLER name=
  .thumb_func
  .weak \name
\name:
1: b 1b /* endless loop */
.endm

DEFAULT_ISR_HANDLER SRC_IRQHandler   /*Debugger stops on this line*/
Run Code Online (Sandbox Code Playgroud)

据我所知,DEFAULT_ISR_HANDLER是一个定义无限循环的宏.我想要做的是在C文件中定义我自己的函数,我可以在发生异常时调用,而不是调用DEFAULT_ISR_HANDLER宏中定义的whats.

我的问题是,如何在该程序集中定义一个调用特定C函数的宏?

希望我解释自己.欢迎任何有关此主题的信息或指示.

如果它是相关的我使用GCC ARM编译器v5.4_2016q3

谢谢,艾萨克

编辑

我正在使用Cortex-M3.

直到现在我才意识到我在谈论处理器异常.根据数据表,有一个包含16种异常类型的列表.

显然,它的工作方式是将所有异常类型重定向到宏,后者又调用一些拇指函数,然后调用无限循环(根据代码中的DEFAULT_ISR_HANDLER).

我想要做的是在C文件中定义我自己的函数,为方便起见,所以每次出现任何类型的处理器异常时,我都可以控制如何继续.

c assembly exception-handling cortex-m3

2
推荐指数
1
解决办法
351
查看次数