ARM

    xiaoxiao2025-01-12  8

    ARM_Linux NOTE_3

    Vine Farer

    2016.08.10


    3、ARM汇编、C混合编程

    1)LED实验

    汇编

    .text .globl _start _start: nop bl main #跳进main函数 nop _stop: b _stop

    main.c中的main函数

    volatile:

    1、修饰代码块,屏蔽编译器优化 2、修饰变量,等式两边对同一变量都读一次

    int main(int argc, char *argc[]) { (*((volatile unsigned int *)(0x11400000 + 0x01e0))) = ((*((volatile unsigned int *)(0x11400000 + 0x01e0))) & (0x0fffff)) | (0x100000); (*((volatile unsigned int *)(0x11400000 + 0x01e4))) |= (0b100000); return 0; }

    Makefile

    SHELL=C:\WINDOWS\system32\cmd.exe all: arm-none-eabi-gcc -c -g asm.s -o asm.o arm-none-eabi-gcc -c -g main.c -o main.o arm-none-eabi-ld -Ttext 0x40008000 asm.o main.o -o asm.elf arm-none-eabi-objdump -D asm.elf > asm.dis clean: rm -rf *.elf *.o

    2)C语言的传参

    asm:

    .text .globl _start _start: nop bl main nop _stop: b _stop .globl _fun #全局调用_fun函数,要先用.globl声明 _fun: mov r3,#1 mov r4,#2 mov pc,lr

    main:

    int _fun(); int fun(int a, int b, int c, int d) { return 300; } int main(int argc, char *argv[]) { int a = 100; a = fun(6,7,8,9); a = _fun(); return 250; }

    3)内联汇编

    如果全局调用汇编函数,则pc不断跳转很浪费时间 所以,内联汇编使C中内嵌汇编,省去跳转时间,提高效率 输出列表中的变量,内联结束后,变量会得到寄存器返回的值

    int main(int argc, char *argv[]) { int a = 100; int b, c, d; //内联汇编 asm volatile( /*也可__asm__ __volatile__*/ /*volatile用来关闭编译器优化*/ "mov r0,#123\n\r" "mov %0,#45\n\r" /* \n是回车,\r是行首 */ "str r1,%1\n\r" "mov r2,%2\n\r" "ldr r3,%3\n\r" :"+r"(a),"=m"(b) /*输出列表output table*/ :"r"(c),"m"(d) /*输入列表input table*/ :"r0","r1","r2","r3" /*异变列表change table*/ ); /*r是寄存器传输、m是内存传输*/ /*+是可读可写、=是只写、*/ /*输出列表的元素默认只读*/ a = fun(6,7,8,9); a = _fun(); return 250; }


    4)C代码实现片外模块功能

    先包含exynos_4412.h头文件,里面包含了所有的片外寄存器声明

    LED闪烁

    #include "exynos_4412.h" void mydelay_ms(int ms) { int i, j; while(ms--) { for (i = 0; i < 5; i++) for (j = 0; j < 514; j++); } } int main(int argc, char *argv[]) { int i; GPF3.CON = (GPF3.CON & (~(0xf << 20))) | (0x1 << 20); for(i = 0; i < 100; i ++) { GPF3.DAT ^= (0b1 << 5); //异或取反 mydelay_ms(500); } return 0; }

    蜂鸣器驱动

    #include "exynos_4412.h" void mydelay_ms(int ms) { int i, j; while(ms--) { for (i = 0; i < 5; i++) for (j = 0; j < 514; j++); } } void mydelay_10us(int us) { int i, j; while(us--) { for (i = 0; i < 5; i++) for (j = 0; j < 5; j++); } } int main(int argc, char *argv[]) { int i; GPD0.CON = (GPD0.CON & ~(0xf << 0)) | (0x1 << 0); while(1) { GPD0.DAT ^= (0x1 << 0); // mydelay_ms(1); mydelay_10us(1); } return 0; }

    按键

    /*beep GPD0_0*/ GPD0.CON = (GPD0.CON & (~(0xf << 0))) | (0x1 << 0); /*led5 GPX3_5*/ GPF3.CON = (GPF3.CON & (~(0xf << 20))) | (0x1 << 20); /*key4 GPX3_5*/ GPX3.CON &= ~(0xf << 8); while(1) { if(0 == (GPX3.DAT & (1 << 2))){ mydelay_ms(50); if(0 == (GPX3.DAT & (1 << 2))){ GPF3.DAT ^= (1 << 5); while(0 == (GPX3.DAT & (1 << 2))) ; } } }


    转载请注明原文地址: https://ju.6miu.com/read-1295419.html
    最新回复(0)