标签: arm

STM32 - 如何在 HAL 库中为外设 R/W 选择 DMA 或中断

我正在使用 STM32F3 微控制器和 HAL 库。对于许多外设(例如ADC、SPI、I2C),HAL 库提供了3 种读/写数据的方式:轮询模式、中断模式和DMA 模式。我知道我不想要轮询模式,因为它会阻塞。但是,我不确定如何在中断模式和 DMA 模式之间进行选择。有一般经验法则吗?我觉得DMA模式应该总是更好,因为它可以在没有CPU干预的情况下将值写入内存?

arm interrupt stm32 dma

1
推荐指数
1
解决办法
3961
查看次数

如果在复位处理程序中调用主函数,其他中断如何处理?

这是 Tiva C 启动代码的示例代码,正如您所看到的,主函数是在重置处理程序内部调用的,据我所知,它是最高优先级的,所以我的问题是,如果我们还在重置处理程序中吗?

```
; Reset Handler

Reset_Handler   PROC
            EXPORT  Reset_Handler             [WEAK]
            IMPORT  SystemInit
            IMPORT  __main
            LDR     R0, =SystemInit
            BLX     R0
            LDR     R0, =__main
            BX      R0
            ENDP
```
Run Code Online (Sandbox Code Playgroud)

c embedded arm

1
推荐指数
1
解决办法
1567
查看次数

为 ARM 交叉编译的 Hello world 可在 x86_64 和 ARM 上运行

我正在准备演示 Qemu 的用户模式(qemu-user 包)qemu-arm。为此,我使用了一个简单的 hello world C 程序hello.c

#include <stdio.h>

int main()
{
        printf("Oi, Qemu!\nPrograma C aqui!\n");
}

Run Code Online (Sandbox Code Playgroud)

为了交叉编译它(静态链接),我使用了以下的交叉工具链gcc-arm-linux-gnueabihf

$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Ubuntu 9.3.0-10ubuntu1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-linux-gnueabihf-gcc hello.c -o hello_c_static -static
Run Code Online (Sandbox Code Playgroud)

输出在 qemu-arm、Beaglebone Black和 PC 上运行。

这怎么可能?!

编辑

关于编译后的可执行文件:

file hello_c_static 
hello_c_static: …
Run Code Online (Sandbox Code Playgroud)

linux x86 arm qemu cross-compiling

1
推荐指数
1
解决办法
847
查看次数

是否需要内存屏障是因为CPU乱序执行还是因为缓存一致性问题?

我想知道为什么需要内存屏障,我已经阅读了一些关于这个主题的文章。
有人说这是因为cpu乱序执行,而另一些人说这是因为缓存一致性问题,存储缓冲区和无效队列导致。
那么,需要内存屏障的真正原因是什么?cpu乱序执行或者缓存一致性问题?或两者?cpu乱序执行和缓存一致性有关系吗?x86和arm有什么区别?

x86 arm cpu-architecture memory-barriers cpu-cache

1
推荐指数
1
解决办法
888
查看次数

将部分内存复制到另一个位置

CopyMemory函数必须将部分内存复制到另一个位置。

CopyMemory
; The CopyMemory function receives the following parameters:
; R0: Address of the first 32-bit word to copy
; R1: Address of the last 32-bit word to copy
; R2: Destination address

ADD R4, R1, #4

Loop
CMP R4, R1
BEQ EndLoop

LDR R3, [R0]
STR R3, [R2]
ADD R0, R0, #4
ADD R2, R2, #4

B Loop
EndLoop

EndCopyMemory
BX LR
Run Code Online (Sandbox Code Playgroud)

我的代码有错误,但我看不出它是什么。我做错了什么吗?

memory assembly arm cpu-registers

1
推荐指数
1
解决办法
857
查看次数

实现永远等待的汇编代码

我想在 Arm Linux 中编写简单而简短的汇编代码,并且永远等待。

label:
b label
Run Code Online (Sandbox Code Playgroud)

这可行,但需要大量 CPU 时间。

我考虑过nanosleep 每 X 秒使用并跳转到标签,但是如何在汇编中使用它?

pause系统调用(在注释中建议)不好,因为该进程有一个信号处理程序。

有简单的方法吗?

linux assembly sleep arm

1
推荐指数
1
解决办法
435
查看次数

ARM Neon 内在函数,两个向量的加法

我有一个非常简单的 C 函数,成对添加两个整数数组:

void add_arrays(int* a, int* b, int* target, int size) {
    for(int i=0; i<size; i++) {
        target[i] = a[i] + b[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到在 ARM 上,Neon 内在函数在 <arm_neon.h> 中可用,并且您应该能够对向量进行加法、乘法等操作,但我看到的所有示例都非常复杂。有人可以展示如何使用 ARM Neon 内在函数执行简单的操作,例如成对加法吗?

更新 我的术语是错误的,我希望实现按元素加法。

c arm hpc addition neon

1
推荐指数
1
解决办法
830
查看次数

程序计数器的值如何递增?

我有一个指令块,我想知道电脑寄存器是如何工作的。维基百科上说,pc 寄存器保存下一条要执行的指令的值,但是,查看二进制忍者的反汇编图以查找同一指令块,似乎这并不完全正确。

这是二进制忍者的反汇编图的一部分,其中每个内存加载前面都写入了加载发生的内存地址。
在此输入图像描述

000080ec         ldr r3, [pc, #76] -> 0x813c = 0x80f0 + 0x4c -> pc = 80f0 ?? (shouldnt it be 80ee).
000080ee         cmp r3, #0
000080f0         it eq
000080f2         ldreq r3, [pc, #68] -> 0x8138 = 0x80f4 + 0x44 -> pc = 80f4 (this makes sense).
000080f4         mov sp, r3
000080f6         sub.w sl, r3, #65536 (edited) 
Run Code Online (Sandbox Code Playgroud)

这也发生在代码中,并不总是电脑保存下一条要执行的指令的地址..有什么我应该考虑的吗?

assembly arm reverse-engineering program-counter

1
推荐指数
1
解决办法
1873
查看次数

“hit-under-miss” 中的 “under” 是什么意思?

ARM 网站包含对称为“HUM”(hit-under-missing)的功能的说明。

看来“under”可以解释为“after”或“follow”,意思是前面的访问是未命中,而后续的访问是命中。这种理解正确吗?如果,我想知道使用“下面”这个词是否有特殊的上下文(即使用空间关系而不是时间关系)。

caching arm

1
推荐指数
1
解决办法
807
查看次数

编译器如何在 ARM 汇编中强制执行 C++ 易失性

根据 cppreference,一个volatile限定变量的存储不能重新排序为另一个volatile限定变量。换句话说,在下面的示例中,当 y 变为 20 时,可以保证 x 为 10。

volatile int x, y;
...
x = 10;
y = 20;
Run Code Online (Sandbox Code Playgroud)

根据维基百科,ARM 处理器的一个存储可以在另一个存储之后重新排序。因此,在下面的示例中,第二个存储可以在第一个存储之前执行,因为两个目的地是不相交的,因此它们可以自由地重新排序。

str     r1, [r3]
str     r2, [r3, #4]
Run Code Online (Sandbox Code Playgroud)

有了这样的理解,我写了一个玩具程序:

volatile int x, y;

int main() {
    x = 10;
    y = 20;
}
Run Code Online (Sandbox Code Playgroud)

我预计生成的程序集中会出现一些围栏,以保证 x 和 y 的存储顺序。但为 ARM生成的程序集是:

main:
        movw    r3, #:lower16:.LANCHOR0
        movt    r3, #:upper16:.LANCHOR0
        movs    r1, #10
        movs    r2, #20
        movs    r0, #0
        str     r1, [r3]
        str     r2, [r3, #4] …
Run Code Online (Sandbox Code Playgroud)

c++ assembly arm volatile memory-barriers

1
推荐指数
1
解决办法
587
查看次数