大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
信息
当前版本作者联系方式(长期有效):E-mail: WindForest@yeah.net
当前版本:2022-4-16-R1.0-预发布-问题意见征集
前言
本文拟基于 Hi3516DV300 介绍开发环境和最小系统搭建过程,以及一些不依赖于特定平台的通用嵌入式Linux开发技能和工具,因此学习将绕过芯片内相关资源的使用。如果你希望学习基于海思的音视频编解码,那更好的建议是在完成本文档的演练后,专注于海思SDK中提供的MPP例程,那里将成为你上手IPC(IP Camera,网络摄像机)开发的起点。
作为 “入门演练” ,我们将避过程序编写和内核调试等内容,仅通过对已有的工具进行编译、配置和测试来帮助你熟悉嵌入式设备的开发和调试过程。而后围绕该过程扩充其中如设备树、内核(Kernel)、构建系统(Build System)、常用工具和外设等知识节点。诚然,这么多内容放在一篇文档中,其叙述必将十分浅显,但是如此记录却能降低你们的学习门槛——至少不用花时间为了某个错误找遍论坛或者翻阅十几篇博客。
需要注意的是,本文档的内容具备时效性!这因你使用的工具或环境的版本更新而变化。即便你使用随本文提供的资源和软硬件,开发机中的各种依赖包却依然会不断升级迭代,如果它们不能提供很好的前向兼容(Forward Compatibility),那旧版本的程序将不能在新环境中工作。随时更新本文档可以避免这样的问题,提醒维护者不要忘记对每一版发布的文档指定正确且唯一的版本编号,这将为后续维护者提供文档是否应当被更新的参考。
阅读本文不需要你有太多的基础,否则就感觉不到新奇和兴奋了。但为了能理解我的叙述,你至少应该 了解 过Linux的基本使用、嵌入式的基本概念和大致内容,第1章中给出的几本书会帮助你构筑这方面的知识体系。至于本文的写作风格…我尽力把它写的好像是我在你身边亲自对你说话一样,也许这会使你印象深刻一些。另外,我虽然有心将本文写得全面,使你能够无障碍复现,但是内容中的众多细节,还是需要你亲自去查阅资料。
本入门文档 不包含 以下内容:
- 海思音视频编解码和软编解码(e.g. x264…)
- IPC相关协议(e.g. TCP/UDP/RTP/RTSP/RTMP/Onvif…)及相关推流框架(e.g. JRTPlib/Live555/ffmpeg…)
- 内核精简、驱动开发和系统优化
- 安全启动与固件加密
- 屏幕、触摸、GUI和嵌入式Qt
- 应用开发(e.g. 网络编程/多线程/多进程…)
- ……
勉励
我曾在其它文档中说过,现在要再说一遍:这世界上任何事情,一旦追求极致就根本不可能轻松。如果想要轻松,不学就是最轻松的了。
就算你身边没有混日子的人,你也总能听说一些——他们的热情消磨殆尽、惰于自己的舒适区;他们的追求仅限于欲望和金钱;他们的娱乐被限制在虚拟的游戏之内,刷着微博抖音看着剧,明明是自己的生命填充的却是他人的时间。也许我没有资格对别人的生活品头论足,只是,我希望你们能和“他们”有些许的不同。
1 开始之前
本章将介绍一些必备的技能和工具。
通常情况下,学习嵌入式需要先准备好一块硬件开发板,因为嵌入式方向必须实际上手操作才能真正学到东西,就好比捧着C语言教程不会让你入门编程,焊一焊洞洞板不会让你完美Layout一样,你读过了那么多的书,不上手做一做就无法积累经验。但在这一章,请你暂时按捺住购买的欲望,先对基础知识查缺补漏一番,如果没有本章所述的技能,在面对后续的操作和命令时你可能会无所适从。
1.1 操作系统与开发准备
计算机的基本操作和组成是现代化社会中作为电子类专业的学生必会的常识。Windows操作系统的使用和一些常用外设是必须要知道的,比如这里说几个名词:处理器/RAM/磁盘/通用串行总线/FAT32/路由/驱动程序……如果你认为这些名字不过是小儿科,那就意味着你已经达到了作为嵌入式开发者的入门级要求。
和单片机开发不同,海思的开发离不开Linux环境。因此在开始本文的演练之前,你需要多少学习一下Linux的基本操作。个人推荐的Linux发行版是Debain系的Ubuntu或Kubuntu,前者的桌面环境使用GNOME,后者则使用KDE,你可以根据喜好随意选择。一些老教程通常选择CentOS,这可能是一些历史原因造成的,但相信我,Ubuntu是一个更友好、漂亮又易于使用的发行版。你可以在虚拟机(e.g. VMWare Player)中安装Linux,并尝试在Linux中做你在Windows下做的那些事,经过一段时间的磨合后,你将对后续的操作得心应手。
如果你学习过单片机开发,那么应该对串口非常的熟悉了。嵌入式Linux开发板上都会提供一个调试串口,用于对接Linux的串口控制台(Console),因此对应地,开发机上应当准备一个虚拟终端软件以调试在开发板上的Linux系统(或内核)。我使用的虚拟终端软件是SecureCRT(V8.5.3),或者根据你的喜好,Xshell和MobaXterm也是不错的选择,至于正版和盗版…你懂的。而在Linux下,可以使用免费好用的minicom。开发板的调试串口通过USB转TTL小板连接到电脑上,电脑就能识别出一个串口设备了,在Windows下可通过查看设备管理器找到一个被分配有COMx的串口;在Linux下则会在/dev目录下生成诸如ttyUSBx的节点。
[关于USB转TTL]
市面上常见的USB转TTL小板使用的几种芯片如:CH340、PL2303、FT232和CP210x等,在使用之前记得安装对应的驱动。
嵌入式应用开发通常离不开网络编程,因此开发者还需要掌握一些网络知识,如基本的IPv4协议等,你可以在国家计算机等级考试三级(网络技术)和四级(网络工程师)中找到这些内容。除编程所需外,当开发板提供有线网络连接时,可以通过TFTP方式向开发板下载镜像或者挂载NFS文件系统,网络知识就显得更加不可或缺了。
最后,还要收拾一下心情。我能够理解一个人面对新征程时的兴奋感,也能够体会每一个小成功带来的喜悦之情,但开发者无论面临什么景况都应当保持内心镇静——无论是程序一次成功还是长久的调试无果。总要戒骄戒躁默默耕耘,怀着持久且谦虚的学习态度,是在这个行业上保持自己竞争力的唯一方法。
1.2 推荐的书籍
书是读不完的!关于入门的图书,我可以向你推荐一些,它们并不是全部,却实实在在能帮助你了解嵌入式世界。此外,如果你想向更深入的方向探索,就必须要主动去寻找那些知识了。
-
《嵌入式Linux基础教程》
本书向你介绍了通用嵌入式Linux开发的诸多细节,属于入门类的书籍,在速读阶段建议不求甚解。
-
《C Primer Plus(第6版)中文版》
该书能够完善你的C语言基础,嵌入式方向中,C语言或许不是最适合手头开发需求的,但绝对是必须要掌握的。如果你是完全的零基础,那并不建议使用这本书作为学习C语言的第一本书,因为它涉及的东西太全了。因此如果你没有时间通览全书,将它作为工具书摆在案头也是极好的。
-
《C陷阱与缺陷》
-
《C语言解惑》
-
《高质量嵌入式Linux C编程(第2版)》
该书可以作为嵌入式Linux学习的第一本书,读这本书时,不要过分考究前半部分的内容,如Makefile等,它们虽然必需,但不是最要紧的事情,后面有关Linux的编程部分才是首先需要掌握的东西。
-
《嵌入式Linux编程》(《Mastering Embedded Linux Programming》)
该书介绍了一个嵌入式产品的开发流程和嵌入式开发中经常使用到的构建系统的概念。这本书可以对开阔嵌入式视野、增加知识广度起到很大的帮助。
-
《Linux环境编程 从应用到内核》(《Programming in Linux Environment from Userspace to Kernel》)
在动手实操一些例子之后,这本书可以帮助你从内核的层面上理解应用编程的细节,比如读写锁、线程安全和信号安全等等。
-
《C++ Primer Plus中文版》
如果你的工作是应用方向,那么C++将是必需的。如果你还没有觉悟啃下这本书,那也许你还没准备好学习C++。但时代在发展,这本书也并不是万全的,随着C++标准不断更新,你应当即时跟进新的标准和技术。
-
《Linux设备驱动开发详解》
如果你的方向是底层驱动开发或者对内核的驱动子系统感兴趣,则宋宝华这本书是必读的。虽然Kernel已经迭代到5.x版本了,但4.x的内容仍然适用于目前大多开发需求。
-
《奔跑吧Linux内核》
这本书比较新,是基于Linux5.x版本的,如果你想成为内核工程师,那就读一读吧。
-
《UNIX环境高级编程》
上面的书籍都可以在学校的图书馆借到,如果时过境迁,有新的版本发售,那就去看最新的版本。如果可以的话,建议读书结合着工程和编码一起进行,这能够帮助你更好地理解它们。还有很多其它的优秀书籍,可我不想在这里罗列清单——文档的读者是新手,他们需要自己探索和发现并享受这个过程带来的成就感,因此他们不应该被无谓的建议束缚了手脚。
对了,我不是很推荐看视频,因为看视频的时间利用率实在是太低了。文字记录能方便读者根据自己的速度阅读,也方便索引和查找。如果视频能让你学到东西,那看书会让你学到更多。你应当谨慎地选择自己阅读的书籍,好像战士细心挑选自己的兵器一样。
1.3 书本之外
不要被所谓软件和硬件方向限制了视野。和IT/互联网不同,嵌入式领域的人必须对软硬件有交叉认知:硬件是如何依赖软件运行的,软件又如何使用硬件提供的功能。嵌入式是软件和硬件的结合体,因此越是接近底层开发,开发者就越是需要掌握硬件测试和原理图阅读等技能。
经常逛逛论坛或者在行业群里看看别人的闲聊内容很有好处,至少可以开阔你的视野。且论坛上并不是只有吹水的人,一些真正的大佬玩家和开源项目维护者大都活跃在论坛,如海思平台为主的 Ebaina(易佰纳)电子技术论坛 和全志平台为主的 Whycan社区 等。不过千万不要花太长时间在上面,我们毕竟是学业为重!
琳琅满目的市场就好像论坛一样,充斥着大量的开发板产品。在选择开发板时,你可能会注重配套资料和教程的多少,或者其开源社区建设,比如正点原子和野火这些大店铺的产品,以及韦东山、朱友鹏、稚辉君、飞凌、DOPI、各种水果派(树莓派、香橙派、荔枝派、蓝莓派、香蕉派、樱桃派…)的板子。这自然是没有问题的,但要记得:不要轻易搞收藏;选择要适合学习计划或职业规划;初期不要一味追求高性能的平台。
啰嗦了半天,可以开始了!本文并不局限于某个固定的开发板,你可以先试着做一做前面不需要开发板的部分内容,待熟练之后再尝试在自己的板子上做差异化学习。
2 最小系统环境的搭建流程
本章将以 Hi3516CV500R001C02SPC020 (提取码:6i6q)开发包为基准,讲述最基本的开发环境搭建步骤和Hi3516DV300所需的最小系统环境的构建过程。
本章内容无需开发板。
2.1 VMWare Workstation Player和Kubuntu
VMWare Workstation Player是一款免费好用的虚拟机软件;Kubuntu是一款Debain系的Linux发行版,本文档后续的叙述将基于它们进行。本文使用的VMWare Player版本为16,使用的Kubuntu版本为20.04.3 LTS。
2.1.1 创建虚拟机
打开VMWarePlayer,点击右侧【创建新虚拟机】,而后按照向导配置虚拟机。
选择我们下载好的Kubuntu20.04系统镜像,虚拟机自动识别到了OS信息。
设置机器名字、用户名和密码,建议简单一些,因为开发机可能经常用到root权限,密码太长是自找麻烦。
设置在VMWarePlayer中展示的虚拟机名字和存储位置。
磁盘不要太小,否则后期扩容是一件麻烦事。
这里我们不需要太多关注虚拟机设置,除非你的内存和CPU资源不足需要修改,否则全部保持默认即可,最后点击【完成】。
2.1.2 Kubuntu系统安装
系统启动后,将自动载入ISO镜像,并检查文件系统。
这里可以跳过,因为我们使用的是虚拟机,“磁盘”不会有什么问题。VMWarePlayer的简易安装非常便捷,我们几乎不需要手动操作,只管 耐心 等待。
[关于Dolphin]
Dolphin是Kubuntu的“资源管理器”,可以使用它浏览本机上存储的内容,默认打开位置为用户的Home目录,使用
Shift+F4
可在当前目录打开终端窗口;使用F4
可在当前目录调出内嵌的终端。
安装完成后,点击【徽标键】-【Konsole】打开终端,而后使用以下命令升级软件包:
sudo apt update
sudo apt upgrade
[为Ubuntu操作系统更换镜像源]
Apt默认使用的仓库源所在地为美国,因此访问速度可能比较缓慢,可以选择更换为国内镜像源以加快软件下载的速度。
在【Update】程序中的【Settings】界面,按照以下方式更换国内镜像源。
再执行
apt update
命令就能看到镜像源已经更换完成了。
至此,虚拟机和Linux系统环境已经准备完成。
[学习使用apt安装应用程序]
apt是Debain系OS的默认包管理程序,通过它可下载并管理发布在其仓库中的众多应用程序。以
lolcat
为例,使用以下命令进行安装:sudo apt install lolcat
而后在终端中执行该程序(如
man lolcat |lolcat
)查看效果:
2.2 搭建Hi3516DV300的开发环境
还记得本章伊始提及到的那一大长串名字的开发包吗?那里面包含了这款芯片从文档到例程的所有开发资料。你可能会问,我们不是要学习Hi3516DV300么,为什么开发包的名字是Hi3516CV500呢?因为它们同属一个系列,这几款芯片共用文档、例程和开发包,就这么简单。
文档部分请自己查阅,海思的文档相当细致,但这里我还是会亲手带你走一遍。
进入 Hi3516CV500R001C01SPC020 目录,同名压缩包就是我们接下来要用到的,下载并解压它,将其中的01.Software/ board/ Hi3516CV500_SDK_V2.0.2.0.tgz 拷贝到虚拟机中。SVP(Smart Vision Platform) 是海思媒体处理芯片智能视觉异构加速平台,该平台包含了CPU、DSP、NNIE等多个硬件处理单元和运行在这些硬件上SDK开发环境,本文暂时用不到,如果你需要在该平台部署深度学习模型或者部署异构算法,你才需要用到这个包中的内容。Toochain 是交叉编译工具链,是我们后面编译各种程序要用到的,下载并解压得到 arm-himix200-linux.tgz ,拷贝到虚拟机中。
解压这两个文件,可以通过右键文件-【Extract】-【Extract archive here, autodetect sobfolder】实现。
2.2.1 工具链安装与开发环境配置
进入 arm-himix200-linux 目录下,在当前窗口按 F4
调出终端,执行以下命令安装工具链:
sudo ./arm-himix200-linux.install
安装后重启虚拟机,在终端中输入 arm-himix200-linux-
并按下两次 tab
键,则会展示出安装的工具链。
而后安装开发环境所需的必要软件包:
sudo apt install vim make gcc g++ patch python net-tools swig u-boot-tools bison flex
sudo apt install python-dev libssl-dev libncurses-dev python3-dev python3-distutils
sudo apt install build-essential lib32z1 lib32stdc++6
完成之后,工具链就可以成功运行了。原压缩包和安装程序所在目录可以删除。
[关于32位兼容包]
当使用32位操作系统时,无需安装上面的 lib32z1 和 lib32stdc++6 包。
2.2.2 展开SDK
由于SDK脚本不支持dash,故首先在终端输入 sudo dpkg-reconfigure dash
并在弹出的窗口中通过方向键选择 no 并回车保存以禁用dash。
进入 Hi3516CV500_SDK_V2.0.2.0 目录下,在当前窗口按 F4
调出终端,执行以下命令展开SDK:
./sdk.unpack
SDK展开完成后的目录结构如图所示。
-
hi3516dv300_spi_smp_image_glibc
该目录中存放官方编译好的镜像文件可供直接验证所需,其中后缀名表示固件采用的文件系统格式。但我们的目标是自己编译制作镜像文件,故可以略过这个目录。
-
osdrv
该目录下存放着与嵌入式板端操作系统相关的程序和脚本,也是本章主要的工作目录。
-
package
该目录下存放 osdrv 和 smp 目录内容的原始压缩包。
-
smp
该目录下存放关于MPP和音视频编码例程相关的内容。不在本文档学习范围内。
SDK中提供的程序和资源要多留意查看,也许你暂时不会或用不到它们,但是理解和认识这些工具也是学习的一部分。况且既然官方提供了这些工具,那就说明它们对制作一个IPC固件而言确是必要的。
至此我们已经准备好基本资源和开发环境,可以真正上手制作Hi3516DV300的最小系统了。
2.3 U-Boot的编译
U-Boot是基于PowerPC,ARM,MIPS和其他几种处理器的嵌入式板的引导加载程序,可以安装在引导ROM中,用于初始化和测试硬件或下载运行应用程序代码。
[U-Boot名字和拼写]
根据U-Boot自述文件中的叙述,该项目的“正式”名称是“Das U-Boot”。所有书面文本(文档,源文件中的注释等)均应使用拼写“U-Boot”。例:
这是U-Boot项目的README文件。
文件名等应基于字符串“u-boot”。例:
include/asm-ppc/u-boot.h
#include <asm/u-boot.h>变量名称,预处理器常量等应基于字符串“u_boot”或基于“U_BOOT”。例:
U_BOOT_VERSION u_boot_logo
IH_OS_U_BOOT u_boot_hush_start使用正确的拼写是程序员的基本素质之一,且是对他人工作和项目的认可与尊重。
进入展开后SDK的 osdrv/opensource/uboot 目录下,解压 u-boot-2016.11.tgz ,随后在 u-boot-2016.11 目录下打开终端(可在该目录下按 Shift+F4
打开终端窗口,后文不再提示),并执行以下命令编译:
# 根据使用的存储器类型进行选择,Nor和Nand使用前者,eMMC使用后者
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- hi3516dv300_defconfig
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- hi3516dv300_emmc_defconfig
# 配置(可选)
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- menuconfig
# 编译
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- -j2
即可得到u-boot.bin文件。
[make和构建工具]
GCC是编译工具;make调用GCC,通过Makefile指定编译规则,属于构建工具;cmake可创建Makefile文件指导make构建过程,称为元构建工具。
进入 展开后的SDK根目录 下 依次 执行:
cd ./osdrv/tools/pc/uboot_tools
tar -zxf hiregbin-v5.0.1.tgz
cd hiregbin-v5.0.1
sudo chmod +x hiregbin
./hiregbin ../Hi3516DV300-DMEB_4L_FLYBY-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm ./reg.bin
cp reg.bin ../../../../opensource/uboot/u-boot-2016.11/.reg
cd ../../../../opensource/uboot/u-boot-2016.11
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- u-boot-z.bin
至此,我们得到了最终的u-boot镜像文件 u-boot-hi3516dv300.bin 。
[重要 – 关于hiregbin和DDR适配]
U-Boot的一项重要任务是初始化DDR控制器,为此,海思提供了hiregbin工具以从xlsm表格模板中生成配置文件。
Hi3516DV300-DMEB_4L_FLYBY-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm 文件从名字看适配的是 16bit*2/两颗2Gbit的DDR3内存颗粒。然而实际上该文件当前适配的是 16bit*2/两颗4Gbit的DDR3内存颗粒,即支持两片512MB共1GB的内存配置。开发者需自行确认该处设置与所用硬件保持一致。
更详细的内容可查看官方文档《Hi3516DV300 DDR3 参数配置方法》,此处不再赘述。
2.4 Kernel的编译
下载 linux-4.9.37.tar.gz,拷贝到展开后SDK的 osdrv/opensource/kernel 目录下,并在该目录下执行:
tar -zxf linux-4.9.37.tar.gz
mv linux-4.9.37 linux-4.9.y && cd linux-4.9.y
patch -p1 < ../linux-4.9.37.patch
执行以下命令编译:
# 根据使用的存储器类型进行选择,Nor和Nand使用前者,eMMC使用后者
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- hi3516dv300_smp_defconfig
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- hi3516dv300_emmc_smp_defconfig
# 配置(可选)
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- menuconfig
# 编译内核
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- uImage -j2
# 编译模块
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- modules
mkdir _modules_install
make ARCH=arm INSTALL_MOD_PATH=_modules_install modules_install
至此,在 arch/arm/boot/ 目录下得到内核镜像 uImage ;在 _modules_install 目录下得到编译出的内核驱动ko文件。
[关于 hi3516dv300_smp_defconfig 和 hi3516dv300_emmc_smp_defconfig 的区别]
使用文本对比工具(如Beyond Compare)可以方便地查看文件间的不同。为了满足你的好奇心,这里直接给出两配置文件的对比结果:相比于Nor/Nand版本,eMMC版配置文件关闭了对MTD的支持(即 CONFIG_MTD 未配置)、关闭了对Yaffs2和JFFS2文件系统的支持,以及缺少了对 CONFIG_ZLIB_DEFLATE=y 的配置,其余配置项均相同。
2.5 根文件系统制作
能够使Linux启动的最小根文件系统需要包含以下基本组件:
-
Shell外壳程序
Shell为用户使用Linux提供了便捷的操作接口。Busybox集成众多UNIX工具,且自带了一个轻量的shell实现,被广泛应用在嵌入式Linux环境下。Busybox的编译过程如下:
进入展开后SDK目录下的 ./osdrv/opensource/busybox 目录并解压busybox源码包,
cp ./config_v200_a7_softfp_neon ./.config
而后执行
make -j2
和make install
编译和安装二进制文件到指定目录。编译完成后的busybox相关程序即被复制到 ./_install 目录下待用。 -
基本目录结构
将展开后SDK目录下的 osdrv/rootfs_scripts/rootfs.tgz 解压(比如解压到Home目录下)。
将busybox目录下 _install 目录下的文件和目录拷贝到目标根文件系统目录下。
拷贝时选择【Write Into】。
而后按照下面的提示修改 /etc/inittab 文件第77行,否则后续开机挂载devtmpfs后启动脚本将无法找到ttyS000设备文件。
- ::respawn:/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..." + ::respawn:/sbin/getty -L ttyAMA0 115200 vt100 -n root -I "Auto login as root ..."
-
运行库
运行库由交叉编译工具链提供,用于提供应用程序运行期间所需的函数调用实体。如果交叉编译工具链(arm-himix200-linux-)安装在默认路径,则可在目标根文件系统目录下执行:
tar -xf /opt/hisi-linux/x86-arm/arm-himix200-linux/runtime_glibc/a7_softfp_neon-vfpv4/lib.tgz -C ./
运行库文件将拷贝到根文件系统目录下的 lib 目录中。
同理,将编译内核时得到的模块文件也拷贝到该目录下:
最后,可删除 mknod_console 和 mking.rootfs 脚本文件,它们对板端内核运行没有用处。至此,最小的根文件系统准备完成,可打包存档待用。
[关于mking.rootfs脚本]
你可能注意到了,在海思提供了rootfs模板中,和 mknod_console 脚本在一处的 mking.rootfs 脚本,从名字上也能够猜到,该脚本用于将rootfs打包成可供烧录的镜像文件。但我们可能面对各种各样的硬件,学习手动制作固件镜像是更加重要的,因此我们并不打算使用这个脚本。
3 存储器适配与烧录
本章分别以Nand Flash和eMMC存储器为示例,简略叙述如何进行分区规划、镜像文件制作和烧录。请读者根据自己实际需求和硬件配置选择各小节中的具体步骤进行操作。在进行烧录前也要确保编译内核时使用的是支持eMMC的配置文件。
特别地,考虑到Hi3516DV300的性能较为强大,且因支持NNIE常用于AI应用落地,因此绝大多数项目选型和开发板设计都不会选择容量较小的Nor Flash,故本章略过对Nor Flash的记录。
3.1 使用Nand Flash的情况
本节操作以 MT29F2G01ABA 256MB Nand Flash为例,使用实验室自研硬件开发板验证。
3.1.1 Nand存储器分区规划
Nand的空间通常数以MB计,因此根文件系统不宜过大,剩余空间应按需求划分为具体的分区视情况进行挂载。
这里使用的分区表如下表所示:
分区名称 | 镜像文件 | 起始地址 | 跨越长度 |
---|---|---|---|
fastboot | u-boot-hi3516dv300.bin | 0 | 1M |
kernel | uImage | 1M | 5M |
rootfs | rootfs_hi3516dv300.yaffs2 | 6M | 122M |
space | blank.yaffs2 | 128M | 128M |
这只是一个例子,你当然可以按照自己的设计更改上述分区表,但同时要记得修改后续对应的启动命令和相关配置。
3.1.2 文件系统打包(yaffs2)
下载 yaffs2utils-0.2.9.tar.gz ,并复制到展开后SDK目录下的 osdrv/tools/pc/yaffs2utils/ 目录下,按照readme.txt文件所示的步骤执行编译。将 bin/mkyaffs2image100 拷贝到 /usr/bin/ 目录下即可在全局使用它(即 sudo cp bin/mkyaffs2image100 /usr/bin/
命令)。
在 2.5 根文件系统制作 章节中,我们得到了一份可用的根文件系统目录,在该 rootfs 目录所在目录下使用以下命令将其打包为yaffs2格式的镜像:
mkyaffs2image100 rootfs rootfs_hi3516dv300.yaffs2 2k 8bit
其中,2k 表示使用的Nand的页大小为2K;8bit 为Nand的ECC长度。这些信息可以在器件的芯片手册中找到,如果内核支持该型号的Flash,也可能在内核相关驱动文件的注释或代码中找到。这样就得到了根文件系统镜像文件 rootfs_hi3516dv300.yaffs2 。
同样地,我们可以打包一个空目录,命令是相似的,这里不再给出,你可以自己尝试一下,最终生成一个名为 blank.yaffs2 的镜像文件。
3.1.3 使用有线网络烧录到Nand Flash的示例
这里我们还是使用 HiTool 工具进行镜像烧录,按照上述存储器规划表配置分区表,并确保下载参数是正确的,参考下图。
烧写的最佳实践是将fastboot分区和其余镜像的下载分开进行。对于fastboot分区,选择串口方式并冷启动硬件开始下载;对于其余镜像,在完成bootloader烧写后进行。需要注意:若手动对U-Boot进行了裁剪,禁用了对网络或相关命令的支持,则无法采用网口烧录方式进行下载。
下载前需确保开发板与PC端网络连接正常。如采用网线直连方式,需使用双绞线或连接双方有一方支持自动极性转换,IPv4地址建议使用链路本地地址即 169.254.0.0/16 ;如经过路由器连接,需确保分配给双方的IPv4地址的有效性,HiTool暂不支持IPv6。
若U-Boot支持、硬件工作正常且网络设置正确,点击【烧录】按钮后按软件提示重新为板端上电即可自动完成烧录过程,接下来设置内核启动参数和U-Boot启动命令。
3.1.4 内核启动参数和U-Boot命令配置
镜像文件下载完成后,还需设置U-Boot的 bootcmd 和 bootargs 命令以便正确启动到Linux Kernel。
启动时进入U-Boot命令行,依次执行以下指令设置 bootcmd 和 bootargs 环境变量并保存:
setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=yaffs2 mtdparts=hinand:1M(boot),5M(kernel),122M(rootfs),128M(space)'
setenv bootcmd 'nand read 0x80000000 0x100000 0x500000;bootm 0x80000000'
saveenv
在 bootargs 中,mem 为OS能够使用的内存大小,需根据实际内存大小和MMZ空间设置综合考虑(MMZ是MPP所需内存空间);console 为串口控制台参数设置;root 指定启动分区;rootfstype 指定启动分区类型;mtdparts 为传入的分区表。
bootcmd 被设置用于拷贝内核到内存并移交控制权,其中,nand read
命令从Nand中1M的位置读取5M的数据到内存0x80000000的位置上,并从该内存位置启动。
[关于DDR起始地址]
不同的芯片拥有不同的地址空间映射,对于Hi3516CV500系列而言,DDR起始地址为0x80000000。
该信息可在《Hi3516CV500╱Hi3516DV300╱Hi3516AV300 开发环境用户指南》文档中找到。
设置完成后在U-Boot命令行执行 reset
或 run bootcmd
或重新启动硬件即可启动到系统。
3.2 使用eMMC的情况
本节操作以 KLM8G1GETF 8GB eMMC为例,使用荣品 RP-DV300 开发板验证。
3.2.1 eMMC存储器分区规划
eMMC的空间通常数以GB计,因此根文件系统不宜过大,剩余空间应按需求划分为具体的分区视情况进行挂载。
这里使用的分区表如下表所示:
分区名称 | 镜像文件 | 起始地址 | 跨越长度 |
---|---|---|---|
fastboot | u-boot-hi3516dv300.bin | 0 | 1M |
kernel | uImage | 1M | 5M |
rootfs | rootfs_hi3516dv300.ext4 | 6M | 122M |
space | blank.ext4 | 128M | 7328M |
这只是一个例子,你当然可以按照自己的设计更改上述分区表,但同时要记得修改后续对应的启动命令和相关配置。
[关于eMMC容量]
有必要说明的是,8GB的eMMC,用户可使用的空间仅有7456M。如果按照8192M划分空间并制作镜像,则space空间将有8064M,但在挂载该分区时会提示超出设备容量:
据此提示进行计算即可推算实际可用空间大小。
参见器件手册中的用户密度说明:
7456/8192=91.015625%,符合手册中的描述。
3.2.2 文件系统打包(ext4)
首先编译镜像打包工具 make_ext4fs ,进入展开后SDK目录下的 osdrv/tools/pc/ext4_utils/ 目录下执行 make
命令即可。将 bin/make_ext4fs 拷贝到 /usr/bin/ 目录下即可在全局使用它(即 sudo cp bin/make_ext4fs /usr/bin/
命令)。
在 2.5 根文件系统制作 章节中,我们得到了一份可用的根文件系统目录,在该 rootfs 目录所在目录下使用以下命令将其打包为ext4格式的镜像:
make_ext4fs -l 122M -s rootfs_hi3516dv300.ext4 rootfs
其中, -l 选项指定了该分区的大小;-s 选项可用于指示尺寸缩减,当目录大小小于分区大小时,不填充镜像到分区大小。这样就得到了根文件系统镜像文件 rootfs_hi3516dv300.ext4 。
同样地,我们可以打包一个空目录,命令是相似的,这里不再给出,你可以自己尝试一下,最终生成一个名为 blank.ext4 的镜像文件。
3.2.3 使用USB烧录到eMMC的示例
这里我们还是使用 HiTool 工具进行镜像烧录,按照上述存储器规划表配置分区表,并确保所选芯片和下载参数是正确的,参考下图。
烧写的最佳实践是将fastboot分区和其余镜像的下载分开进行。对于fastboot分区,选择串口方式并冷启动硬件开始下载;对于其余镜像,按照下列步骤的指示。需要注意:若手动对U-Boot进行了裁剪,禁用了对USB或相关命令的支持,则无法采用USB烧录方式进行下载。
-
首先下载fastboot并为硬件上电,烧写完成后2秒内按下任意键进入U-Boot命令行;
-
输入并执行
usb device
命令,而后将板端USB连接到PC; -
此时PC的设备管理器中应显示出 HiUSBBurn 设备,否则请检查驱动;
-
勾选HiTool工具中除fastbool外的其它分区,点击【烧写】;
-
当HiTool出现以下提示时,不要断开开发板电源,重新插拔USB线,下载将正式开始直至完成。
此时镜像内容已经存在于存储器,接下来设置内核启动参数和U-Boot启动命令。
3.2.4 内核启动参数和U-Boot命令配置
镜像文件下载完成后,还需设置U-Boot的 bootcmd 和 bootargs 命令以便正确启动到Linux Kernel。
启动时进入U-Boot命令行,依次执行以下指令设置 bootcmd 和 bootargs 环境变量并保存:
setenv bootargs 'mem=512M console=ttyAMA0,115200 root=/dev/mmcblk0p3 rootfstype=ext4 rw rootwait blkdevparts=mmcblk0:1M(boot),5M(kernel),122M(rootfs),-(space)'
setenv bootcmd 'mmc read 0 0x80000000 0x800 0x2800;bootm 0x80000000'
saveenv
在 bootargs 中,mem 为OS能够使用的内存大小,需根据实际内存大小和MMZ空间设置综合考虑(MMZ是MPP所需内存空间);console 为串口控制台参数设置;root 指定启动分区;rootfstype 指定启动分区类型;rw 表示启动分区可读写;rootwait 用于等待eMMC初始化完成后再挂载分区;blkdevparts 为传入的分区表。
bootcmd 被设置用于拷贝内核到内存并移交控制权,其中,mmc read
命令从设备号为0的eMMC中0x800×512(块大小)的位置读取0x2800×512(块大小)的数据到内存0x80000000的位置上,并从该内存位置启动。
[关于DDR起始地址]
不同的芯片拥有不同的地址空间映射,对于Hi3516CV500系列而言,DDR起始地址为0x80000000。
该信息可在《Hi3516CV500╱Hi3516DV300╱Hi3516AV300 开发环境用户指南》文档中找到。
设置完成后在U-Boot命令行执行 reset
或 run bootcmd
或重新启动硬件即可启动到系统。
4 常用软件编译方法
本章介绍了一些常用的工具和软件的编译和典型使用方法,你可以根据需要选择性阅读。常用的当然不只这些,它们只是一个开始。
4.1 wpa_supplicant
wpa_supplicant可用于连接无线Wi-Fi热点。
wpa_supplicant的编译过程和使用示例参见:《wpa_supplicant2.9编译过程》。
4.2 hostapd
hostapd可用于建立无线Wi-Fi热点。
hostapd的编译过程和使用示例,以及udhcpd、udhcpc和iw工具的简要介绍参见:《hostapd2.9编译过程》。
4.3 iperf3
iperf-3.1.3下载地址:https://iperf.fr/iperf-download.php#source
首先搜索 ./src/Makefile.in 文件,删除 -pg 选项。然后在源码目录下使用以下命令进行静态编译:
mkdir _install
./configure --host=arm-himix200-linux --prefix=$(pwd)/_install CFLAGS=-static CXXFLAGS=-static
make
make install
将编译后的程序复制到根文件系统对应目录中即完成安装。在待测试网络链路两端的机器上分别使用以下命令启动测试:
#服务端
iperf3 -s
#客户端
iperf3 -c [服务端IP地址] -t [持续时间(秒)]
#e.g.
iperf3 -c 192.168.1.103 -t 10
#若不使用-t参数,则测试10轮后自动停止
4.4 gdb
GDB可用于调试在板端运行的程序,SDK中提供了GDB的编译方法,见 osdrv/tools/board/gdb/readme.txt 。
下载 ncurses-6.0.tar.gz 和 gdb-7.9.1.tar.gz ,拷贝到gdb目录,执行命令以编译:
tar -xzf gdb-7.9.1.tar.gz && cd gdb-7.9.1
patch -p1 < ../hi-gdb-7.9.1.patch && cd ../
make all
将编译后的程序复制到根文件系统对应目录中即完成安装。使用gdb调试应用程序的方法可查阅网上相关资料。
4.5 lrzsz
lrzsz可用于开发板和PC间通过串口传输文件,当无网络配置时,可使用此工具向开发板中拷贝文件,以节省重新制作和烧录镜像文件的时间。lrzsz:https://ohse.de/uwe/software/lrzsz.html
mkdir _install
./configure CC=arm-himix200-linux-gcc --cache-file=./arm-linux.cache --prefix=$PWD/_install --host=arm-himix200-linux --build=arm-himix200-linux
make CC=arm-himix200-linux-gcc
make install
将编译后的程序复制到根文件系统对应目录中即完成安装。使用时可在板端执行:
lrz
以启动Zmodem传输,传输的文件将保存在当前目录下。在SecureCRT终端软件下进行Zmodem传输的过程如下图所示。
4.6 himm和devmem
himm是海思提供的寄存器操作工具,隶属海思 reg-tools 工具集;devmem是busybox提供的寄存器操作工具。使用它们可以在Shell环境下读写指定寄存器的值。
himm的编译很简单,进入展开后SDK目录下的 osdrv/tools/board/reg-tools-1.0.0/ 目录下,执行 make
编译即可。将编译完后的文件拷贝到板端 /bin/ 或**/usr/bin/** 目录下即可在全局调用它。
使用示例:为UART1的TxD和RxD设置引脚复用。
# 使用himm的方式
himm 0x111F0008 32 0x501
himm 0x111F000C 32 0x501
# 使用devmem的方式
devmem 0x111F0008 32 0x501
devmem 0x111F000C 32 0x501
可见,两者的使用差异并非很大,其实现也均使用到了 mmap 系统调用。
[关于引脚复用]
引脚复用指的是同一个外设引脚可以兼具多种功能,但同一时刻只能设置为一种的特性。以UART_TxD为例,该引脚的默认设置为GPIO5_3。关于引脚复用信息可查看《Hi3516DV300_PINOUT_CN》表格。
4.7 ntpdate
ntpdate和htpdate可用于获取网络时间并同步本机时间。在IPC应用中,画面上通常会打上时间信息,该时间信息可在系统联网成功后通过时间工具自动获取和设置。
首先下载 ntp-4.2.8p15.tar.gz 并拷贝到虚拟机并解压,执行以下命令编译:
mkdir _install
./configure CFLAGS="-O2 -g -fPIC" --prefix=/home/wind/ntp-4.2.8p15/_install --host=arm-himix200-linux --with-yielding-select=yes
make
make install
其中 –prefix 后面必须使用绝对路径,你需要手动替换为你所使用的路径。命令执行完成后即可在 _install 目录下得到交叉编译的ntpdate,将编译后的程序复制到根文件系统对应目录中即完成安装。
关于ntpdate的使用,可参考如 这个网站 等网络资料,此处不再赘述。
哦对了,busybox中已经自带了精简版的 ntpd
工具,一般可以满足基本的时间同步需求,不妨试一试。此外,htpdate工具使用http流量获取时间信息,可在NTP流量被限制等情况下作为替代工具使用,ntpd、ntpdate和htpdate的区别可查阅网上相关资料。
———— 2022-4-16@燕卫博 ————
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/190124.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...