linux及arm-linux程序开发笔记,嵌入式linux应用开发手册笔记

嵌入式linux应用开发手册笔记

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

-O

大写

3f288ee285423cc6e29fa526842ca321.png

连接器选项

下面的选项用于连接obj文件,输出可执行文件或库文件

-llibrary

连接名为library的库文件

-nostartfiles

不连接系统标准启动文件,用于编译bootloader、内核

-nostdlib

不连接系统标准启动文件和标准库文件,用于编译内核、bootloader,他们不需要启动文件标准库文件

-static

阻止使用连接共享库

-shared 生成一个共享obj库

目录选项

-Idir 在头文件的搜索路径列表中添加dir目录

头文件的搜索方法:#include<>只从标准库目录开始搜索(包括使用-Idir选项定义的目录)

#include“”先从用户的工作目录开始搜索,在搜索标准库目录

-I-

只是用于#includ“”,在-I-前面的-I搜索路径只是用于#include “”

;如果用“-I”选项指定的搜索路径位于-I-选项后面,就可以在这些路径中搜索所有的#include指令,

-I选项能够阻止当前目录成为搜索“#include”的第一选择

-Ldir

在-I选项的搜索路径列表中添加dir目录

在-I选项的搜索路径列表中添加dir目录

3f288ee285423cc6e29fa526842ca321.png

-T可以直接指定代码段数据段,bss段的起始地址也可以用来指定一个连接脚本,在连接脚本中进行更复杂的地址设置;只用于bootloader、内核等“没有底层软件支持”的软件;连接运行与操作系统之上的应用程序无需指定-T选项,

格式如下:

-Ttext startaddr

-Tdata startaddr

-Tbss startaddr

3f288ee285423cc6e29fa526842ca321.png

b、bl、mov

不依赖于-Ttext选项,ldr依赖。

2.使用连接脚本设置地址

arm-linux-ld -Ttimer.lds -o xxx

他使用连接脚本timer.lds来设置可执行文件timer_elf的地址信息,timer_elf文件内容如下:

SECTIONS {

.=0X30000000;

//设置“当前运行地址”为0x30000000

.text

{*(.text)} //定义了一个名为‘.text'的段它的内容为“*(.text)”,表示所有输入文件的代码段。这些代码段被集合在一起,起始运行地址为0x30000000.

.rodata ALIGN(4)

:{*(.rodata)}//定义“.rodata”段,ALIGN(4)表示起始运行地址为4字节对齐,假设前面段的地址范围是0x30000000~0x300003f0,则“.rodata”段的地址是4字节对齐后的0x300003f4

.data ALIGN(4)

:{*(.data)}

.bss ALINGN(4)

:{*(.bss

*(COMMON)}

}

完整的连接脚本格式如下:

SECTIONS {

...

secname start ALIGN(align)(NOLOAD)

:AT(ldadr)

{contents}>region:phdr

=fill

...

}

secname

和contents是必需的,前者用来命名这个段,后者用来确定代码中的说明部分

(NOLOAD):用来告诉加载器,在运行时不用加载这个段,

AT(ldadr):指定这个段在编译出来的映像文件中的加载地址如果不使用这个选项,则加载地址等于运行地址

3.1.3

arm-linux-objcopy用来将elf格式的可执行文件转换为二进制文件

被用来复制一个目标文件的内容到另一个文件,可以使用不同于源文件的格式来输出目的文件,即可以进行格式转换。

arm-linux-objcopy

-O binary -S led_elf led.bin

arm-linux-objdump -D xxx > xxx.dis

反汇编指令

3.2 Makefile

target..:依赖 ....

(command)

eg:

hello:hello.c

gcc

-o hello  hello.c

//执行编译hello.c

clean:

rm

-f hello

//清除编译出来的文件

注意:每个命令行前面必须是一个tab字符,即命令行第一个字符是tab,这是容易出错的地方

3.2.2

MAKEFILE

赋值

分为延时变量和立即变量区别在于前者在使用时才扩展开(才确定),后者是在定义时它的值已经确定了。

immeddiate=deferred

//延时变量

immeddiate?=deferred

//用来定义第一次出现的延时变量

immeddiate:=deferred

//立即变量

immeddiate+=deferred

or immediate

//若右边变量在前面使用(:=)定义为立即变量则它也是立即变量,否则均为延时变量

3.2.3

函数格式:$(function arguments)

$(subst from,to,text)

在文本中to替换每一处from(字母)

$(patsubst

pattern,replacement,text)//寻找text中符合pattern的字用replacement替换它们(字符串?)

$(strip

string)//去掉前导和结尾空格,并将中间的多个空格压缩为单个空格,如$(strip a

b  c)结果为a b c

$(findstring

find,in)在字符串“in”中搜寻“find”,如果找到,则返回值是“find”,否则返回值为空

$(filter pattern...,text)

//返回text中由空格隔开且匹配格式“pattern...”的字

$(sort list)

//将list中的字按字母顺序排序,并去掉重复的字

以options程序的Makefile为例,options目录下所有的文件为main.c

Makefile sub.c sub.h 。Makefile 内容如下:

src :=$(shell ls *.c)

//src=main.c sub.c

objs:=$(patsubst

%.c,%.o,$(src)) //objs=main.o sub.o

test:$(objs)

//test:main.o sub.o

gcc -o $@ $^

%.o:%.c

gcc -c -o $@ $<

clean:

rm -f test *.o

3.3.1 arm

asm and atpcs rules

跳转指令b、bl

bl除了跳转之外,还将返回地址(bl的下一条指令的地址)保存在lr寄存器中,这两条指令的可调转范围是当前指令的前后32mb

mov

mov r1,r2

//r1=r2

ldr:从内存中读取数据到寄存器,str

:相反,它们的操作数据都是32位

ldr

即可能是大范围的地址读取指令可能是内存访问指令,当第二个参数有=时表示伪指令

ldr r1,=4097  //r1=4097// d

ldr r1,=label

label:

....

msr and mrs

ARM有一个程序状态寄存器cpsr,它用来控制处理器的工作模式、设置中断的总开关

msr cpsr,r0

.复制r0到cpsr中

mrs r0,cpsr .复制cpsr到r0中

other asm

eg:

.extern

main

//定义一个外部符号变量或函数,在这里指引用外部函数main

.text

//表示下面的语句都是代码段

.global

_start

//.global将文件中的某个程序标号定义为全局的

_start:

汇编指令执行条件2012年9月3日 15:10:34

3f288ee285423cc6e29fa526842ca321.png

ATPCS(子程序调用规则)

1.寄存器使用规则

arm

处理器中有r0~r15共16个寄存器

3f288ee285423cc6e29fa526842ca321.png

FD:Full Descending 满递减

ED:Empty Descending 空递减

FA:Full Ascending 满递增

EA:empty ascending 空递增

数据栈为FD,8字节对齐使用stmdb/ldmia批量内存访问指令来操作fd数据栈

使用stmdb命令玩数据栈中保存内容时先递减sp指针,在保存数据(入栈)

eg:stmdb sp!,{fp,ip,lr}

使用ldmia命令从数据栈中恢复数据先获得数据在递增sp指针,sp指针总是指向栈顶元素

eg:ldmia sp,{fp,sp,pc}

3.参数传递规则

int copycode2sdram(unsigned char *buf,unsigned long

strart_addr,int size)

在汇编代码中,使用下面的代码调用它并判断返回值

ldr r0,=0x30000000

//  第五章

gpio接口

s3c2440有130个I/O口:gpa、gpb...gpj。

通过寄存器来操作gpio引脚

GPXCON(32位)

GPXCON用于选择引脚功能、gpxdat用于读/写引脚数据;gpxup用于确定是否使用上拉电阻。

gpacon寄存器对应gpa(共23个引脚),当gpacon某位=0,我们可以在gpadat相应位写入0或1让此引脚输出低电平或高电平,gpacon=1,gpa相应引脚为地址线或用于地址控制,一般gpacon全设为1以便访问外部存储器件

gpbcon~gpjcon

没两位控制一根引脚:00=输入;01=输出;10=特殊功能;11=保留不用

gpb=[10:0]

GPXDAT

GPXDAT根据gpxcon设置来读/写引脚状态

GPXUP

gpxup=1,相应引脚无内部上拉电阻;gpxup=0,使用内部上拉电阻

3f288ee285423cc6e29fa526842ca321.png

1.访问单引脚

#define GPBCON   (*(volatile

unsigned long *)0x56000010)

#define GPBDAT

(*(volatile unsigned long*)

0x56000014)

#define GPB5_out

(1<

GPBCON=GPB5_out;

// gpb5=out,

GPBDAT&=~(1<<5);

//GPB5=0

2.总线方式访问

5.2 点亮第一个led灯

tq2440 4个灯

3f288ee285423cc6e29fa526842ca321.png3f288ee285423cc6e29fa526842ca321.png

gpbcon对应地址 0x56000010

gpbdat对应地址0x56000014

估汇编程序如下:

1 .text

2 .global _start

3 _start:

4

LDR R0,=0x56000010

5

MOV R1,#0x400

6

STR R1,[R0]

@GPBCON  SET OK

7

8

9

LDR R0,=0x56000014

10

MOV R1,#0x0

11

STR R1,[R0]

@GPBDAT SET OK

12

13 main:

14

B main

对应makefile 如下:

1 led.bin:led.s

2

arm-linux-gcc -g -c -o led.o led.s

//-g 可执行程序中包含标准调试信息

-s只编译不连接生成汇编代码

-c只编译不链接生成目标文件”o“

3

arm-linux-ld -Ttext 0x30000000 -g led.o -o led_elf

//链接

4

arm-linux-objcopy -O binary -S led_elf led.bin

-O//elf转为二进制bin并优化

5 clean:

6

rm -f *elf *.o  //删除

使用C语言点灯

3f288ee285423cc6e29fa526842ca321.png

crt0.s

@*****************

@trun to c

@*******************

.text

.global _start

_start:

ldr r0,=0x56000010  @watchdog conf addr

mov r1,#0x0

str

r1,[r0]

@stop

watchdog

ldr

sp,=1024*4

@sp<=4kb

bl main

@use c main

halt_loop:

b

halt_loop

ledonc.c

#define GPBCON (*(volatile unsigned long *)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

int main()

{

GPBCON=0X400;//GPB5C5=01 OUT

GPBDAT=0X00;

//GPB5=0

return 0;

}

MAKEFILE:

ledonc.bin:crto.s ledonc.c

arm-linux-gcc -g -c -o

crto.o

crto.s

arm-linux-gcc -g -c -o ledonc.o ledonc.c

arm-linux-ld -Ttext 0x0000000 -g crto.o ledonc.o -o

ledonc_elf

arm-linux-objcopy -O binary -S ledonc_elf ledonc.bin

arm-linux-objdump -D -m arm ledonc_elf >ledonc.dis

clean:

rm -f ledonc.dis ledonc.bin ledonc_elf *.o

3.使用按键是对应灯亮

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

gpfcon=0x56000050 gpfdat=0x56000054

crt0.s

@*****************

@trun to c

@*******************

.text

.global _start

_start:

ldr r0,=0x56000010  @watchdog conf addr

mov r1,#0x0

str

r1,[r0]

@stop

watchdog

ldr

sp,=1024*4

@sp<=4kb

bl main

@use c main

halt_loop:

b

halt_loop

keyledon.c

#define GPBCON (*(volatile unsigned long*)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

#define GPFCON (*(volatile unsigned long *)0x56000050)

#define GPFDAT (*(volatile unsigned long *)0x56000054)

int main()

{

GPBCON=0x15400; //gpbcon=010101010000000000

GPFCON=0x00; //00 means input

int rdat; //use toread gpfdat

while(1)

{

rdat=GPFDAT;

if(rdat&0x01)

GPBDAT=0x10;//led0 off

else

GPBDAT=0xef; //led0 on

//

if(rdt&)

}

}

Makefile

keyled.bin:crto.s keyledon.c

arm-linux-gcc -g -c -o crto.o  crto.s

arm-linux-gcc -g -c -o keyledon.o keyledon.c

arm-linux-ld -Ttext 0x00000000 -g crto.o keyledon.o -o

keyledelf

arm-linux-objcopy -O binary -S keyledelf keyledelf.bin

clean:

rm -f  *.o *.bin *elf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值