我正在调试ARM的代码源版本的gdb(即arm-none-eabi-gdb)并尝试生成核心文件以供以后检查.OpenOCD是我的GDB目标.所有gdb告诉我,当我运行'gcore'或'generate-core-file'时,"无法创建corefile".有什么建议?通常可以使用远程目标进行核心转储吗?
我们有一个设备,我想使用printf函数向IDE发送消息以进行调试.设置:
ARM Cortex-M3设备
ULINK2接口
uVision4 IDE
我已按照此链接中的说明操作,以便能够在"Debug(printf)Viewer"中查看消息.首先,我修改了"retarget.c"文件,将输出重定向到ITM界面:
#include <stdio.h>
#include <rt_misc.h>
#pragma import(__use_no_semihosting_swi)
// Para utilização do saida de debug através do ULINK2
#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA 0x01000000
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
// Escreve caractere na porta de Debug
int sendchar (int ch) { …
Run Code Online (Sandbox Code Playgroud) 鉴于此,在ARM Cortex M3上,我可以:
如何将这些组合用于互斥体式操作集:
try lock
take lock
release lock
Run Code Online (Sandbox Code Playgroud)
似乎try_lock
或者take_lock
需要两个不是原子的操作.
我需要更多控制才能实现这一目标吗?禁用全局中断会这样做,但似乎应该有更多的手术方法.
我在LPC1754,59和68 + FreeRTOS + CMSIS 上运行固件.
我希望能够将微控制器置于最低功耗模式,但是:
据我在" LPC17xx用户手册 "(第58,59页)中所读到的,我应该可以从EINT3唤醒到"断电"模式.
我错过了什么?是否在低功率时产生中断?怎么说?我应该做任何特定的东西才能生成它吗?
编辑:
在gcc的CMSIS定义中,您可以找到如下内容:
static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }
Run Code Online (Sandbox Code Playgroud)
我的问题是:如果内存障碍没有在clobber列表中声明"内存",它有什么用?
它是core_cm3.h中的错误还是有一个原因导致gcc在没有任何其他帮助的情况下应该正常运行?
我有一个关于在 cortex m3 中使用信号量的问题。我找到了一个线程“ARM cortex: mutex using bit banding” ARM cortex: mutex using bit banding。有一个问题的简短描述,最后一个答案对我的问题很有用 - 但我不确定如何在 c/c++ 中实现它。
“我从来没有在 ARM 上使用过位带;相反,我倾向于对所有这些操作使用负载独占/存储条件。使用循环来负载独占旧值,计算新值,然后使用一个条件存储来写回它。循环直到条件存储成功(如果不是第一次,它可能会第二次成功)。”
如果有人可以发布如何使用它的简短代码,我将不胜感激。
谢谢,马丁
我正在为STM32Fx cortex-M3系列处理器开发一个程序.在stdint.h中定义了以下内容:
typedef unsigned int uint_fast32_t;
typedef uint32_t uint_least32_t;
typedef unsigned long uint32_t;
Run Code Online (Sandbox Code Playgroud)
据我了解.
[u]int_fast[n]_t will give you the fastest data type of at least n bits.
[u]int_least[n]_t will give you the smallest data type of at least n bits.
[u]int[n]_t will give you the data type of exactly n bits.
Run Code Online (Sandbox Code Playgroud)
据我所知sizeof(unsigned int)<= sizeof(unsigned long)和UINT_MAX <= ULONG_MAX - 总是如此.
因此,我希望uint_fast32_t是一个大小等于或大于uint32_t大小的数据类型.
在cortex-M3 sizeof(unsigned int)== sizeof(unsigned long)== 4的情况下.因此上述定义在大小方面是"正确的".
但是为什么它们没有以与基础数据类型的名称和逻辑大小一致的方式定义,即
typedef unsigned long uint_fast32_t;
typedef unsigned int uint_least32_t;
typedef uint_fast32_t uint32_t;
Run Code Online (Sandbox Code Playgroud)
有人可以澄清基础类型的选择吗?
鉴于'long'和'int'的大小相同,为什么不对所有三个定义使用相同的数据类型? …
临时解决方法
我使用微小的printf解决了这个问题:
可能newlib printf占用了太多内存。此后,PC会更改一些奇怪的东西,从理论上讲,这应该是数组的结尾char[100]
。
cp = buf + BUF
Run Code Online (Sandbox Code Playgroud)
稍后它尝试执行
*--cp = something
Run Code Online (Sandbox Code Playgroud)
它崩溃了。内存错误?有很多我不理解的事情。例如,我不确定链接描述文件是否正确,或者syscall函数是否正确。在获得进一步的了解之前,我必须坚持使用小巧的printf。
原版的
我有一个STM32F103RB板(Nucleo),而USART1才可以工作。另外,我测试了Newlib函数,并按puts()
预期工作。但是,当我尝试printf()
用于整数时,如下所示:
printf("ADC: %d\r\n", test);
Run Code Online (Sandbox Code Playgroud)
如果test < 10
程序正常运行,但是test >= 10
产生了严重故障。经过一些GDB调试后,我发现它是从vfprintf生成的:
#0 HardFault_Handler () at main.c:136
#1 <signal handler called>
#2 0x08005af4 in _vfprintf_r (data=<optimized out>, fp=0x20000384 <impure_data+852>, fmt0=fmt0@entry=0x20004f57 " \254\264", ap=...,
ap@entry=...) at ../../../../../../newlib/libc/stdio/vfprintf.c:1601
#3 0x08004fd0 in printf (fmt=0x800b4ac "ADC: %d\n\r") at ../../../../../../newlib/libc/stdio/printf.c:52
#4 0x080004e8 in main () at main.c:168
Run Code Online (Sandbox Code Playgroud)
我想不出任何解决方案。这是我的_sbrk()
:
caddr_t …
Run Code Online (Sandbox Code Playgroud) 我试图在cortex-m3控制器上实现以下伪代码,(特别是STM32L151)
void SysTick_Handler() {
do_high_priority_periodic_tasks(); // not to be interrupted
lower_interrupt_priority();
do_low_priority_periodic_tasks(); // these may be interrupted
}
Run Code Online (Sandbox Code Playgroud)
换句话说,运行优先级为0的第一部分,然后以某种方式将当前中断优先级降低到15,以便其余部分可以被其他硬件中断抢占.
一个想法是do_low_priority_periodic_tasks();
进入一个单独的中断处理程序,并调用此处理程序,通过该处理程序NVIC_SetPendingIRQ()
设置NVIC->ISPR[]
寄存器中的挂起位.这样,其他中断将紧随其后SysTick
,除非有任何优先级在0和14之间的待处理.
#define LOWPRIO_IRQn 55
void IRQ55_Handler() {
do_low_priority_periodic_tasks(); // these may be interrupted
}
void SysTick_Handler() {
do_high_priority_periodic_tasks(); // not to be interrupted
NVIC_SetPendingIRQ(LOWPRIO_IRQ);
}
void main() {
HAL_Init();
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
HAL_NVIC_SetPriority(LOWPRIO_IRQn, 15, 0);
HAL_NVIC_EnableIRQ(LOWPRIO_IRQn);
while(1) {
/* main loop */
}
}
Run Code Online (Sandbox Code Playgroud)
我已经选择了IRQ 55因为它没有占用我的控制器,它将是STM32L162上的AES中断处理程序,但我有点担心.我应该选择不同的IRQ,也许是未使用的DMA通道中断?使用Cortex-M3内核定义的中断57-67是否安全,而STM32L系列中没有?有没有更好的方法呢?
我有一个32位的Cortex-M3 ARM控制器(STM32L1),其可以通过异步中断处理程序来修改在64位整数的变量。
volatile uint64_t v;
void some_interrupt_handler() {
v = v + something;
}
Run Code Online (Sandbox Code Playgroud)
显然,我需要一种访问方式,以防止获取不一致的中途更新值。
这是第一次尝试
static inline uint64_t read_volatile_uint64(volatile uint64_t *x) {
uint64_t y;
__disable_irq();
y = *x;
__enable_irq();
return y;
}
Run Code Online (Sandbox Code Playgroud)
该CMSIS内联函数__disable_irq()
,并__enable_irq()
有一个不幸的副作用,迫使编译器内存屏障,所以我试图拿出一些更精致
static inline uint64_t read_volatile_uint64(volatile uint64_t *x) {
uint64_t y;
asm ( "cpsid i\n"
"ldrd %[value], %[addr]\n"
"cpsie i\n"
: [value]"=r"(y) : [addr]"m"(*x));
return y;
}
Run Code Online (Sandbox Code Playgroud)
它仍然禁用中断,这是不希望的,因此我想知道是否有一种方法可以不诉诸cpsid
。该权威指南的ARM Cortex-M3和Cortex-M4处理器,第三版由约瑟夫·耀说
如果在处理器执行多周期指令(例如整数除法)时中断请求到达,则该中断处理程序完成后,该指令可能会被放弃并重新启动。这种行为也适用于装载双字(LDRD)和存储双字(STRD)指令。
这是否意味着我只要写一下就可以了?
static inline uint64_t read_volatile_uint64(volatile uint64_t *x) {
uint64_t y; …
Run Code Online (Sandbox Code Playgroud)