微控制器制造商的开发板,以及他们随开发板提供的软件项目示例,在开始新设计时对工程师有很大帮助。但是,在设计项目完成其早期阶段后,在进一步设计时,制造商提供的软件也会导致问题。使用实时操作系统作为应用程序代码平台的设计仍然面临着许多挑战,例如如何为不同的并行任务分配功能,如何设计高可靠的进程间通信,以及如何在平台上测试整个软件包。硬件。越来越多的OEM发现,避免上述两个问题的最佳方法是使用开源的、经过验证的、可扩展的操作系统Linux开始新的设计,该操作系统可以在不同的硬件平台上运行。就移植到各种计算机硬件平台的操作系统数量而言,Linux是首屈一指的。Linux的衍生产品已经在各种各样的嵌入式系统上运行,包括:网络路由器、移动电话、楼宇自动化控制、电视和视频游戏机。仅仅因为Linux使用成功并不意味着它很容易使用。Linux包含超过一百万行的代码,其操作具有鲜明的Linux方法论风味,初学者可能难以快速掌握。因此,本文的主要思想是使用Linux的嵌入式操作系统版本μClinux开始一个新的设计项目。该指南分为五个步骤。为了说明该指南,本文介绍了使用Emcraft的STM32F429DiscoveryLinux板级支持包(BSP)在STMicroelectronics的STM32F429微控制器(ARMCortex-M4内核,高达180MHz)上实施的μClinux项目。第1步:Linux工具和项目布局每个嵌入式软件设计都从选择正确的工具开始。工具链是一组连接(或链接)在一起的软件开发工具,其中包括GNUCompilerCollection(GCC)、binutils(一组开发工具,包括链接器、汇编器和其他用于目标文件和存档的工具)等工具)和glibc(一个提供系统调用和基本功能的C函数库);在某些情况下,还可能包括其他工具,例如编译器和调试器。用于嵌入式开发的工具链是交叉工具链,通常称为交叉编译器。GNUBinutils是嵌入式Linux工具链的第一个组件。GNUBinutils包含两个重要工具:“as”,汇编器,将汇编代码(由GCC生成)转换为二进制代码“ld”,链接器,将离散的目标代码段链接到库或形成可执行文件编译器是第二个重要部分工具链。在嵌入式Linux中,它被称为GCC,支持许多微控制器和处理器架构。接下来是C函数库。它实现了Linux传统的POSIX应用程序编程接口(API),可用于开发用户空间应用程序。它通过系统调用与内核交互并提供高级服务。工程师有多种C库可供选择:glibc是开源GNU项目提供的可用C库。该库功能齐全、可移植,并且符合Linux标准。嵌入式GLIBC(EGLIBC)是为嵌入式系统优化的衍生产品。其代码精简,支持交叉编译和交叉测试,源代码和二进制代码兼容GLIBC。uClibc是另一个C库,可在闪存空间有限和/或内存占用必须最小化时使用。调试器通常也是工具链的一部分,因为需要交叉调试器来调试目标机器上的应用程序运行时。在嵌入式Linux领域,GDB是常用的调试器。上面的工具是如此不可或缺,但是当它们各自独立工作时,编译Linux源代码并将其集成到最终镜像(image)中的时间太长了。幸运的是,Buildroot(一种自动生成交叉编译工具的工具)自动化了构建完整嵌入式系统的过程,并通过生成以下任何或所有任务简化了交叉编译:交叉编译工具链根文件系统内核映像引导映像是嵌入式系统设计人员还可以方便地使用诸如BusyBox之类的实用程序聚合器,它汇集了最常用的工具。根据BusyBox的信息页面,“它将许多常见UNIX工具的微型版本组合到一个小型可执行文件中。它提供了大多数工具的替代品,您通常会在GNUfileutils和shellutils等工具中看到它。BusyBox中的工具通常较少选择比他们的全功能GNU对应物;但所提供的选项提供了预期的功能和行为,这些功能和行为与相应的GNU提供的几乎相同。对于任何小型或嵌入式系统,BusyBox提供的环境都相当完整。“最后一个重要的工具是BSP,它是专门为带有项目目标MCU或处理器的电路板制作的。BSP包括预配置工具,以及将操作系统加载到电路板上的引导加载程序。它还提供内核和源代码与设备驱动程序一起提供(见图1)。图1:STM32F429探索板的EmcraftBSP的主要组件。第2步:启动顺序、时钟系统、内存和串行接口典型的嵌入式Linux启动顺序执行过程如下:1)Bootloader固件(示例工程中的U-Boot)运行在目标MCU的内置闪存上(无需外部存储器),上电/复位后,执行所有必要的初始化工作,包括设置串行端口和使用外部存储器内存控制器进行(RAM)访问。2)U-Boot可以将Linux映像从外部闪存传输到外部RAM,并将控制权移交给RAM中的内核入口点。Linux映像可以成为竞争者essed以节省闪存空间,代价是在启动时支付解压缩时间。3)Linux启动并挂载一个基于RAM的文件系统(initramfs)作为根文件系统。在项目构建时,Initramfs填充了所需的文件和目录,然后简单地链接到内核。4)在Linux内核下,执行/sbin/init。/sbin/init程序根据/etc/inittab中配置文件的描述初始化系统。5)一旦初始化过程完成了运行级别的执行和/sbin/init命令,它将开始一个登录过程。6)shell初始化文件/etc/profile的执行标志着启动过程的完成。通过启用就地执行(ExecuteInPlace——XIP),可以显着缩短启动时间和整体性能,XIP是从闪存执行代码的方法。通常情况下,Linux代码是从闪存??加载到外部存储器,然后从外部存储器执行的。通过从闪存执行,需要的内存更少,因为这一步不再重复,只读存储器不再占用程序空间。本文示例工程基于STM32F429MCU。实际上,用户可能会发现STM32F4系列MCU的外设初始化一开始并不容易掌握。幸运的是,STMicroelectronics开发了一些工具来帮助解决这个问题。STM32CubeMX初始化代码生成器(部件号UM1718)是最新的产品之一。该工具包括外设初始化的每一个细节,配置外设时显示警告和错误,硬件冲突警告。对于小型嵌入式Linux项目,STM32F429MCU的内部闪存足够了。重要的是要记住嵌入式Linux项目中使用了多个二进制映像(引导加载程序、Linux内核和根文件系统):这些都需要闪存扇区边界对齐。这避免了一个图像在加载另一个图像时被部分删除或损坏的风险。第3步:在主机上安装Linux要构建嵌入式Linux项目,需要一台Linux主机。对于WindowsPC,最好安装OracleVirtualBox以创建“一个”具有512MBRAM和16GB硬盘的新虚拟机。有许多可用的Linux发行版;根据我的经验,Debian是与VirtualBox环境相匹配的。Linux主机必须能够访问互联网才能为该ARMCortex-M目标MCU下载GNU交叉编译工具。设计人员将创建一个类似于图1所示的树结构,并将交叉构建工具拉到/tools文件夹中。此时,需要创建一个ACTIVATE.sh脚本。只需使用以下代码即可。(<......>为解压出来的GNU工具文件夹路径):exportINSTALL_ROOT=<......>exportPATH=$INSTALL_ROOT/bin:$PATHexportCROSS_COMPILE=arm-uclinuxeabiexportCROSS_COMPILE_APPS=arm-uclinuxeabiexportMCU=STMDISCOexportARCH=arm在干净的Linux系统中安装GNU工具,但其使用并不能自给自足,实际上需要其他系统的配合。它的运行实际上依赖于其他几个系统组件(如主机C/C++编译器、标准C库头文件和一些系统工具)。获得这些必要组件的一种方法是安装EclipseIntegratedDevelopmentEnvironment(IDE)forC。除了解决这个紧迫的问题外,EclipseIDE还可以在开发过程的许多其他方面提供帮助,尽管这不是本文详细介绍了EclipseIDE的特性。现在,是时候启用Linux终端工具了:单击“Applications”,然后单击“Accessories”和“Terminal”(参见图2)。图2:Linux包括“终端”工具和类似于Windows资源管理器的图形工具“文件”。终端是配置Linux主机和构建嵌入式Linux应用程序的主要工具。键入以下命令以安装Eclipse和其他所需工具:su[enterrootuserpassword]apt-getinstalleclipse-cdtapt-getinstallgenromfsapt-getinstalllibncurses5-devapt-getinstallgitapt-getinstallmc准备此Linux项目的最后一步是下载STM32F429DiscoveryBuildroot和解压到/uclinux文件夹。第4步:使用Buildroot构建μClinux现在需要关闭之前使用root用户配置文件的终端,并启动一个新终端。在命令行输入“mc”,使用导航器导航到“Doc??uments”,输入“uClinux”命令。按Ctrl+O并激活LinuxARMCortex-M开发部分,然后运行“.ACTIVATE.sh”命令。再次按Ctrl+O并转到“stm32f429-linux-builder-master”文件夹。用户现在有两种选择。如果使用VirtualBox中的示例项目,请遵循“makeclean”和“makeall”命令序列。要准备一个全新的环境,请使用“make”命令。大约30分钟后,新的μClinux映像将可用,如下所示:out\uboot\u-boot.binout\kernel\arch\arm\boot\xipuImage.binout\romfs.bin将这些新映像写入闪存。如果使用Windows和ST-LINK工具,以下代码将起作用:ST-LINK_CLI.exe-MEST-LINK_CLI.exe-P"u-boot.bin"0x08000000ST-LINK_CLI.exe-P"xipuImage.bin"0x08020000ST-LINK_CLI.exe-P"romfs.bin"0x08120000将串行调试器(串行控制台)连接到目标板(外部RX=>PC10,外部TX=>PC11,115200bits/s,8个数据位,无奇偶校验,1个停止位模式),然后按下复位键,μClinux工程就会开始运行。引导输出将显示在串行调试器上,Linux企鹅徽标将出现在显示屏上。第5步:创建“Hello,World”应用程序现在,按照下面的代码示例和说明将用户应用程序添加到μClinux项目。创建:“stm32f429-linux-builder-master/user/src/hello.c”文件:#includeintmain(){printf("Hello,world\n");return0;}Tab如有必要,创建:“stm32f429-linux-builder-master/user/Makefile”文件:CC=$(CROSS_COMPILE)gccLDFLAGS?=$(CFLAGS)target_out?=outall:checkdirs[Tab]$(CC)$(LDFLAGS)src/hello/hello.c-o$(target_out)/bin/hello$(LDLIBS)[Tab]-rm-rf$(target_out)/bin/*.gdbcheckdirs:[Tab]mkdir-p$(target_out)/binclean:[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)/.configuser_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)/usertarget_out_user:=$(target_out)/useruser_dir:=$(root_dir)/usertarget_out_user:=$(target_out)/user在目标MCU上构建后,下载并运行映像,您将在/usr/bin目录中找到此应用程序以及其他现有应用程序。可以通过在连接到探索板的终端上键入“hello[enter]”来测试应用程序。
