深入探索物联网3:嵌入式系统裸机开发
1.嵌入式系统裸机
嵌入式系统裸机是指只有硬件部分,没有安装任何软件的嵌入式系统。
2.裸机开发概念
裸机开发是指在没有操作系统支持的情况下,直接对硬件进行编程的开发方式。在裸机开发中,开发者使用汇编语言或高级语言直接编写程序,这些程序将直接运行在硬件平台上,没有操作系统的介入。
裸机开发由于没有操作系统的支持,开发者需要直接管理硬件资源,包括内存、CPU、外设等,以及需要自行解决开发中的错误处理、任务调度、资源管理等问题,这意味着开发者需要了解硬件的特性和工作原理,这为开发者增加了开发的复杂性和难度。
尽管裸机开发具有一定的局限性,但裸机开发的程序通常具有较小的体积和较高的执行效率,因为它们不需要与操作系统进行交互,也没有额外的系统开销。同时,在一些对实时性要求极高、资源受限或需要直接控制硬件的场合,裸机开发能够提供更好的性能和灵活性。
3.裸机开发的特点
裸机没有操作系统,开发者需要直接操作硬件的寄存器以控制硬件。
系统调用是操作系统提供给应用程序的一组编程接口,但裸机是没有安装操作系统的,因此系统调用无法被使用。
如S5P6818开发板使用寻址空间0x40000000 ~ 0xBFFFFFFF范围内的地址对DDR3进行读写操作。
如S5P6818开发板使用寻址空间0xC0000000 ~ 0xDFFFFFFF范围内的地址控制与外设的数据传输。
程序的编译链接过程分为预处理、编译、汇编和链接四个过程,为方便通常会将四步合成一步。但在裸机开发中,由于裸机没有操作系统管理内存,因此需要在链接时手动指定程序在内存的起始地址,这样预处理、编译和汇编可以三步合成一步执行,链接单独一步执行。
程序编译链接成功后,会生成ELF格式的可执行文件,但裸机不可运行ELF文件,这是因为ELF文件包含了许多与操作系统交互的信息,如动态链接、符号解析等,这些在裸机环境中是不可用的。
4.交叉编译器
交叉编译器是一种特殊的编译器,它用于在一个平台上生成可在另一个平台上运行的代码。这意味着,开发人员可以在一个操作系统(例如,Linux)上使用交叉编译器来编译代码,而生成的可执行文件或库则可以在完全不同的操作系统或硬件架构(例如,ARM架构的嵌入式系统)上运行。这种能力使得交叉编译器在裸机开发、嵌入式系统开发、操作系统开发以及跨平台软件开发中非常有用。下面是交叉编译器的安装步骤:
第1步:获取交叉编译器
交叉编译器下载地址:点击下载 提取码:7lyd
第2步:安装交叉编译器
tar xvf arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2
mkdir /usr/local/arm-linux-gcc-4.6.4
cd opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4
cp -r * /usr/local/arm-linux-gcc-4.6.4
export PATH=/usr/local/arm-linux-gcc-4.6.4/bin:$PATH
第3步:执行arm-linux-gcc -v命令验证交叉编译器是否安装成功,安装成功如下图:
5.SecureCRT
SecureCRT是一款用于链接远程系统的工具。可以使用SecureCRT链接开发板,通过SecureCRT操作开发板。
SecureCRT下载地址:点击下载
SecureCRT的安装和破解教程请自行百度。
5.1.SecureCRT链接开发板
第1步:链接电脑与开发板
第2步:配置串口
Port请选择第①步使用的端口。参数配置完成后点击“Connect”按钮。
第3步:启动开发板验证SecureCRT与开发板是否链接成功
开发板启动后,SecureCRT若是打印信息,则说明连接成功。
打印信息如上图(上图只是部分信息的截图)
5.2.SecureCRT常用操作介绍
5.2.1.SecureCRT与开发板快速链接
在串口配置成功后,会在如下图处记录。双击“Serial-COM1”会打开会话窗口并链接。
5.2.2.修改SecureCRT会话窗口的背景和字体
6.裸机烧写程序
裸机烧写程序是指将裸机可运行的二进制文件烧写到开发板的过程。裸机烧写程序通常需要使用特定的工具,这些工具根据目标硬件、开发环境和需求的不同而有所差异。常见的裸机烧写程序工具有JTAG工具、SD卡烧写工具和U-Boot工具。
6.1.JTAG烧写工具
JTAG是一种硬件调试接口标准,它允许开发者直接访问和控制目标硬件的寄存器和存储器。常用的JTAG工具有OpenJTAG、JLink等。
6.2.SD卡烧写工具
对于某些开发板,可以通过SD卡来烧写裸机程序。例如,MiniTools工具可以用于烧写系统或裸机程序到TQ210等开发板的SD卡中。此外,也有专门的SD卡烧写工具,如SDCardWriter,它类似于Linux中的dd命令,可以将裸机程序烧写到SD卡的指定地址。
6.3.U-Boot烧写工具
U-Boot是一个开源的引导加载程序(Bootloader),它可以在裸机上运行并加载操作系统或裸机程序,U-Boot的更多介绍请查看《物联网之嵌入式系统启动》文章的“嵌入式系统启动过程”、“Bootloader种类”和“U-Boot移植”章节。
本文章使用此工具烧写裸机程序。
7.裸机开发过程
7.2.过程
第1步:创建C源文件,如native.c
第2步:编写裸机程序
第3步:执行如下命令编译C源文件生成目标文件
arm-linux-gcc -c -o <目标文件名称>.o <C源文件名称>.c
第4步:执行如下命令链接目标文件生成可执行文件
arm-linux-ld -o <可执行文件名称> <目标文件名称>.o -Ttext=<程序在内存的起始地址>
第5步:执行如下命令去除elf格式生成裸机运行的二进制文件
arm-linux-objcopy -O binary -S <可执行文件名称> <二进制文件名称>.bin
第6步:通过SecureCRT将裸机运行的可执行文件烧写到开发板
loadb <二进制文件烧写到内存的地址>
// <二进制文件烧写到内存的地址>需与<程序在内存的起始地址>相同
若是开发板没有loadb命令,请查看本文章的“启用loadb命令”章节。
第7步:执行如下命令运行程序
go <程序在内存的起始地址>
第8步:查看运行结果
7.2.示例
第1步:创建native.c文件
第2步:编写裸机程序,代码如下
int _start(int argc, char *argv[])
{
// 0xC00A1020地址映射到向UART0串口发送数据的寄存器
// 使数据通过UART0窗口发送到SecureCRT
// (如何查找寄存器的映射地址会在后续的文章中介绍)
unsigned char *p = (unsigned char *)0xC00A1020;
unsigned char *str = "hello world!\n";
while(*str){
*p = *str++;
}
return 0;
}
第3步:执行如下命令编译C源文件生成目标文件
arm-linux-gcc -c -o native.o native.c
第4步:执行如下命令链接目标文件生成可执行文件
arm-linux-ld -o native native.o -Ttext=0x48000000
第5步:执行如下命令去除ELF格式生成裸机运行的二进制文件
arm-linux-objcopy -O binary -S native native.bin
第6步:通过SecureCRT将裸机运行的可执行文件烧写到开发板
loadb 0x48000000
第7步:执行如下命令运行程序
go 0x48000000
第8步:查看运行结果
8.启用loadb命令命令
8.1.查看开发板是否已启用loadb命令
第1步:启动开发板,在uboot三秒倒计时结束前按下空格键进入uboot模式
第2步:输入help命令查看是否有loadb命令
8.2.启用loadb命令
loadb命令是U-Boot的命令之一,启用loadb命令需要先了解U-Boot,了解U-Boot请查看《物联网之嵌入式系统启动》文章的“U-Boot移植”章节。
第1步:执行vim common/cmd_load.c命令查看loadb命令的程序是否已实现
第2步:执行vim include/configs/x6818.h命令,添加如下代码
#define CONFIG_CMD_LOADB 1
第3步:根据《物联网4(嵌入式系统启动过程)》文章的“U-Boot编译”和“U-Boot烧写”章节对U-Boot编译并烧写
第4步:进入uboot模式下,执行help命令查看loadb命令是否已启用
作者:知可知