简体   繁体   English

Cortex-M4F MCU启动中关键部分的内存屏障

[英]Memory barriers for critical sections in Cortex-M4F MCU startup

INTRODUCTION: I've designed an embedded system featuring an ATSAME54N20A 32-bit ARM® Cortex®-M4F MCU. 简介:我设计了一个嵌入式系统,该系统具有ATSAME54N20A 32位ARM®Cortex®-M4FMCU。 The board will be assembled and ready for programming soon so I was setting up my programming environment. 该板将被组装并准备好进行编程,因此我正在设置编程环境。 I went for a bare-bone solution where only the minimum C-written files necessary are present, because although it's a time consuming process, it helps me to understand the system workings. 我选择了一种准系统解决方案,其中仅包含最少的C编写文件,因为尽管这是一个耗时的过程,但它可以帮助我了解系统的运行情况。 The compiler chosen is GCC with the following arguments: 选择的编译器是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

QUESTION: The reference programming project I'm using to compare my code against ( Atmel Studio LEDflasher example ) uses critical sections like the following: ( present on hri_nvmctrl_e54.h line 944 ) 问题:我用来比较代码的参考编程项目(Atmel Studio LEDflasher示例 )使用的关键部分如下所示:(出现在hri_nvmctrl_e54.h第944行)

NVMCTRL_CRITICAL_SECTION_ENTER();
((Nvmctrl *)hw)->CTRLA.reg |= NVMCTRL_CTRLA_RWS(mask);
NVMCTRL_CRITICAL_SECTION_LEAVE();

Which I don't understand. 我不明白。 I tried to follow those function implementations to see what they were doing and ended up with the following code: 我尝试遵循这些函数的实现,以查看它们在做什么,并最终得到以下代码:

// ==============================================================================================
// 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;

Do any of this memory barriers make sense? 这些记忆障碍是否有意义? Is wrapping a asm volatile ("dmb 0xF":::"memory"); 正在包装asm volatile(“ dmb 0xF” :::“内存”); between two asm volatile ("isb 0xF":::"memory"); 在两个asm volatile之间(“ isb 0xF” :::“内存”); a common useful implementation? 一个常见的有用实现? What would those instructions mean? 这些指示是什么意思? I'm not sure if the "GoTo Implementation" path was followed correctly to end up with these statements! 我不确定是否正确遵循了“ GoTo实现”路径以结束这些语句!

I'd like to thank everyone in advance for your time and hope this question helps others in the future ! 我想在此先感谢大家的宝贵时间,并希望这个问题对以后的其他人有所帮助!

Do any of this memory barriers make sense? 这些记忆障碍是否有意义?

In my eyes, yes. 在我眼中,是的。 If there are caches, interrupts, optimisations, load latencies, etc, memory barries may be a must. 如果存在缓存,中断,优化,加载等待时间等,则可能必须使用内存屏障。

Is wrapping a asm volatile ("dmb 0xF":::"memory"); 正在包装asm volatile(“ dmb 0xF” :::“内存”); between two asm volatile ("isb 0xF":::"memory"); 在两个asm volatile之间(“ isb 0xF” :::“内存”); a common useful implementation? 一个常见的有用实现? What would those instructions mean? 这些指示是什么意思?

isb : it flushs buffers and fetchs instructions so far. isb :到目前为止,它会刷新缓冲区并获取指令。

dmb : it completes all memory access so far. dmb :到目前为止,它完成了所有内存访问。

isb : after dmb , it ensures that the new context has been loaded. isb :后dmb ,它保证了新的环境已经加载。

It is an useful and a very safe (and defensive) way to protect the code against procesor/compiler re-ordering, latencies, etc. 这是一种保护代码免受处理器/编译器重新排序,延迟等影响的有用且非常安全(防御性)的方法。

Furthermore, this critical region is disabling the interrupts in order to promote it to the highest priority task, so nobody will be able to interrupt this part of the code. 此外,该关键区域正在禁用中断,以便将其提升为最高优先级的任务,因此没有人能够中断代码的这一部分。 Definitely, a proper way to protect a critical region. 绝对是保护关键区域的正确方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM