Tag: arm

为内联汇编创建常量池的正确方法是什么?

问题是在C函数内部我有一个内联汇编。 就像是 ldr r7, =0xdeadbeef svc 0 如果未明确创建文字池(这是这种情况),汇编程序会在翻译单元的末尾创建一个文字池。 通常这很好,但是如果翻译单元真的很大,那么这不起作用,因为文字池离ldr指令太远了。 所以,我想知道处理这个问题的最佳方法是什么。 最明显的方法是在内联汇编中手动创建文字池: ldr r7, =0xdeadbeef svc 0 b 1f .ltorg 1: 要么 ldr r7, 1f svc 0 b 2f 1: .word 0xdeadbeef 2: 不幸的是,由于冗余分支指令,这导致了次优代码。 我不希望汇编器足够聪明,为函数内部的常量池找到合适的位置。 我想要做的是在函数的末尾创建一个常量池。 有没有办法告诉编译器(gcc)在函数末尾创建一个文字池? PS我最终使用了movw/movt对而不是常量池。 虽然,首先,movw / movt解决方案的可移植性略低于文字池,其次,我只是想知道是否可以可靠而有效地在内联汇编中使用常量池。 更新: 那么,处理问题的最佳方法是什么? 要强制工具链在函数之后创建常量池,可以将函数放在单独的代码部分中。 它的工作原理是因为在翻译单元结束时汇编程序为每个部分生成单独的常量池。 实际上, 最好的方法是避免将常量加载到内联汇编中的寄存器中。 让编译器这样做会更好。 在我的情况下,我最终写了一个类似的代码 register int var asm(“r7”) = 0xdeadbeef; asm […]

16位int机器(MSP430)和32位int机器(ARM CORTEX)的减法结果不同

当下面的代码针对像MSP430微控制器这样的16位整数机器运行时, s32产生65446。 #include uint16_t u16c; int32_t s32; int main() { u16c = 100U; s32 = 10 – u16c; } 我的理解是10-u16c将隐式类型提升为unsigned int。 数学上10-u16c等于-90。 但是如何将负数表示为unsigned int呢? 当-90被提升为unsigned int时,是否意味着忽略了数字的符号? 让我们假设,数字的符号被忽略。 90的二进制表示是00000000 01011010 。 当这被分配给32位宽的有符号整数变量s32 ,转换是如何发生的? 为了使s32等于65446,90必须采用2的补码。 那将是00000000 10100110 。 我不太了解s32成为65446的过程。 在像ARM这样的32位宽整数机器中, s32是-90,这是正确的。 要在16位整数机器中修复这种情况, (int16_t)需要(int16_t)的类型转换。 这如何解决这个问题? 添加了s32六进制数据表示,如IAR Workbench(右下角)所示。 结果表明s32变为0x0000FFA6 。 因此对于MSP430,从无符号16位转换为有符号32位的机器实现,它只是预先设置16 0位。

通过交叉编译armv5的节点来兼容库

我尝试在我的Ubuntu 14.04桌面x64上为我的QNAP armv5te机器交叉编译节点 。 QAPP App-center中存在节点QPKG,但其版本较旧(0.8.22)。 以下是有关服务器的信息: Linux SERVERNAME 3.4.6#1 Mon Dec 29 06:00:47 CST 2014 armv5tel未知 处理器名称 :Feroceon 88F6281 rev 1(v5l)@ 1.2 GHz BogoMIPS :1196.85 特点 :swp half thumb fastmult edsp CPU实现者 :0x56 CPU架构 :5TE CPU变体 :0x2 CPU部分 :0x131 CPU修订版 :1 硬件 :Feroceon-KW ARM版本 :0000 型号 :0000000000000000 这是我在桌面上使用的命令: apt-get update apt-get upgrade apt-get install […]

处理ARM芯片的保留寄存器位

我正在使用ARM Cortex M3的寄存器。 在文档中,一些位可能是“保留的”。 在寄存器上写入时,我不清楚如何处理这些保留位。 这些保留位是否可写? 我不小心不接触它们吗? 如果我触摸它们会发生什么不好的事吗?

导致无法在海湾合作委员会中划分数字的原因是什么

我的情况非常奇怪。 每次我尝试编译我的arm项目(LPC2378,codesourcery arm-none-eabi-gcc-4.5.1)时我都会遇到同样的错误 /media/data/Projects/arm/uart/main.c:39: undefined reference to `__aeabi_uidiv’ /media/data/Projects/arm/uart/main.c:40: undefined reference to `__aeabi_uidiv’ 违规代码如下所示: U0DLL = ((((PLLCFG & 0x7FFF) + 1) * F_OSC) / ((((PLLCFG & (0xFF <> 16) + 1) * ((CCLKCFG & 0xFF) + 1) * 8 * BAUD * 1)) % 256; U0DLM = ((((PLLCFG & 0x7FFF) + 1) * F_OSC) / […]

为什么i2c_smbusfunction不可用? (I2C – 嵌入式Linux)

在开发嵌入式Linux软件以在I2C总线上进行通信时,有许多参考使用i2c_smbus_函数。 当在软件项目中引用i2c_smbus函数(例如i2c_smbus_read_word_data)时, ARM8处理器错误(如“ i2c_smbus_read_word_data”)未在此范围内声明,则在编译时生成。 对以下头文件的研究表明缺少大多数i2c_smbus函数定义。 /usr/arm-linux-gnueabi/include/linux/i2c.h /usr/arm-linux-gnueabi/include/linux/i2c-dev.h 同样在以下参考i2c.h文件中定义了所有i2c_smbus。 如何解决这个问题? 研究参考 在Linux中使用来自用户空间的I2C Linux用户空间的I2C通信 – 第二部分 I2C开发接口

计算ARM Cortex-a8 BeagleBone Black上的时钟周期计数

我想计算我的c代码中特定函数的时钟周期计数,该函数将在BeagleBone Black上编译和运行。 我不知道我怎么能这样做。 我在网上搜索,发现了这条指令: Arndale板上的时钟读取方法: 步骤1:插入内核模块以启用对PMU计数器的用户空间访问。 解压附件文件“arndale_clockread.tar.bz2”,该文件包含Makefile和enableccnt.c。 在Makefile中用您的内核源目录更改“KERNELDIR”,例如/ usr/src/linux-kernel-version然后运行命令。 linaro@linaro-server:~/enableccnt$ make 上面的命令应该输出为enableccnt.ko ,这是内核模块,用于启用用户空间访问PMU计数器。 然后运行该命令。 linaro@linaro-server:~/enableccnt$ sudo insmod enableccnt.ko 以下命令应显示正在运行的内核中插入enableccnt模块。 linaro@linaro-server:~/enableccnt$ lsmod 步骤2:从用户空间应用程序中读取计数器。 一旦设置了内核模块。 以下function可用于读取计数器 static void readticks(unsigned int *result) { struct timeval t; unsigned int cc; if (!enabled) { // program the performance-counter control-register: asm volatile(“mcr p15, 0, %0, c9, c12, 0” :: “r”(17)); //enable […]

snprintf()使用newlib nano打印垃圾浮动

我正在运行带有ARM Cortex-M3(STM32F205)的裸机嵌入式系统。 当我尝试使用带浮点数的snprintf()时,例如: float f; f = 1.23; snprintf(s, 20, “%5.2f”, f); 我把垃圾变成了垃圾。 格式似乎很荣幸,即垃圾是一个格式良好的字符串,包含数字,小数点和两个尾随数字。 但是,如果我重复snprintf ,字符串可能会在两次调用之间发生变化。 浮点数学似乎在其他方面起作用,而snprintf与整数一起工作,例如: snprintf(s, 20, “%10d”, 1234567); 我将newlib-nano实现与-u _printf_float链接器开关一起使用。 编译器是arm-none-eabi-gcc 。 我确实怀疑内存分配问题,因为整数打印没有任何打嗝,但浮动表现就好像它们在过程中被破坏一样。 printf系列函数使用浮点数调用malloc ,而不是整数。 我在这个上下文中使用的唯一不属于newlib的代码是我的_sbrk() ,它是malloc所必需的。 caddr_t _sbrk(int incr) { extern char _Heap_Begin; // Defined by the linker. extern char _Heap_Limit; // Defined by the linker. static char* current_heap_end; char* current_block_address; […]

Intel x86到ARM汇编转换

我目前正在学习ARM汇编语言; 为此,我试图将一些x86 code (AT&T Syntax)为ARM汇编(Intel Syntax)代码。 __asm__(“movl $0x0804c000, %eax;”); __asm__(“mov R0,#0x0804c000”); 从这个文档中 ,我了解到在x86中,堆结构的Chunk 1从0x0804c000开始。 但是,当我尝试做同样的操作时,我收到以下错误: /tmp/ccfNZp9F.s:174: Error: invalid constant (804c000) after fixup 我假设问题是ARM只能加载32位指令。 Question 1: Any idea what would be the first chunk in case of ARM processors? Question 2: 从我之前的问题 ,我知道内存间接寻址是如何工作的。 下面写的片段是否做同样的工作? movl (%eax), %ebx LDR R0,[R1] 我正在使用ARMv7 Processor rev 4 (v7l)

gcc中的内联汇编

我对一些内联汇编代码有些麻烦。 我知道应该做些什么,但我想念“怎么样”! 我有这个“几乎”工作的校验和function: static unsigned long cksum_unroll( unsigned short **w, int *mlen) { int len; unsigned short *w0; unsigned long sum=0; len = *mlen; w0 = *w; while( len >= 8) { asm volatile ( “ldmia %[w0]!, {v1, v2}\n\t” “adds %[sum], %[sum], v1\n\t” “adcs %[sum], %[sum], v2\n\t” “adcs %[sum], %[sum], #0” : [sum] “+r” (sum) […]