微操控器制造商的开发板,以及他们与开发板一同供给的软件项目例程,在工程师着手一个新规划时可以供给很大协助。但在规划项目完结其前期阶段后,进一步规划时,制造商供给的软件也或许会导致一些问题。
运用实时操作体系作为运用程序代码渠道的规划还面临着许多应战,比方怎么将功用分配给不同的并行使命、怎么规划高牢靠的进程间通讯、以及怎么在硬件上测验整个软件包等问题。
越来越多的OEM厂商发现,防止上述两个问题的最好办法,是运用依据开源、经过验证、可扩展、可运转在不同硬件渠道的操作体系Linux开端新的规划。就现已被移植到各种计算机硬件渠道的操作体系的数量来说,Linux名列前茅。Linux的衍生版别已运转在十分广泛的嵌入式体系中,包括:网络路由器、移动电话、修建主动化操控、电视机和视频游戏操控台。
尽管Linux被成功运用,但并不意味着它很简略运用。Linux包括的代码超越一百万行,其运作带有明显的Linux办法论滋味,初学者或许难以敏捷把握。
因而,本文的宗旨是为运用Linux的嵌入式操作体系版别——μClinux,开端一个新的规划项目,该攻略共分为五个进程。为了阐明该攻略,本文介绍了在意法半导体的STM32F429微操控器(ARMCortex-M4内核,最高180MHz)上的一个μClinux项目完结,运用了Emcraft的STM32F429DiscoveryLinux板支撑包(BSP)。
进程1:Linux东西和项目布局
每个嵌入式软件规划都从挑选适宜的东西开端。
东西链是一组衔接(或链接)在一同的软件开发东西,它包括比如GNU编译器调集(GCC)、binutils(一组包括衔接器、汇编器和其它用于方针文件和档案东西的开发东西)和glibc(供给体系调用和根本函数的C函数库)等组件;在某些情况下,还或许包括编译器和调试器等其它东西。
用于嵌入式开发的东西链是一个穿插东西链,更常见的叫法是穿插编译器。
GNUBinuTIls是嵌入式Linux东西链的第一个组件。GNUBinuTIls包括两款重要东西:
●“as”,汇编器,将汇编代码(GCC所生成)转换成二进制代码
●“ld”,衔接器,将离散方针代码段衔接到库或构成可履行文件
编译器是东西链的第二个重要组成部分。在嵌入式Linux,它被称为GCC,支撑许多种微操控器和处理器架构。
接下来是C函数库。它完结Linux的传统POSIX运用编程接口(API),该API可被用来开发用户空间运用。它经过体系调用与内核对接,并供给高阶服务。
工程师有几种C函数库挑选:
●glibc是开源GNU项目供给的可用C函数库。该库是全功用、可移植的,它契合Linux规范。
●嵌入式GLIBC(EGLIBC)是一款针对嵌入式体系优化的衍生版。其代码是精简的,支撑穿插编译和穿插测验,其源代码和二进制代码与GLIBC的兼容。
●uClibc是另一款C函数库,可在闪存空间有限、和/或内存占用有必要最小的情况下运用。
调试器一般也是东西链的一部分,由于在方针机上调试运用程序运转时,需求一个穿插调试器。在嵌入式Linux范畴,GDB是常用调试器。
上述东西是如此地不可或缺,但当它们各自为战时,会花太长时刻来编译Linux源代码并将其整组成终究映像(image)。走运的是,Buildroot(主动生成穿插编译东西的东西)会主动完结构建一个完好嵌入式体系的进程,并经过发生下述任一或一切使命,简化了穿插编译:
●穿插编译东西链
●根文件体系
●内核映像
●引导映像
对嵌入式体系规划师来说,还可以方便地运用一种东西(uTIlity)聚合东西,如BusyBox,这种东西将一般最需求的东西整合在一同。依据BusyBox的信息页面介绍,“它将许多常用UNIX东西的微型版别整组成一个小的可履行文件。它供给了对大多数你一般会在GNUfileuTIls和shellutils等东西中看到的东西的代替。BusyBox里的东西一般比其全功用GNU对应版别的挑选少;但所包括选项所供给的预期功用和行为则与对应的GNU所供给的几无差别。对任何小或嵌入式体系来说,BusyBox供给的环境都是适当完好的。”
最终一个重要东西是一款BSP,是为搭载了项目方针MCU或处理器的主板专门做的。
BSP包括预先装备的东西,以及将操作体系加载到主板的引导加载程序。它还为内核和器材驱动器供给源代码(见图1)。
图1:用于STM32F429Discovery板的EmcraftBSP的首要部件
进程2:引导序列、时钟体系、存储器和串行接口
典型的嵌入式Linux发动次序履行如下:
1)引导加载程序固件(示例项目里的U-Boot)运转于方针MCU内置闪存(无需外部存储器),并在上电/复位后,履行一切必需的初始化作业,包括设置串口和用于外部存储器(RAM)拜访的存储器操控器。
2)U-Boot可将Linux映像从外部Flash转移到外部RAM,并将操控交接到RAM中的内核进口点。可压缩Linux映像以节约闪存空间,价值是在发动时要支付解压缩时刻。
3)Linux进行引导并装置依据RAM的文件体系(initramfs)作为根文件体系。在项目构建时,Initramfs被填充以所需的文件和目录,然后被简略地链接到内核。
4)在Linux内核下,履行/sbin/init。/sbin/init程序依照/etc/inittab中装备文件的描绘对体系进行初始化。
5)一旦初始化进程完结运转级履行和/sbin/init里的指令,它会发动一个登录进程。
6)壳初始化文件/etc/profile的履行,标志着发动进程的完结。
经过使能就地履行(ExecuteInPlace——XIP)可以明显缩短发动时刻、提高全体功能,XIP是从闪存履行代码的办法。一般,Linux代码是从闪存加载到外部存储器,然后从外部存储器履行。经过从闪存履行,因不再需仿制这步,然后只需较少的存储器,且只读存储器不再占程序空间。
本文的示例项目依据STM32F429MCU。事实上,用户或许会发现,开端时,STM32F4系列MCU的外设初始化不简略把握。走运的是,意法半导体开发了一些东西来协助处理这一问题。STM32CubeMX初始化代码生成器(部件编号UM1718)归于最新的。该东西包括外设初始化的每一个细节,在装备外设时,会显现正告和过错、并正告硬件抵触。
对小型嵌入式Linux项目来说,STM32F429MCU内部闪存足够用。重要的是要记住:嵌入式Linux项目中运用多个二进制映像(引导加载程序、Linux内核和根文件体系):这些都需求闪存扇区鸿沟对齐。这就防止了在装载一个图画时,另一图画被部分删去或损坏的危险。
进程3:在主机上装置Linux
要构建一个嵌入式Linux项目,一台Linux主机是必需的。关于WindowsPC,最好是装置OracleVirtualBox,以创立“一台”512MbyteRAM和16Gbyte硬盘的新虚拟机。
有许多Linux版别可用;据笔者的经历,Debian便是与VirtualBox环境相匹配的一款。这款Linux主机有必要可以拜访互联网,以便下载针对这款ARMCortex-M方针MCU的GNU穿插编译东西。规划师将创立一个相似于图1所示的树形结构,并将穿插构建东西提存到/tools文件夹。
在这点上,有必要树立一个ACTIVATE.sh脚本。只需运用下列代码就可完结。(<……>是提取到的GNU东西文件夹途径):
exportINSTALL_ROOT=<…….>
exportPATH=$INSTALL_ROOT/bin:$PATH
exportCROSS_COMPILE=arm-uclinuxeabiexport
CROSS_COMPILE_APPS=arm-uclinuxeabiexport
MCU=STMDISCO
exportARCH=arm
在洁净的Linux体系中装置GNU东西,但其运用并非自给自足,实际上还需求其它体系的合作。其运转实际上依赖于若干其它体系组件(如主机C/C++编译器、规范C函数库头文件,以及一些体系东西)。取得这些必要组件的一种办法是装置用于C的Eclipse集成开发环境(IDE)。除处理这个火烧眉毛的问题外,EclipseIDE还可在开发进程中的许多其它方面供给协助,当然,胪陈EclipseIDE的特性不是本文意图。
现在,是时分启用Linux终端东西了:点击“运用程序(Applications)”,然后“附件(Accessories)”和“终端(Terminal)”(见图2)。
图2:Linux包括的“终端(Terminal)”东西和“文件(Files)”、一种相似Windows资源管理器的图形化东西。
终端是用于装备Linux主机和构建嵌入式Linux运用程序的首要东西。键入以下指令来装置Eclipse和其它所需东西:
su[输入根用户暗码]
apt-getinstalleclipse-cdt
apt-getinstallgenromfs
apt-getinstalllibncurses5-dev
apt-getinstallgit
apt-getinstallmc
预备该Linux项意图最终一步是下载STM32F429DiscoveryBuildroot,并解压到/uclinux文件夹。
进程4:用Buildroot构建μClinux
现在有必要封闭从前运用根用户装备文件的终端,并发动一个新终端。在指令行中输入“mc”,并运用导航器导航到“Documents”,然后输入“uClinux”指令。按Ctrl+O并激活LinuxARMCortex-M开发部分,并运转“.ACTIVATE.sh”指令。再次按下Ctrl+O并进入“stm32f429-linux-builder-master”文件夹。
用户现在有两个挑选。假如运用VirtualBox中的示例项目,请遵从“makeclean”和“makeall”指令序列。假如预备一个全新环境,运用“make”指令。约30分钟后,新的μClinux映像将可用,如下所示:
out\uboot\u-boot.bin
out\kernel\arch\arm\boot\xipuImage.bin
out\romfs.bin
将这些新映像写入闪存。假如运用Windows和ST-LINK东西,下面的代码将作业:
ST-LINK_CLI.exe-ME
ST-LINK_CLI.exe-P“u-boot.bin”0x08000000
ST-LINK_CLI.exe-P“xipuImage.bin”0x08020000
ST-LINK_CLI.exe-P“romfs.bin”0x08120000
将串行调试器(serialconsole)衔接到方针电路板(外部RX=>PC10、外部TX=>PC11、115200bits/s、8个数据位、无奇偶校验、1个中止位形式),然后按下复位按钮,该μClinux项目将发动运转。开机输出将显现在串行调试器上,显现屏将呈现Linux的企鹅标识。
进程5:创立“你好,国际”运用
现在,依照代码示例和下面的阐明,将一个用户运用添加到μClinux项目中。
创立:“stm32f429-linux-builder-master/user/src/hello.c”文件:
#include
intmain(){
printf(“Hello,world\n”);
return0;
}
必要时运用Tab键,创立:“stm32f429-linux-builder-master/user/Makefile”文件:
CC=$(CROSS_COMPILE)gcc
LDFLAGS?=$(CFLAGS)
target_out?=out
all:checkdirs
[Tab]$(CC)$(LDFLAGS)src/hello/hello.c-o$(target_out)/bin/
hello$(LDLIBS)
[Tab]-rm-rf$(target_out)/bin/*.gdb
checkdirs:
[Tab]mkdir-p$(target_out)/bin
clean:
[Tab]-rm-rf$(target_out)
经过activate.sh脚本,在不激活穿插编译环境下,在主机测验“Hello,world”这个运用。
在/user文件夹下,输入:
makeall
./out/bin/hello
为将hello.c嵌入到LinuxBuildroot里的脚本,修正mk/rootf.mak文件,必要时,运用Tab键。(粗体字表明新行开端处):
…
user_hello:
[Tab]make-C$(user_dir)CROSS_COMPILE=$(CROSS_
COMPILE)CFLAGS=$(ROOTFS_CFLAGS)target_
out=$(target_out_user)
$(rootfs_target):$(rootfs_dir)$(target_out_busybox)/.config
user_hello
[Tab]cp-af$(rootfs_dir)/*$(target_out_romfs)
[Tab]cp-f$(target_out_kernel)/fs/ext2/ext2.ko$(target_out_romfs)/lib/modules
[Tab]cp-f$(target_out_kernel)/fs/mbcache.ko$(target_out_romfs)/lib/modules
[Tab]cp-f$(target_out_user)/bin/*$(target_out_romfs)/usr/bin
…
需对mk/defs.mak文件做最终修正。参加以下几行:
…
user_dir:=$(root_dir)/user
target_out_user:=$(target_out)/user
user_dir:=$(root_dir)/user
target_out_user:=$(target_out)/user
一旦在方针MCU上建成、下载并运转映像,就可在/usr/bin目录中找到该运用程序以及其它已有的运用程序。在衔接到Discovery板的终端上键入“hello[回车]”,可对该运用进行测验。