TL; DR:
(unsigned long)(0x400253FC)等同(unsigned long)((*((volatile unsigned long *)0x400253FC)))?我正在使用ARM Cortex-M3处理器,TI 的LM3S6965,以及他们的StellarisWare(免费下载,出口控制)定义.我正在使用gcc版本4.6.1(Sourcery CodeBench Lite 2011.09-69).Stellaris在"inc/lm3s6965.h"中提供了大约5,000个寄存器和内存地址的定义,我真的不想重做所有这些.但是,它们似乎与我想写的宏不兼容.
在ARM Cortex-M3上,一部分内存的别名为外设和RAM内存空间的每位32位字.将地址0x42000000的存储器设置为0x00000001会将地址0x40000000的存储器的第一位设置为1,但不会影响字的其余部分.要更改位2,请将0x42000004处的字更改为1.这是一个简洁的功能,非常有用.根据ARM技术参考手册,计算地址的算法是:
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
Run Code Online (Sandbox Code Playgroud)
哪里:
bit_word_offset 是位带存储区中目标位的位置.bit_word_addr 是别名内存区域中映射到目标位的字的地址.bit_band_base 是别名区域的起始地址.byte_offset 是包含目标位的位带区域中的字节数.bit_number 是目标位的位位置0到7该"inc/hw_types.h"文件包含以下实现此算法的宏.为了清楚起见,它为基于字的模型实现它,该模型接受4字节对齐的字和0-31位的偏移,但结果地址是等效的:
#define HWREGBITB(x, b) \
HWREGB(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \
(((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))
Run Code Online (Sandbox Code Playgroud)
该算法采用SRAM中的基数为0x20000000或外围存储空间为0x40000000),并将其与0x02000000进行或运算,并添加位带基址偏移量.然后,它将偏移量与基数相乘32(相当于左移五位)并加上位数. …
基本上,我很难使执行时间比实际时间要短,并且要减少时钟周期和内存大小。有谁知道我该怎么做吗?代码工作正常,我只想稍作更改。
编写了有效的代码,但不想弄乱代码,但也不知道要进行哪些更改。
; Calculation of a factorial value using a simple loop
; set up the exception addresses
THUMB
AREA RESET, CODE, READONLY
EXPORT __Vectors
EXPORT Reset_Handler
__Vectors
DCD 0x00180000 ; top of the stack
DCD Reset_Handler ; reset vector - where the program starts
AREA 2a_Code, CODE, READONLY
Reset_Handler
ENTRY
start
MOV r1,#0 ; count the number of multiplications performed
MOV r2,#3 ; the final value in the factorial calculation
MOV r3,#1 ; the factorial result will be stored …Run Code Online (Sandbox Code Playgroud) 我正在使用以下代码为 ARM 执行简单的基于计数器的延迟/等待:
.thumb_func
dowait:
ldr r7,=0x200000
dowaitloop:
sub r7,#1
bne dowaitloop
bx lr
Run Code Online (Sandbox Code Playgroud)
我从 dwelch 的blinker01 mbed_samples获得了这个函数,它在其他 LED 闪烁类型的示例程序中运行良好。但是,我目前正在处理的程序需要.syntax unified位于顶部,因为我使用的是 Thumb-2 指令(例如 ITTEE)。
我怀疑“.syntax统一”是问题所在,因为我采用了已知工作的blinker01示例并添加了.syntax unified它,当我上传到我的电路板时它不再工作。
虽然我还没有弄清楚所有的gdb 东西来证明它,但该函数似乎没有计算/延迟。
是否有不同的方法来重新编写这个“延迟”函数以使用统一的/Thumb-2 语法?
这是我的代码:
volatile uint32_t value = *((volatile uint32_t *) 0xA0000000); // here `value` is 12498
value *= 2; // here `value` is still 12498
value |= 0x0000001; // still 12498
Run Code Online (Sandbox Code Playgroud)
value在我的调试器中分析变量时,它在所有行上保持相同的值.我究竟做错了什么?
我正在学习使用基于arm cortex m3的MCU STM32f100RB.为了测试定时器6,我写了一些代码,如下所示.它应该使LED闪烁.但它不起作用.任何人都可以帮我告诉我什么是问题?定时器是否正确初始化?谢谢
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
void delay_millisec(register unsigned short n);
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB1Periph_TIM6, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //enable the pin 8 and pin 9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
while(1)
{
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
delay_millisec(1000);
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
delay_millisec(1000);
}
return 0;
}
void delay_millisec(register unsigned short n)
{
if (n > 1) n--;
TIM6->PSC = 23999; // Set prescaler to 24,000 (PSC + …Run Code Online (Sandbox Code Playgroud) 背景:
我使用的是没有操作系统的cortex-M3 ARM内核.
我的主循环等待来自中断处理程序的标志然后执行一个函数doBigTask().
在一个单独的中断处理程序中,我想执行另一个函数doSmallTask(),但由于这个函数也非常重要,我仍然希望处理其他与I/O相关的中断.
我的问题:
从内部简单地启用中断是否存在任何问题doSmallTask()?例如,在中断已经被禁用后退出中断处理程序是否有任何复杂性?
注意:我不希望发生重入中断,因为doSmallTask()在下一个中断触发它之前就会完成.
int flag = 0;
void doSmallTask()
{
asm volatile ("cpsie i"); // Enable interrupts
// do rest of function
// ...
}
void irqHandler1()
{
flag = 1;
}
void irqHandler2()
{
doSmallTask();
}
void irqHandler3()
{
// service I/O
}
int main()
{
while(1)
if (flag)
{
doBigTask();
flag = 0;
}
}
Run Code Online (Sandbox Code Playgroud) 我正在将一些代码从M3移植到使用3个NOP的M4,以在串行输出时钟更改之间提供非常短的延迟。M3指令集将NOP的时间定义为1个周期。我注意到M4中的NOP不一定会延迟任何时间。我知道我将需要禁用编译器优化,但是我正在寻找一个低级命令,该命令将给我可靠,可重复的时间。实际上,在这种特殊情况下,串行经常被使用,并且速度可能很慢,但是我仍然想知道获得周期级延迟的最佳方法。
我最近遇到了一个只在中断处理程序中被修改的变量的问题.变量本身并未声明为volatile,因此在更高的优化级别下,编译器会破坏代码.但是,编译器足够聪明,可以编译中断代码,因为中断仍会触发.
所以这是我的问题:
如果编译器足够聪明以编译中断代码,为什么它不够聪明才能意识到变量在该中断内被改变了?
在更高的优化级别,未调用的函数会被优化.由于没有代码调用中断处理程序,因此它应该被优化掉.什么原因导致编译器编译中断代码?
我们有一个论文项目正在工作,他们正试图让外部 RAM 为 STM32F417 MCU 工作。该项目正在尝试一些真正需要资源且内部 RAM 不够的东西。
问题是如何最好地做到这一点。
当前的方法只是将链接脚本 (gnu ld) 中的 RAM 地址替换为外部 RAM 的地址。
这种方法的问题在于,在初始化期间,由于 FSMC 尚未初始化,因此芯片必须在内部 RAM 上运行。
它似乎可以工作,但是一旦 pvPortMalloc 运行,我们就会遇到一个硬错误,这可能是由于取消引用虚假地址,我们可以看到变量在系统初始化时没有正确初始化(我猜这是有道理的,因为内部 RAM 不是完全使用,可能应该使用)。
我意识到这是一个模糊的问题,但是在 Cortex M4 MCU(更具体地说是 STM32F4)上的外部 RAM 中运行代码时,一般的方法是什么?
谢谢
我在cortex m3指南中找到了两个陈述(红皮书)1.Cortex m3同时支持Little和big endianess.2.复位后,endianess不能动态更改.
所以它间接地告诉重置处理程序中的更改endianess设置,是这样吗?
如果是,那么如何改变endianess.我需要配置哪些寄存器以及配置位置(在复位或异常处理程序中)
改变endianess实际上并不是一个好主意但是作为一个好奇心我想看看cortex m3是否真的支持这两个endianess?
我想知道在基于ARM M3的MCU上,使用VTOR寄存器重定位向量表有什么好处?我理解的原因是:
这是否意味着如果在编译期间定义并知道所有中断处理程序,则根本不需要使用VTOR?
有没有办法禁用Cortex M3 MCU中的所有irq,除了一个?
我的问题是我有一个系统运行几种具有不同优先级的irq,我想禁用所有irq,除了特定状态的irq.
我知道我可以通过使用"__disable_irq()"指令来禁用所有irq,但是如果我之前没有调用"__enable_irq()",则在调用此指令后我无法启用一个irq.
谢谢你的帮助,
问候