我有一个使用STM32F103(ARM Cortex M3)的嵌入式项目,它在发布模式下偶尔会遇到硬故障.作为恢复的一部分,我想从硬故障之前检索PC值并将其存储起来以便稍后在电池备份区域中进行调试.
如何在硬故障点确定程序计数器的值?显然,PC现在设置在硬故障中断的位置.
我应该在哪里看?它有一个普通模式寄存器组的地址吗?
谢谢!
我需要访问 Cortex-M3 处理器的 MSP 和 PSP 寄存器(主和进程堆栈寄存器)。
我正在用 C/C++ 编写。
µVision 和相关的编译器不允许您为这个仅限 Thumb-2 的内核进行内联汇编(而且我不确定这是否是一个好主意)。
我需要这样做,以便我可以提取 svc 指令的立即值,而不管它是在线程模式还是处理程序模式下执行的。
谢谢,
我的主板上的JTAG连接器上连接了一个Keil ULINK2 USB仿真器盒,它与板载Cortex-M3 CPU(TI/Stellaris/LuminaryMicro LM3S系列)配合使用.似乎JTAG和SWJ-DP端口在这些CPU上共享相同的引脚(以及板上的连接器).一个似乎没有ITM(printf)功能,另一个则没有.
以前的固件人员一直使用stdio到UART(串口),但我需要释放串口,这样调试消息不会干扰串口发送/接收的其他数据,因此我需要跟踪消息去其他地方.可悲的是,我在这块板上只有一个串口.我认为这个CPU中的ITM(跟踪)功能意味着我可以将调试printf消息直接发送到我的调试器/ IDE(Keil uVision).TI/Stellaris CPU文档将此功能称为"串行线JTAG调试端口(SWJ-DP)",我已经阅读过该支持,肯定是Keil uVision IDE中实现的功能.
在我的代码中添加printf消息会导致我的代码在我开始调试时锁定.锁定似乎在RTL库中,这些库链接到我的应用程序,在函数_sys_open中,在BKPT指令处:
_sys_open:
0x00009D7A B50E PUSH {r1-r3,lr}
0x00009D7C E9CD0100 STRD r0,r1,[sp,#0]
0x00009D80 F7FFFC0F BL.W strlen (0x000095A2)
0x00009D84 9002 STR r0,[sp,#0x08]
0x00009D86 4669 MOV r1,sp
0x00009D88 2001 MOVS r0,#0x01
>>0x00009D8A BEAB BKPT 0xAB
0x00009D8C BD0E POP {r1-r3,pc}
Run Code Online (Sandbox Code Playgroud)
以上似乎是被调用的代码的一部分__rt_lib_init_stdio_1
.
到底是怎么回事?我不知道BKPT做了什么.我假设它引发了一个软件断点,然后由调试器处理?是否应该为此配置Keil/ARM ULINK2软件和硬件?是否有一些技巧使调试printf与Keil JTAG/sw端口一起工作?
我不确定sw和JTAG端口之间的区别是什么.SW单元究竟,相信它指的是用于在基板上,其中,JTAG是无痕迹支撑一个典型的但更有限的模式中的JTAG物理连接器的两个可能模式中的一个,和SW模式增加了跟踪支持不添加任何引脚连接到JTAG连接器布局?但这是嵌入式系统,其中含糊不清是常态.我是Cortex-M3开发的新手,自从旧的ARM7TDMI时代以来,很多这些东西对我来说都是新的.但Keil uVision打印出这条消息:"ITM仅适用于SW端口,而不适用于JTAG".SW是否是您必须在电路板上设计的不同物理端口?(我使用的是定制设计的应用板,而不是开发启动板.)
[谷歌搜索让我了解的事实是_sys_open
,一些pragma __use_no_semihosting_swi
和其他东西密切参与这个难题,ROM中的BRKPT指令可能是SWI('软件中断')ARM指令中的某些ARM变体.
我写了(IMO)几乎最简单的ARM应用程序,它没有工作:)什么可能是错的?错过了什么?
闪存写入和CPU复位后,寄存器中有垃圾.
请善待,如果你知道,请告诉我在STM32F1上运行最简单的应用程序需要做些什么.
也许是某人可以列举在申请开始前必须做的事情,即.
应用程序:
@Directives
.thumb @.code 16
.syntax unified
.section .text
.org 0 @ Alters location of pointer - in this case set to zero
vectors: @ Define basic vectors for specific capabilities
.word _start + 1 @ Set - start address and increment pointer
.word _nmi_handler + 1 @ Below all other vectors will be declared:
.word _hard_fault + 1
.word _memory_fault + 1
.word _bus_fault + 1
.word _usage_fault + 1
_start:
mov …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个ARM Cortex-M3(SiLabs)SOC项目.我需要将中断向量[编辑]和代码从闪存底部移开,为"引导加载程序"腾出空间.当核心复位时,引导加载程序从地址0开始出现.它的功能是验证主图像,加载到更高的地址,并可能用新图像替换主图像.
因此,引导加载程序的向量表将为0,后跟其代码.在更高的固定地址(例如8KB)将是主要图像,从其向量表开始.
我找到了这个页面,它描述了引导加载程序可以使用的向量表偏移寄存器(显然屏蔽了中断)将硬件指向新的向量表.
我的问题是如何将"主"图像链接起来,以便在写入闪存时起作用,从零开始.我不熟悉ARM程序集,但我认为代码不是位置独立的.
我正在使用SiLabs的Precision32 IDE,它使用gcc作为工具链.我发现了如何添加链接器标志.我的问题是gcc标志将提供对向量表和代码的基础的更改.
谢谢.
我是MCU的新手,并试图弄清楚基于arm(Cortex M3-M4)的MCU是如何启动的.因为启动是针对任何SOC的,所以我采用了STM的示例硬件板进行案例研究.
主板:STMicroelectronics - STM32L476 32位.
在该板中,当引导模式为(x0)"从用户闪存引导"时,电路板将0x0000000
地址映射到闪存地址.在闪存上我已经粘贴了我的二进制文件,前4个字节指向矢量表第一个条目,即esp
.现在如果我按下复位按钮ARM文档说PC值将设置为0x00000000
.
CPU通常基于PC -> PC + 1
循环执行指令流.在这种情况下,如果我看到PC值指向esp
,这不是指令.Arm CPU如何做不使用该指令地址的逻辑,但跳转到地址处的值存储0x00000004
?
或者是这种情况:复位会产生一个特殊的硬件中断并导致PC值为at 0x00000004
,如果是这样的话,为什么Arm文档说它将PC值设置为0x00000000
?
参考:http://infocenter.arm.com/help/index.jsp?topic = / com.arm.doc.faqs/ka3761.html
上电复位后ARM寄存器中有哪些值?适用于:ARM1020/22E,ARM1026EJ-S,ARM1136,ARM720T,ARM7EJ-S,ARM7TDMI,ARM7TDMI-S,ARM920/922T,ARM926EJ-S,ARM940T,ARM946E-S,ARM966E-S,ARM9TDMI
应答寄存器R0-R14(包括存储寄存器)和SPSR(在所有模式下)在复位后未定义.
如果内核具有VINITHI或CFGHIVECS输入,当核心保持复位时,程序计数器(PC/R15)将被设置为0x000000或0xFFFF0000.应设置此输入以反映系统中矢量表的基础所在的位置.
当前程序状态寄存器(CPSR)将指示ARM内核已启动处于ARM状态,Supervisor模式同时设置了FIQ和IRQ掩码位.条件代码标志将是未定义的.有关CPSR的详细说明,请参阅"ARM体系结构手册".
我有一个来自Luminary Micro的RDK-IDM.该板具有32位ARM®Cortex ™-M3内核.有没有人试图在这样的设备上运行.NET Micro Framework应用程序?
当ARM Cortex-M3的GCC 4.7.3(20121207)获取函数的地址时,它无法获得函数的确切地址.我可以在那个指针中看到一个一个接一个.
// assume at address 0x00001204;
int foo() {
return 42;
}
void bar() {
int(*p)() = &foo; // p = 0x1205;
p(); // executed successfully
foo(); // assembly: "bl 0x00001204;"
}
Run Code Online (Sandbox Code Playgroud)
虽然指针指向奇数地址,但执行成功.我希望在这一点上有一个例外.为什么需要那个奇怪的地址以及它为什么不会受到伤害.
编辑
如何知道字中的字节是表示16位指令还是32位指令?
我提到了ARM ARMv7M,我不清楚如何区分它是16位指令还是32位指令.
它说
If bits [15:11] of the halfword being decoded take any of the following values, the halfword is the first halfword of a 32-bit instruction:
• 0b11101
• 0b11110
• 0b11111.
Otherwise, the halfword is a 16-bit instruction
这是否意味着处理器总是取半字,检查它们并决定它是16位还是32位?
前半字是什么意思?一个字中的位[31-16]或位[15-0]?
如果我有32位,那么我可以知道它是32位指令还是16位指令?
谢谢.
我正在使用 STM32F107VC 微控制器实现高频(> 100kHz)数据采集系统。它使用spi外设与高频ADC芯片进行通信。我必须使用实时操作系统。我怎样才能做到这一点?
我尝试过 FreeRTOS,但它的最大滴答频率为 1000Hz,所以我无法使用 FreeRTOS 每隔 1us 运行一个线程。我也试过Keil RTX5,它的tick频率可以达到1MHz,但我在某处研究过,不建议将tick频率设置高,因为它会增加整体上下文切换时间。所以我该怎么做?谢谢。