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

时间:2022-01-22 08:03:54

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

嵌入式linux应用开发手册笔记嵌入式linux应用开发手册笔记嵌入式linux应用开发手册笔记-O大写嵌入式linux应用开发手册笔记

连接器选项下面的选项用于连接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目录


嵌入式linux应用开发手册笔记-T可以直接指定代码段数据段,bss段的起始地址也可以用来指定一个连接脚本,在连接脚本中进行更复杂的地址设置;只用于bootloader、内核等“没有底层软件支持”的软件;连接运行与操作系统之上的应用程序无需指定-T选项,格式如下:-Ttext startaddr-Tdata startaddr-Tbss startaddr嵌入式linux应用开发手册笔记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.3arm-linux-objcopy用来将elf格式的可执行文件转换为二进制文件被用来复制一个目标文件的内容到另一个文件,可以使用不同于源文件的格式来输出目的文件,即可以进行格式转换。 arm-linux-objcopy-O binary -S led_elf led.bin
arm-linux-objdump -D xxx > xxx.dis 反汇编指令

3.2 Makefiletarget..:依赖 .... (command)eg: hello:hello.c     gcc-o hello  hello.c  //执行编译hello.cclean:      rm-f hello    //清除编译出来的文件  注意:每个命令行前面必须是一个tab字符,即命令行第一个字符是tab,这是容易出错的地方

3.2.2MAKEFILE赋值 分为延时变量和立即变量区别在于前者在使用时才扩展开(才确定),后者是在定义时它的值已经确定了。immeddiate=deferred //延时变量immeddiate?=deferred //用来定义第一次出现的延时变量immeddiate:=deferred//立即变量immeddiate+=deferred or immediate //若右边变量在前面使用(:=)定义为立即变量则它也是立即变量,否则均为延时变量
3.2.3函数格式:$(function arguments)$(subst from,to,text)在文本中to替换每一处from(字母)$(patsubstpattern,replacement,text)//寻找text中符合pattern的字用replacement替换它们(字符串?)$(stripstring)//去掉前导和结尾空格,并将中间的多个空格压缩为单个空格,如$(strip a  b  c)结果为a b c$(findstringfind,in)在字符串“in”中搜寻“find”,如果找到,则返回值是“find”,否则返回值为空$(filter pattern...,text)//返回text中由空格隔开且匹配格式“pattern...”的字$(sort list)//将list中的字按字母顺序排序,并去掉重复的字
以options程序的Makefile为例,options目录下所有的文件为main.cMakefile sub.c sub.h 。Makefile 内容如下:src :=$(shell ls *.c)  //src=main.c sub.cobjs:=$(patsubst%.c,%.o,$(src)) //objs=main.o sub.o
test:$(objs)   //test:main.o sub.o    gcc -o $@ $^
%.o:%.c    gcc -c -o $@ $<</font>
clean:    rm -f test *.o
3.3.1 armasm and atpcs rules
跳转指令b、bl bl除了跳转之外,还将返回地址(bl的下一条指令的地址)保存在lr寄存器中,这两条指令的可调转范围是当前指令的前后32mb

mov mov r1,r2    //r1=r2mov r1,#4096  //传送的常数必须能用立即数来表示 

ldr:从内存中读取数据到寄存器,str:相反,它们的操作数据都是32位ldr即可能是大范围的地址读取指令可能是内存访问指令,当第二个参数有=时表示伪指令ldr r1,=4097  //r1=4097// dldr r1,=labellabel:....

ldr r1,[r2,#4]  //将r2+4的内存地址数据读取到r1中ldr r1,[r2],#4 //将r2的内存地址数据读取到r1中然后r2=r2+4str r1,[r2,#4]  //[r2+4]=r1str r1,[r2],#4   //[r2]=r1,r2=r2+2ldmiastrdbadd sub
add r1,r2,#4  .r1=r2+4sub r1,r2,#4  .r1=r2-4
msr and mrsARM有一个程序状态寄存器cpsr,它用来控制处理器的工作模式、设置中断的总开关msr cpsr,r0 .复制r0到cpsr中mrs r0,cpsr .复制cpsr到r0中

other asmeg:.extern     main  //定义一个外部符号变量或函数,在这里指引用外部函数main.text             //表示下面的语句都是代码段.global     _start        //.global将文件中的某个程序标号定义为全局的_start:

汇编指令执行条件2012年9月3日 15:10:34嵌入式linux应用开发手册笔记


ATPCS(子程序调用规则)1.寄存器使用规则arm处理器中有r0~r15共16个寄存器嵌入式linux应用开发手册笔记
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 longstrart_addr,int size)在汇编代码中,使用下面的代码调用它并判断返回值ldr r0,=0x30000000//  *buf=0x30000000mov r1,#0    //start_addr=0mov r2,#16*1024  //size=16*1024cmp a0,#0  //return value



第五章 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]
GPXDATGPXDAT根据gpxcon设置来读/写引脚状态
GPXUPgpxup=1,相应引脚无内部上拉电阻;gpxup=0,使用内部上拉电阻嵌入式linux应用开发手册笔记1.访问单引脚#define GPBCON   (*(volatileunsigned long *)0x56000010)#define GPBDAT   (*(volatile unsigned long*)0x56000014)#define GPB5_out (1<<(5*2))GPBCON=GPB5_out;    // gpb5=out,GPBDAT&=~(1<<5);  //GPB5=0

2.总线方式访问
5.2 点亮第一个led灯tq2440 4个灯嵌入式linux应用开发手册笔记嵌入式linux应用开发手册笔记gpbcon对应地址 0x56000010 gpbdat对应地址0x56000014估汇编程序如下: 1 .text
  2 .global _start
  3 _start:
        LDR R0,=0x56000010