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(
"mov r0,#123\n\r"
"mov %0,#45\n\r"
"str r1,%1\n\r"
"mov r2,%2\n\r"
"ldr r3,%3\n\r"
:
"+r"(a),
"=m"(b)
:
"r"(c),
"m"(d)
:
"r0",
"r1",
"r2",
"r3"
);
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_10us(
1);
}
return 0;
}
按键
GPD0.CON = (GPD0.CON & (~(
0xf <<
0))) | (
0x1 <<
0);
GPF3.CON = (GPF3.CON & (~(
0xf <<
20))) | (
0x1 <<
20);
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