
使用ARM Linux GCC 2.95.3编译你的嵌入式应用程序——一份详细教程
嵌入式系统是一种特殊的计算机系统,通常用于控制或监测各种设备和机器。由于其特殊的应用环境,嵌入式系统通常要求高度稳定、高效并具有可靠性。在实际的开发中,嵌入式系统应用程序的编写离不开编译器的支持,ARM Linux GCC是一种广泛使用的嵌入式系统编译器。
本文将为大家介绍使用ARM Linux GCC 2.95.3编译嵌入式应用程序的详细教程,包括环境搭建、编写应用程序、编译等过程。
一、环境搭建
在使用ARM Linux GCC编译嵌入式应用程序之前,我们需要先搭建好相应的开发环境。以下是环境搭建的具体步骤:
1.安装Linux系统
我们需要安装适合的Linux系统,以便使用ARM Linux GCC。在安装时,我们需要选择支持ARM架构的版本,如Ubuntu 14.04等。
2.安装ARM GCC编译器
我们需要下载并安装支持ARM架构的GCC编译器,建议使用2.95.3版本。我们需要下载GCC源码,然后进行解压缩,进入解压后的目录,执行以下命令:
./configure –target=arm-elf –prefix=/usr/local/arm
make
make install
3.设置环境变量
为了方便使用ARM GCC编译器,我们需要将其加入环境变量中。可以在.bashrc或/etc/profile文件中设置,添加以下内容:
export PATH=$PATH:/usr/local/arm/bin
source /etc/profile
至此,我们已经完成了ARM Linux GCC的环境搭建。
二、编写应用程序
在编写嵌入式应用程序之前,我们需要先了解一些基础知识。嵌入式应用程序使用的语言一般为C/C++,而且在编写时需要注意内存的使用和程序的大小等问题。下面我们将以一个简单的LED闪烁应用程序为例进行讲解。
1.包含头文件
我们首先需要在C文件的开头包含相应的头文件,以便使用其中的函数和宏定义。
#include
#include
#include
#include
#include
#define GPIO_BASE 0x20230000
#define GPIO_SIZE 4096
#define GPIO_OUT 0x1c
2.定义GPIO输出
接下来,我们需要定义GPIO输出,并将其映射到内存。
int mem_fd;
char *gpio_mem, *gpio_map;
volatile unsigned *gpio;
if((mem_fd = open(“/dev/mem”, O_RDWR | O_SYNC))
gpio_mem = (char *)malloc(GPIO_SIZE + (sysconf(_SC_PAGE_SIZE)-1));
if((unsigned long)gpio_mem % sysconf(_SC_PAGE_SIZE)) {
gpio_mem += sysconf(_SC_PAGE_SIZE) – ((unsigned long)gpio_mem % sysconf(_SC_PAGE_SIZE));
}
gpio_map = mmap(
NULL,
GPIO_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
mem_fd,
GPIO_BASE
);
close(mem_fd);
if((long)gpio_map
gpio = (volatile unsigned *)gpio_map;
3.GPIO输出控制
接下来,我们可以通过设置相应的输入输出状态,控制GPIO输出,以实现LED的闪烁。
while(1) {
*gpio |= (1
usleep(500000);
*gpio &= ~(1
usleep(500000);
}
四、编译
编写完嵌入式应用程序后,我们需要使用ARM Linux GCC进行编译。以下是编译的详细步骤:
1.编写Makefile
我们需要在应用程序源码目录中编写Makefile,进行编译。
示例Makefile代码:
CC = arm-elf-gcc
CFLAGS = -Wall -O2
OUT = led
all: $(OUT)
$(OUT): $(OUT).c
$(CC) $(CFLAGS) -o $(OUT) $(OUT).c
clean:
rm -f $(OUT)
2.执行make命令
在执行make命令前,我们需要先确认当前已设置好ARM Linux GCC环境变量。随后,我们可以进入应用程序源码目录,执行以下命令进行编译:
make
3.运行应用程序
编译完成后,我们可以运行应用程序,向GPIO输出控制信号,实现LED的闪烁。
四、
相关问题拓展阅读:
- 如何建立Linux下的ARM交叉编译环境
- linux arm交叉工具链建好后在生成的文件夹下面有两个bin文件,一个在根目录,另外一个在其子目录中。
如何建立Linux下的ARM交叉编译环境
这个过程如下
1. 下载源文件、补丁和建立编译的目录
2. 建立内核头文件
3. 建立二进制工具(binutils)
4. 建立初始编译器(bootstrap gcc)
5. 建立c库(glibc)
6. 建立编译器(full gcc)
下载源文件、补丁和建立编译的目录
1. 选定软件版本号
选择软件版本号时,先看看glibc源代码中的INSTALL文件。那里列举了该版本的glibc编译时所需的binutils 和gcc的版本号。例如在 glibc-2.2.3/INSTALL 文件中推荐 gcc 用 2.95以上,binutils 用 2.10.1 以上版本。
我选的各个软件的版本是:
linux-2.4.21+rmk2
binutils-2.10.1
gcc-2.95.3
glibc-2.2.3
glibc-linuxthreads-2.2.3
如果你选的glibc的版本号低于2.2,你还要下载一个叫glibc-crypt的文件,例如glibc-crypt-2.1.tar.gz。 Linux 内核你可以从
www.kernel.org
或它的镜像下载。
Binutils、gcc和glibc你可以从FSF的FTP站点 或它的镜像去下载。在编译glibc时,要用到 Linux 内核中的 include 目录的内核头文件。如果你发现有变量没有定义而导致编译失败,你就改变你的内核版本号。例如我开始用linux-2.4.25+vrs2,铅敏卜编译glibc-2.2.3 时报 BUS_ISA 没定义,后来发现在 2.4.23 开始它的名字被改为 CTL_BUS_ISA。如果你没有完全的把握保证你改的内核改完全了,就不要动内核,而是把你的 Linux 内核的版本号降低或升高,来适应 glibc。
Gcc 的版本号,推荐用 gcc-2.95 以上的。太老的版本编译可能会出问题。Gcc-2.95.3 是一个比较稳定的版本,也是内核开发人员推荐用的一个 gcc 版本。
如果你发现无法编译过去,有可能是你选用的软件中有的加入了一些新的特性而其他所选软件不支持的原因,就相应降低该软件的版本号。例如槐穗我开始用 gcc-3.3.2,发现编译不过,报 as、ld 等版本太老,我就把 gcc 降为 2.95.3。太新的版本大多没经过大量的测试,建议不要选用。
2. 建立工作目录
首先,我们建立几个用来工作的目录:
在你的用户目录,我用的是用户liang,因此用户目录为 /home/liang,先建立一个项目目录embedded。
$pwd
/home/liang
$mkdir embedded
再在这个项目目录 embedded 下建立三个目录 build-tools、kernel 和 tools。
build-tools-用来存放你下载的 binutils、gcc 和 glibc 的源代码和用来编译这些源代码的目录。
kernel-用来存放你的内核源代码和内核补丁。
tools-用来存放编译好的交叉编译工具和库文件。
$cd embedded
$mkdir build-tools kernel tools
执行完后目录结构如下:
$ls embedded
build-tools kernel tools
3. 输出和环境变量
我们输拿运出如下的环境变量方便我们编译。
$export PRJROOT=/home/liang/embedded
$export TARGET=arm-linux
$export PREFIX=$PRJROOT/tools
$export TARGET_PREFIX=$PREFIX/$TARGET
$export PATH=$PREFIX/bin:$PATH
如果你不惯用环境变量的,你可以直接用绝对或相对路径。我如果不用环境变量,一般都用绝对路径,相对路径有时会失败。环境变量也可以定义在.bashrc文件中,这样当你logout或换了控制台时,就不用老是export这些变量了。
体系结构和你的TAEGET变量的对应如下表
你可以在通过glibc下的config.sub脚本来知道,你的TARGET变量是否被支持,例如:
$./config.sub arm-linux
arm-unknown-linux-gnu
在我的环境中,config.sub 在 glibc-2.2.3/scripts 目录下。
网上还有一些 HOWTO 可以参考,ARM 体系结构的《The GNU Toolchain for ARM Target HOWTO》,PowerPC 体系结构的《Linux for PowerPC Embedded Systems HOWTO》等。对TARGET的选取可能有帮助。
4. 建立编译目录
为了把源码和编译时生成的文件分开,一般的编译工作不在的源码目录中,要另建一个目录来专门用于编译。用以下的命令来建立编译你下载的binutils、gcc和glibc的源代码的目录。
$cd $PRJROOT/build-tools
$mkdir build-binutils build-boot-gcc build-gcc build-glibc gcc-patch
build-binutils-编译binutils的目录
build-boot-gcc-编译gcc 启动部分的目录
build-glibc-编译glibc的目录
build-gcc-编译gcc 全部的目录
gcc-patch-放gcc的补丁的目录
gcc-2.95.3 的补丁有 gcc-2.95.3-2.patch、gcc-2.95.3-no-fixinc.patch 和gcc-2.95.3-returntype-fix.patch,可以从
下载到这些补丁。
再将你下载的 binutils-2.10.1、gcc-2.95.3、glibc-2.2.3 和 glibc-linuxthreads-2.2.3 的源代码放入 build-tools 目录中
看一下你的 build-tools 目录,有以下内容:
$ls
binutils-2.10.1.tar.bz2 build-gcc gcc-patch
build-binutluild-glibcglibc-2.2.3.tar.gz
build-boot-gccgcc-2.95.3.tar.gz glibc-linuxthreads-2.2.3.tar.gz
建立内核头文件
把你从
www.kernel.org
下载的内核源代码放入 $PRJROOT /kernel 目录
进入你的 kernel 目录:
$cd $PRJROOT /kernel
解开内核源代码
$tar -xzvf linux-2.4.21.tar.gz
或
$tar -xjvf linux-2.4.21.tar.bz2
小于 2.4.19 的内核版本解开会生成一个 linux 目录,没带版本号,就将其改名。
$mv linux linux-2.4.x
给 Linux 内核打上你的补丁
$cd linux-2.4.21
$patch -p1 gcc/cstamp-h.in
在我们编译并安装 gcc 前,我们先要改一个文件 $PRJROOT/gcc/config/arm/t-linux,把
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC
这一行改为
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
你如果没定义 -Dinhibit,编译时将会报如下的错误
stdlib.h: No such file or directory
unistd.h: No such file or directory
make: Error 1
make: Error 2
make: Error 1
make: Error 2
linux arm交叉工具链建好后在生成的文件夹下面有两个bin文件,一个在根目录,另外一个在其子目录中。
应该是arm-9tdmi-linux-gnu-gcc
gcc-2.95.3太老了, 新的gcc编译器不支持它的源码。
你可以:此祥
1,建立gcc-3.4以前的本地工具链编译gcc-2.95.3
2,用新的版本的隐扒桥gcc制作交叉编译工具。
3,或者你可以修改2.95.3的源码让它可以通过编译。
_
看你现在用的灶猛gcc是什么版本, 建议更低不要低于3.4. 另外, gcc到底用什么版本和你的binutils , glibc的版本有关, 要不会有问题。
是Makefile上的编译目标语句,如
TARGET = $(QPEDIR)/bin/
arm linux gcc 2.95.3的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于arm linux gcc 2.95.3,使用arm linux gcc 2.95.3编译你的嵌入式应用程序——一份详细教程,如何建立Linux下的ARM交叉编译环境,linux arm交叉工具链建好后在生成的文件夹下面有两个bin文件,一个在根目录,另外一个在其子目录中。的信息别忘了在本站进行查找喔。
香港服务器首选树叶云,2H2G首月10元开通。
树叶云(www.IDC.Net)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/185809.html<