嵌入式开发基础二
来源:互联网 发布:西部数码 域名管理 编辑:程序博客网 时间:2024/05/28 11:50
1.嵌入式产品
手机
2.嵌入式定义
iphone和低端的诺基亚
3.嵌入式系统的组成部分
硬件:
依赖用户需求
三大件:CPU,内存,闪存
外围设备:USB口(可以有),串口(必须有),网口(可以有),SD,摄像头,声卡,各种sensors
软件:
依赖硬件和用户需求
嵌入式linux软件包括:bootloader,kernel,rootfs
4.嵌入式linux系统开发的基本模式
左手PC机:
具备:串口,网口,USB口,linux系统,linux系统还要安装tftp网络服务
右手开发板:
具备:串口,网口,USB口
串口:用于双方通信
网口:主要用于下载
USB口:主要用于下载
5.嵌入式linux系统软件部署
嵌入式linux软件组成部分:
bootloader(BIOS),选在u-boot(属于bootloader一种)
linux内核(kernel)
根文件系统(rootfs)
5.1.bootloader部署
1.获取要部署的bootloader二进制镜像文件(u-boot.bin)
2.明确这个软件部署的位置
一般部署在nand,0地址处,启动方式要以nand启动
也可以部署在SD卡,在SD卡的512字节以后,要以SD卡
3.部署的过程
可以利用USB下载
可以利用SD下载
可以利用网络下载
dnw 20008000
或者
tftp 20008000 u-boot.bin
nand erase 0 100000
nand write 20008000
总结:不管是哪种烧写方法,前提是要运行一个u-boot
4.网络下载部署的注意事项
1.保证PC的linux系统安装和启动tftp网络服务
tftp(简单的文件传输服务)
sudo apt-get install tftpd-hpa
2.保证设置好一个共享目录
/tftpboot
将来开发板客户端就可以从虚拟机的tftpboot目录下载
3.保证启动tftp服务
sudo /etc/init.d/tftpd-hpa restart
4.利用开发板u-boot的相关tftp命令来部署软件
tftp 20008000 led.bin
go 20008000
nand erase 0 100000
nand write 20008000 0 100000
print
setenv
saveenv
ping:tftp下载之前一定要记得先ping!
ping不需要tftp服务!
5.此时此刻,开发板运行的程序仅仅是u-boot
还没有运行linux系统,说明以前UC的代码此时此刻不能在开发板上运行起来!
此时此刻的软件都是裸板程序
6.裸板程序:
在无操作系统下运行的软件,它们可以直接对硬件进行访问操作,不许要以文件的形式来访问硬件设备
在linux系统下必须以文件的形式访问硬件设备!
6.ARM裸板程序的开发
6.1.明确:
在无操作系统的状态下,软件访问硬件是"直接"访问
6.2.明确:
在ARM架构下,CPU访问外设都是以地址(指针)的形式访问,如果要访问某个外设,一定要搞清楚外设的基地址,例如TPAD的内存的基地址0x20000000
例如,现在向内存地址0x20000000写入0x55
//int a = 100; //仅仅告诉编译器,从内存某个位置分配4字节的内存,&a就是这块内存的首地址
unsigned long *p = (unsigned long *)0x20000000;
*p = 0x55;
6.3.明确:
对于S5PV210,32位处理器,CPU寻址的硬件地址范围:
0x00000000~0xFFFFFFFF;
6.4.明确:
“外设”:CPU核以外的任何硬件逻辑单元都是外设
不仅仅包括肉眼能看到的硬件,还包括处理器内部集成的硬件逻辑单元
6.5.初识S5PV210处理器
明确:S5PV210处理器的硬件特性都是在datasheet(芯片手册)--S5PV210_UM_REV1.1.pdf
resource/datasheet/S5PV210_UM_REV1.1.pdf
工作频率:1GHz
内部集成的外设:
GPIO控制器
RTC控制器
USB控制器
SD控制器
NAND控制器
...
6.6.初识TPAD开发板的硬件原理图
核心板的原理图:
CW210_CORE_LHGZ.pdf(融汇光泽)
CW210_CORE_TARENA.pdf(Tarena)
底板的原理图:
CW210-Peripherial.pdf
由硬件工程师提供!
6.7.外设地址的确定
对于CPU内部集成的外设,外设的基地址看芯片手册即可
对于CPU外部的外设,不仅仅要看CPU的芯片手册还要看原理图,以DM9000网卡为例:
通过原理图和芯片手册发现DM9000网卡的基地址就是0x88000000
切记:如果不清楚,一定咨询硬件工程师
7.面试题:谈谈ARM处理器如何某个外设?
以TPAD的两个LED灯的操作为例
案例目的:掌握裸板程序中,CPU如何访问某个外设
具体实施步骤:
7.1.明确用户的需求
实现一个流水灯(亮灭亮灭...)
7.2.明确两个LED的硬件操作特性
宏观看:大致看LED灯在开发板的位置
利用万用表测试LED的电源和底是否连接正确
细微看:看原理图,看LED在原理图的硬件连接方式
先看底板原理,找到LED灯硬件位置
7.3.通过原理图获取LED的硬件操作特性
第一个LED的开关由CPU的GPC1_3来决定
第二个LED的开关由CPU的GPC1_4来决定
GPC1_3/4输出高电平,灯亮
GPC1_3/4输出低电平,灯灭
问:GPC1_3/4的名如何起?
7.4.S5PV210的IO(input/output)管脚的特性
S5PV210的IO管脚由简称GPIO(通用输入和输出)
S5PV210包括237个复用GPIO
“复用”:一个GPIO既可以做输入口,又可以做输出口
又可以做别的功能的IO口
同一时刻只能有一个功能!
S5PV210并且把这些GPIO进行分组:A,B,C...等
一堆GPIO:
A组
A0组
包括8个GPIO
A1组
包括4个GPIO
B组
C组
C0组:5个
GPC0_0,GPC0_1,GPC0_2,...
C1组:5个
... GPC1_0,GPC1_1,GPC1_2,GPC1_3,GPC1_4
问:现在研究的问题是由原先的两个LED转变成研究两个GPIO管脚(GPC1_3,GPC1_4),CPU如何操作这两个管脚呢?
答:CPU通过操作GPIO控制器来间接操作IO的状态
切记:CPU访问某个GPIO都是通过访问GPIO控制器这个硬件逻辑单元间接访问GPIO
切记:GPIO控制器对于CPU核就是一个外设!
切记:就需要明确这个GPIO控制器外设的地址,这个地址只需查看CPU的芯片手册即可
7.5.GPIO控制器的硬件操作方法
0."寄存器":像内存一样的硬件,能够存储数据
1.GPIO控制器的操作都是通过一堆的GPIO的寄存器来进行
访问操作,例如:
GPC1_3,GPC1_4对应的寄存器有:
GPC1CON
GPC1DAT
GPC1PUD
...
2.明确:GPIO对应寄存器的基地址
寄存器名称 物理地址
GPC1CON 0xE0200080
GPC1DAT 0xE0200084
GPC1PUD 0xE0200088
例如:向GPC1CON寄存器写0x55
*((volatile unsigned long *)0xE0200080) = 0x55;
切记:
对于嵌入式软件开发,硬件的访问一定要加volatile
3.总结:
CPU访问某个GPIO,是通过访问对应的寄存器来进行
4.以GPC1_3,GPC1_4对应的寄存器为例(P141)
GPC1CON特点:
GPC1组的配置寄存器,用于配置GPIO的工作模式
可以配置为输入或者输出或者中断或者别的或者保留
对于LED应该配置为输出口
基地址0xE0200080
可读,可写
有效位数为20bit位
GPC1_3对应的bit位为:BIT[12:15]
GPC1_4对应的bit位为:BIT[16:19]
4bit对应一个GPIO
GPC1DAT特点:
数据寄存器,用于保存GPIO的状态(高/低电平)
例如:如果作为输出口,如果寄存器对应的bit的值为1,表示这个GPIO将输出高电平,否则低电平
基地址0xE0200084
可读,可写
有效的位数为5位
GPC1_3对应的bit位为:BIT[3]
GPC1_4对应的bit位为:BIT[4]
例如:
BIT[3] = 1,GPC1_3输出高电平
BIT[4] = 0,GPC1_4输出低电平
GPC1PUD[n]特点:
n表示对应的GPIO编号(0,1,2,3,4)
上/下拉电阻配置寄存器
基地址0xE0200088
可读,可写
有效的位数为10
GPC1_3对应的bit位为:BIT[6:7]
GPC1_4对应的bit位为:BIT[8:9]
例如:
BIT[6:7] = 00:禁止上下拉电阻功能
BIT[6:7] = 01:使能下拉电阻功能
BIT[6:7] = 10:使能上拉电阻功能
...
"上拉电阻":如果GPIO连接一个上拉电阻,会让GPIO的状态默认设置为高电平
"下拉电阻":
"GPIO悬空":不外接任何设备或者即使连接了某个外设
也不确定GPIO的状态到底是高还是低
"默认":CPU不操作,外设也操作GPIO,此时上/下拉电阻操作,设置为高或者低
7.6.编写裸板代码(无操作系统)
裸板程序的主要功能实现流水灯
编码实施步骤:
PC虚拟机中执行:
1.将/opt/目录的用户和组改为tarena用户和tarena组
sudo chown tarena /opt -R
sudo chgrp tarena /opt -R
2.创建ARM裸板代码的存放目录
mkdir /opt/arm/day03/1.0 -p
cd /opt/arm/day03/1.0
3.vim led.c
硬件寄存器的操作原则:
1.只能修改对应的BIT位,其余位不能乱改
2.先读取寄存器数据,
3.修改读取的数据
4.修改完毕再写回
保存退出
4.交叉编译led.c
"交叉编译":在PC机上编译源码,源码运行在ARM平台上
此时不能用gcc编译器编译,gcc针对于X86架构
5.虚拟机中添加设置交叉编译器(arm-linux-gcc)的环境变量,arm-linux-gcc针对于ARM架构
6.获取交叉编译器
ftp://ARM/resource.rar/arm gcc编译器/
arm-2009q3.tar.bz2
拷贝到虚拟机的/opt/目录下
cp arm-2009q3.tar.bz2 /opt
cd /opt
tar -xvf arm-2009q3.tar.bz2
rm arm-2009q3.tar.bz2
sudo vim /etc/environment //在环境变量中添加交叉编译器的命令支持
PATH="/opt/arm-2009q3/bin:...
也就是在PATH中添加/opt/arm-2009q3/bin的路径
将来在终端中直接输入arm-linux-gcc即可使用!
保存退出
重启虚拟机
重启以后验证交叉编译器是否能正常使用:
arm-linux-gcc -v //查看编译器的版本是否为4.4.1
7.交叉编译led.c
cd /opt/arm/day03/1.0
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
arm-linux-objcopy -O binary led.elf led.bin
cp led.bin /tftpboot
8.进入开发板的u-boot命令行模式,执行:
tftp 20008000 led.bin
go 20008000
9.有些同学的板子的GPIO不是GPC1_3/GPC1_4(Tarena)
而是GPC0_3/GPC0_4(融慧广泽)
10.添加GPC1_4(LED2)的开关操作
11.温习arm-linux-gcc或者gcc编译的过程
预处理->汇编->编译->链接
以交叉编译led.c为例:
1.预处理
cd /opt/arm/day03/1.0
arm-linux-gcc -E led.c -o led.i
生成预处理文件led.i
2.汇编
arm-linux-gcc -nostdlib -S led.i -o led.s
生成汇编文件led.s
3.编译(不连接标准C库)
arm-linux-as led.s -o led.o
4.连接
明确一般应用程序的main函数都是标准C库的启动代码来调用!
明确:程序一般包括代码段,数据段,BSS段
ELF文件格式:
ELF文件头
原始二进制代码
ELF文件尾
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
-nostartfiles:链接时不需要添加启动文件
-nostdlib:链接时不需要链接标准库
-Ttext=0x20008000:指定代码段的起始地址为0x20008000(内存地址)
-eled_test:指定程序的入口为led_test,仅仅是消除一个警告而已,没有实质意义
-o led.elf:最终生成一个ELF格式的文件
注意:ELF格式的文件只能在linux系统下运行
不能再裸板上运行,需要获取其中的原始二进制文件信息
5.如果是裸板,需要对ELF进行处理获取最终的二进制文件
arm-linux-objcopy -O binary led.elf led.bin
cp led.bin /tftpboot
开发板测试
6.注意:
arm-linux-gcc -nostdlib -c led.c -o led.o
等价于1+2+3三个步骤
问:为什么不能将delay定义放在led_test的前面
答:
正常情况(delay函数定义在led_test后面):
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
反汇编led.elf:
arm-linux-objdump -D led.elf > led.dis
vim led.dis
Disassembly of section .text: //表示代码段的开始
20008000 <led_test>:
//led_test函数的地址0x20008000
起始地址 机器码(CPU) 汇编指令(人)
20008000: e92d4800 等价 push { fp, lr}
异常情况(delay函数定义放在led_test前面):
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
反汇编led.elf:
arm-linux-objdump -D led.elf > led.dis
vim led.dis
2.了解蜂鸣器的硬件工作特性
查看底板原理图和芯片手册
注意:要连接号电源的跳帽
3.XpwmTOUT1是CPU的某个管脚
4.在底板原理图上搜索XpwmTOUT1,找到插座位J1D
5.打开核心板的原理图CW210_CORE_TARENA.pdf
6.在核心板原理图上搜索J1D
7.在核心板原理图上搜索XpwmTOUT1,会搜索一下信息:
XpwmTOUT1/GPD0_1:表名这个GPIO是复用的
即可用于XpwmTOUT1也可以用于普通的输入和输入(GPD0_1)
8.GPD0_1输出高电平,蜂鸣器响,否则不响
手机
2.嵌入式定义
iphone和低端的诺基亚
3.嵌入式系统的组成部分
硬件:
依赖用户需求
三大件:CPU,内存,闪存
外围设备:USB口(可以有),串口(必须有),网口(可以有),SD,摄像头,声卡,各种sensors
软件:
依赖硬件和用户需求
嵌入式linux软件包括:bootloader,kernel,rootfs
4.嵌入式linux系统开发的基本模式
左手PC机:
具备:串口,网口,USB口,linux系统,linux系统还要安装tftp网络服务
右手开发板:
具备:串口,网口,USB口
串口:用于双方通信
网口:主要用于下载
USB口:主要用于下载
5.嵌入式linux系统软件部署
嵌入式linux软件组成部分:
bootloader(BIOS),选在u-boot(属于bootloader一种)
linux内核(kernel)
根文件系统(rootfs)
5.1.bootloader部署
1.获取要部署的bootloader二进制镜像文件(u-boot.bin)
2.明确这个软件部署的位置
一般部署在nand,0地址处,启动方式要以nand启动
也可以部署在SD卡,在SD卡的512字节以后,要以SD卡
3.部署的过程
可以利用USB下载
可以利用SD下载
可以利用网络下载
dnw 20008000
或者
tftp 20008000 u-boot.bin
nand erase 0 100000
nand write 20008000
总结:不管是哪种烧写方法,前提是要运行一个u-boot
4.网络下载部署的注意事项
1.保证PC的linux系统安装和启动tftp网络服务
tftp(简单的文件传输服务)
sudo apt-get install tftpd-hpa
2.保证设置好一个共享目录
/tftpboot
将来开发板客户端就可以从虚拟机的tftpboot目录下载
3.保证启动tftp服务
sudo /etc/init.d/tftpd-hpa restart
4.利用开发板u-boot的相关tftp命令来部署软件
tftp 20008000 led.bin
go 20008000
nand erase 0 100000
nand write 20008000 0 100000
setenv
saveenv
ping:tftp下载之前一定要记得先ping!
ping不需要tftp服务!
5.此时此刻,开发板运行的程序仅仅是u-boot
还没有运行linux系统,说明以前UC的代码此时此刻不能在开发板上运行起来!
此时此刻的软件都是裸板程序
6.裸板程序:
在无操作系统下运行的软件,它们可以直接对硬件进行访问操作,不许要以文件的形式来访问硬件设备
在linux系统下必须以文件的形式访问硬件设备!
6.ARM裸板程序的开发
6.1.明确:
在无操作系统的状态下,软件访问硬件是"直接"访问
6.2.明确:
在ARM架构下,CPU访问外设都是以地址(指针)的形式访问,如果要访问某个外设,一定要搞清楚外设的基地址,例如TPAD的内存的基地址0x20000000
例如,现在向内存地址0x20000000写入0x55
//int a = 100; //仅仅告诉编译器,从内存某个位置分配4字节的内存,&a就是这块内存的首地址
unsigned long *p = (unsigned long *)0x20000000;
*p = 0x55;
6.3.明确:
对于S5PV210,32位处理器,CPU寻址的硬件地址范围:
0x00000000~0xFFFFFFFF;
6.4.明确:
“外设”:CPU核以外的任何硬件逻辑单元都是外设
不仅仅包括肉眼能看到的硬件,还包括处理器内部集成的硬件逻辑单元
6.5.初识S5PV210处理器
明确:S5PV210处理器的硬件特性都是在datasheet(芯片手册)--S5PV210_UM_REV1.1.pdf
resource/datasheet/S5PV210_UM_REV1.1.pdf
工作频率:1GHz
内部集成的外设:
GPIO控制器
RTC控制器
USB控制器
SD控制器
NAND控制器
...
6.6.初识TPAD开发板的硬件原理图
核心板的原理图:
CW210_CORE_LHGZ.pdf(融汇光泽)
CW210_CORE_TARENA.pdf(Tarena)
底板的原理图:
CW210-Peripherial.pdf
由硬件工程师提供!
6.7.外设地址的确定
对于CPU内部集成的外设,外设的基地址看芯片手册即可
对于CPU外部的外设,不仅仅要看CPU的芯片手册还要看原理图,以DM9000网卡为例:
通过原理图和芯片手册发现DM9000网卡的基地址就是0x88000000
切记:如果不清楚,一定咨询硬件工程师
7.面试题:谈谈ARM处理器如何某个外设?
以TPAD的两个LED灯的操作为例
案例目的:掌握裸板程序中,CPU如何访问某个外设
具体实施步骤:
7.1.明确用户的需求
实现一个流水灯(亮灭亮灭...)
7.2.明确两个LED的硬件操作特性
宏观看:大致看LED灯在开发板的位置
利用万用表测试LED的电源和底是否连接正确
细微看:看原理图,看LED在原理图的硬件连接方式
先看底板原理,找到LED灯硬件位置
7.3.通过原理图获取LED的硬件操作特性
第一个LED的开关由CPU的GPC1_3来决定
第二个LED的开关由CPU的GPC1_4来决定
GPC1_3/4输出高电平,灯亮
GPC1_3/4输出低电平,灯灭
问:GPC1_3/4的名如何起?
7.4.S5PV210的IO(input/output)管脚的特性
S5PV210的IO管脚由简称GPIO(通用输入和输出)
S5PV210包括237个复用GPIO
“复用”:一个GPIO既可以做输入口,又可以做输出口
又可以做别的功能的IO口
同一时刻只能有一个功能!
S5PV210并且把这些GPIO进行分组:A,B,C...等
一堆GPIO:
A组
A0组
包括8个GPIO
A1组
包括4个GPIO
B组
C组
C0组:5个
GPC0_0,GPC0_1,GPC0_2,...
C1组:5个
... GPC1_0,GPC1_1,GPC1_2,GPC1_3,GPC1_4
问:现在研究的问题是由原先的两个LED转变成研究两个GPIO管脚(GPC1_3,GPC1_4),CPU如何操作这两个管脚呢?
答:CPU通过操作GPIO控制器来间接操作IO的状态
切记:CPU访问某个GPIO都是通过访问GPIO控制器这个硬件逻辑单元间接访问GPIO
切记:GPIO控制器对于CPU核就是一个外设!
切记:就需要明确这个GPIO控制器外设的地址,这个地址只需查看CPU的芯片手册即可
7.5.GPIO控制器的硬件操作方法
0."寄存器":像内存一样的硬件,能够存储数据
1.GPIO控制器的操作都是通过一堆的GPIO的寄存器来进行
访问操作,例如:
GPC1_3,GPC1_4对应的寄存器有:
GPC1CON
GPC1DAT
GPC1PUD
...
2.明确:GPIO对应寄存器的基地址
寄存器名称 物理地址
GPC1CON 0xE0200080
GPC1DAT 0xE0200084
GPC1PUD 0xE0200088
例如:向GPC1CON寄存器写0x55
*((volatile unsigned long *)0xE0200080) = 0x55;
切记:
对于嵌入式软件开发,硬件的访问一定要加volatile
3.总结:
CPU访问某个GPIO,是通过访问对应的寄存器来进行
4.以GPC1_3,GPC1_4对应的寄存器为例(P141)
GPC1CON特点:
GPC1组的配置寄存器,用于配置GPIO的工作模式
可以配置为输入或者输出或者中断或者别的或者保留
对于LED应该配置为输出口
基地址0xE0200080
可读,可写
有效位数为20bit位
GPC1_3对应的bit位为:BIT[12:15]
GPC1_4对应的bit位为:BIT[16:19]
4bit对应一个GPIO
GPC1DAT特点:
数据寄存器,用于保存GPIO的状态(高/低电平)
例如:如果作为输出口,如果寄存器对应的bit的值为1,表示这个GPIO将输出高电平,否则低电平
基地址0xE0200084
可读,可写
有效的位数为5位
GPC1_3对应的bit位为:BIT[3]
GPC1_4对应的bit位为:BIT[4]
例如:
BIT[3] = 1,GPC1_3输出高电平
BIT[4] = 0,GPC1_4输出低电平
GPC1PUD[n]特点:
n表示对应的GPIO编号(0,1,2,3,4)
上/下拉电阻配置寄存器
基地址0xE0200088
可读,可写
有效的位数为10
GPC1_3对应的bit位为:BIT[6:7]
GPC1_4对应的bit位为:BIT[8:9]
例如:
BIT[6:7] = 00:禁止上下拉电阻功能
BIT[6:7] = 01:使能下拉电阻功能
BIT[6:7] = 10:使能上拉电阻功能
...
"上拉电阻":如果GPIO连接一个上拉电阻,会让GPIO的状态默认设置为高电平
"下拉电阻":
"GPIO悬空":不外接任何设备或者即使连接了某个外设
也不确定GPIO的状态到底是高还是低
"默认":CPU不操作,外设也操作GPIO,此时上/下拉电阻操作,设置为高或者低
7.6.编写裸板代码(无操作系统)
裸板程序的主要功能实现流水灯
编码实施步骤:
PC虚拟机中执行:
1.将/opt/目录的用户和组改为tarena用户和tarena组
sudo chown tarena /opt -R
sudo chgrp tarena /opt -R
2.创建ARM裸板代码的存放目录
mkdir /opt/arm/day03/1.0 -p
cd /opt/arm/day03/1.0
3.vim led.c
硬件寄存器的操作原则:
1.只能修改对应的BIT位,其余位不能乱改
2.先读取寄存器数据,
3.修改读取的数据
4.修改完毕再写回
保存退出
4.交叉编译led.c
"交叉编译":在PC机上编译源码,源码运行在ARM平台上
此时不能用gcc编译器编译,gcc针对于X86架构
5.虚拟机中添加设置交叉编译器(arm-linux-gcc)的环境变量,arm-linux-gcc针对于ARM架构
6.获取交叉编译器
ftp://ARM/resource.rar/arm gcc编译器/
arm-2009q3.tar.bz2
拷贝到虚拟机的/opt/目录下
cp arm-2009q3.tar.bz2 /opt
cd /opt
tar -xvf arm-2009q3.tar.bz2
rm arm-2009q3.tar.bz2
sudo vim /etc/environment //在环境变量中添加交叉编译器的命令支持
PATH="/opt/arm-2009q3/bin:...
也就是在PATH中添加/opt/arm-2009q3/bin的路径
将来在终端中直接输入arm-linux-gcc即可使用!
保存退出
重启虚拟机
重启以后验证交叉编译器是否能正常使用:
arm-linux-gcc -v //查看编译器的版本是否为4.4.1
7.交叉编译led.c
cd /opt/arm/day03/1.0
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
arm-linux-objcopy -O binary led.elf led.bin
cp led.bin /tftpboot
8.进入开发板的u-boot命令行模式,执行:
tftp 20008000 led.bin
go 20008000
9.有些同学的板子的GPIO不是GPC1_3/GPC1_4(Tarena)
而是GPC0_3/GPC0_4(融慧广泽)
10.添加GPC1_4(LED2)的开关操作
11.温习arm-linux-gcc或者gcc编译的过程
预处理->汇编->编译->链接
以交叉编译led.c为例:
1.预处理
cd /opt/arm/day03/1.0
arm-linux-gcc -E led.c -o led.i
生成预处理文件led.i
2.汇编
arm-linux-gcc -nostdlib -S led.i -o led.s
生成汇编文件led.s
3.编译(不连接标准C库)
arm-linux-as led.s -o led.o
4.连接
明确一般应用程序的main函数都是标准C库的启动代码来调用!
明确:程序一般包括代码段,数据段,BSS段
ELF文件格式:
ELF文件头
原始二进制代码
ELF文件尾
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
-nostartfiles:链接时不需要添加启动文件
-nostdlib:链接时不需要链接标准库
-Ttext=0x20008000:指定代码段的起始地址为0x20008000(内存地址)
-eled_test:指定程序的入口为led_test,仅仅是消除一个警告而已,没有实质意义
-o led.elf:最终生成一个ELF格式的文件
注意:ELF格式的文件只能在linux系统下运行
不能再裸板上运行,需要获取其中的原始二进制文件信息
5.如果是裸板,需要对ELF进行处理获取最终的二进制文件
arm-linux-objcopy -O binary led.elf led.bin
cp led.bin /tftpboot
开发板测试
6.注意:
arm-linux-gcc -nostdlib -c led.c -o led.o
等价于1+2+3三个步骤
问:为什么不能将delay定义放在led_test的前面
答:
正常情况(delay函数定义在led_test后面):
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
反汇编led.elf:
arm-linux-objdump -D led.elf > led.dis
vim led.dis
Disassembly of section .text: //表示代码段的开始
20008000 <led_test>:
//led_test函数的地址0x20008000
起始地址 机器码(CPU) 汇编指令(人)
20008000: e92d4800 等价 push { fp, lr}
异常情况(delay函数定义放在led_test前面):
arm-linux-gcc -nostdlib -c led.c -o led.o
arm-linux-ld -nostartfiles -nostdlib
-Ttext=0x20008000 -eled_test led.o -o led.elf
反汇编led.elf:
arm-linux-objdump -D led.elf > led.dis
vim led.dis
Disassembly of section .text: //表示代码段的开始
蜂鸣器提示:
1.明确用户的需求:响~不响2.了解蜂鸣器的硬件工作特性
查看底板原理图和芯片手册
注意:要连接号电源的跳帽
3.XpwmTOUT1是CPU的某个管脚
4.在底板原理图上搜索XpwmTOUT1,找到插座位J1D
5.打开核心板的原理图CW210_CORE_TARENA.pdf
6.在核心板原理图上搜索J1D
7.在核心板原理图上搜索XpwmTOUT1,会搜索一下信息:
XpwmTOUT1/GPD0_1:表名这个GPIO是复用的
即可用于XpwmTOUT1也可以用于普通的输入和输入(GPD0_1)
8.GPD0_1输出高电平,蜂鸣器响,否则不响
阅读全文
0 0
- 嵌入式开发基础二
- 嵌入式开发基础
- 嵌入式开发基础(1)
- 嵌入式开发基础(2)
- 嵌入式开发基础(3)
- 嵌入式开发基础(4)
- 嵌入式系统开发基础
- 嵌入式开发基础4
- 嵌入式开发基础3
- 嵌入式开发基础笔记
- 嵌入式开发基础一
- 嵌入式开发IO基础
- 嵌入式视频处理基础(二)
- 零基础学嵌入式开发
- 嵌入式开发必备linux基础
- 嵌入式开发基础--Linux与windows的共享问题解决方法二
- 嵌入式开发基础--关于Linux与windows的共享问题解决方法二的补充
- tiny4412-arm嵌入式开发裸板驱动 (二):arm基础GPIO操作
- APP及H5的埋点设置
- cdoj_758_P酱的冒险旅途
- Apache2.4 启动闪退
- composer安装流程
- socket系列(三)——Spring-socket实时通信、推送
- 嵌入式开发基础二
- tensorflow实现对图像的编码
- 定点乘法技术
- Linux运维笔记-文档总结-postfix邮件传输服务
- 在线聊天系统,关键代码,(jquery.ajax)
- HMM之维特比算法
- zabbix安装配置
- Apache+Tomcat实现负载均衡及集群(session同步)--三、动静分离(1)使用mod_jk
- HardFault_Handler问题查找方法