【发布时间】:2018-12-02 23:31:33
【问题描述】:
简介:我设计了一个具有ATSAME54N20A 32 位ARM® Cortex®-M4F MCU 的嵌入式系统。该板将很快组装并准备好进行编程,因此我正在设置我的编程环境。我选择了一个简单的解决方案,其中仅存在必要的最少 C 编写文件,因为虽然这是一个耗时的过程,但它有助于我理解系统的工作原理。选择的编译器是带有以下参数的 GCC:
"...\arm-none-eabi-gcc.exe" -x c -mthumb -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -c -std=gnu99 main.c -o main.o
...
"...\arm-none-eabi-gcc.exe" weak_handlers.o main.o SEGGER_RTT.o SEGGER_RTT_printf.o SEGGER_RTT_Syscalls_GCC.o -mthumb -Wl,-Map="app.map" -Wl,--start-group -lm -Wl,--end-group -Wl,--gc-sections -mcpu=cortex-m4 -T flash.ld -o app.elf
问题:我用来比较我的代码的参考编程项目(Atmel Studio LEDflasher example)使用如下关键部分:(出现在 hri_nvmctrl_e54.h 第 944 行)
NVMCTRL_CRITICAL_SECTION_ENTER();
((Nvmctrl *)hw)->CTRLA.reg |= NVMCTRL_CTRLA_RWS(mask);
NVMCTRL_CRITICAL_SECTION_LEAVE();
我不明白。我尝试跟踪这些函数实现以查看它们在做什么,并最终得到以下代码:
// ==============================================================================================
// Enter critical section.
// ==============================================================================================
// Get primask
register uint32_t __regPriMask __asm__("primask");
uint32_t volatile *atomic = __regPriMask;
// Disable IRQ interrupts by setting the I-bit in the CPSR.
// Can only be executed in Privileged modes.
__asm__ volatile ("cpsid i" : : : "memory");
// Memory barrier
do {\
__asm__ volatile ("isb 0xF":::"memory");
__asm__ volatile ("dmb 0xF":::"memory");
__asm__ volatile ("isb 0xF":::"memory");
} while (0U);
// ==============================================================================================
// 25.8.1 Control A
// ==============================================================================================
// NVMCTRL-> offset: CTRLA
// 0x41004000U 0x00000000U
(*(volatile uint32_t*)0x41004000U) = 0x01000400U;
// ==============================================================================================
// Leave critical section.
// ==============================================================================================
// Memory barrier
do {\
__asm__ volatile ("isb 0xF":::"memory");
__asm__ volatile ("dmb 0xF":::"memory");
__asm__ volatile ("isb 0xF":::"memory");
} while (0U);
// Set primask
__regPriMask = &atomic;
这些记忆障碍是否有意义?正在包装 a asm volatile ("dmb 0xF":::"memory"); 在两个 asm volatile ("isb 0xF ":::"memory"); 一个常见的有用实现?这些指示是什么意思?我不确定是否正确遵循了“GoTo Implementation”路径以结束这些语句!
我要提前感谢大家的时间,并希望这个问题在未来对其他人有所帮助!
【问题讨论】:
标签: c assembly arm inline-assembly memory-barriers