嵌入式开发:修订间差异

来自Ubuntu中文
跳到导航跳到搜索
Nsynet留言 | 贡献
Nsynet留言 | 贡献
无编辑摘要
第1行: 第1行:
=前言=
= 基于NXP IMX6ULL芯片的开发板 =
嵌入式系统是一个很广泛的话题,本页面不会就技术细节深入探讨,只希望从一个大的角度给嵌入系统一个分支表,也希望对各方面有兴趣的朋友加入,丰富这里的内容。
==百问网100ask IMX6ULL开发板 ==
=常用嵌入式核心板的对比==
==== 在windows +虚拟机环境下开发(参考《第四 A 章 使用 USB 网卡直连配置网络》) ====
  目前市场很多核心板/半成品板可以用来编程,当时各种性能不同,值得对比和选项。
[[嵌入式开发_非linux核心板|嵌入式开发_非linux核心板]]


//启动方式如下: [[File:vertopal_d4a9bdf9044e4bffbe844f8299b82f2d/5de0c48088dd28e2a943b947f86f3f2039e5847f.png|image]]


[[嵌入式开发_linux核心板|嵌入式开发_linux核心板]]
注意:这个拨码仅仅是uboot的启动,而uboot有可能启动的是sd卡(mmc=0),也考虑启动的是emmc(mmc=1),可以在uboot的环境变量中配置:


=嵌入式系统分类=
<pre>
==8bit系统==
=&gt; printenv
===51系列单片机===
baudrate=115200
51单片机是对目前所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8031单片机,后来随着Flash rom技术的发展,8031单片机取得了长足的进展,成为目前应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。目前很多公司都有51系列的兼容机型推出,在目前乃至今后很长的一段时间内将占有大量市场
board_name=EVK
board_rev=14X14
boot_fdt=try
......
......
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1      //原始是mmc=1即emmc启动
mmcpart=2
mmcroot=/dev/mmcblk1p2 rootwait rw      //原始是mmc=1即emmc启动
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
......
......


===AVR系列单片机===
Environment size: 2738/8188 bytes
AVR 单片机是1997年由ATMEL公司研发出的增强型内置Flash的RISC(Reduced Instruction Set CPU) 精简指令集高速8位单片机。AVR的单片机可以广泛应用于计算机外部设备、工业实时控制、仪器仪表、通讯设备、家用电器等各个领域。
=&gt; setenv mmcdev 0      //改为mmc=0即sd卡启动
=&gt; setenv mmcroot/dev/mmcblk0p2 rootwait rw      //改为mmc=0即sd卡启动
=&gt; saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
=&gt;</pre>
从开机log可以看到到底是mmc=0即sd卡启动:


  AVR的主要特性
<pre>U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)


  高可靠性、功能强、高速度、低功耗和低价位 , 一直是衡量单片机性能的重要指标,也是单片机占领市场、赖以生存的必要条件。
CPU:  Freescale i.MX6ULL rev1.1 696 MHz (running at 396 MHz)
CPU:  Industrial temperature grade (-40C to 105C) at 39C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:  FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT7016 (1024x600)
Video: 1024x600x24
In:    serial
Out:  serial
Err:  serial
Net:  No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0
## Error: &quot;findtee&quot; not defined
switch to partitions #0, OK
mmc0 is current device                    &lt;&lt;&lt;&lt;&lt;&lt;&lt;
switch to partitions #0, OK
mmc0 is current device                    &lt;&lt;&lt;&lt;&lt;&lt;&lt;
</pre>
还是mmc=1即emmc启动:


  早期单片机主要由于工艺及设计水平不高、功耗高和抗干扰性能差等原因,所以采取稳妥方案:即采用较高的分频系数对时钟分频,使得指令周期长,执行速度慢。以后的 CMOS单片机虽然采用提高时钟频率和缩小分频系数等措施,但这种状态并未被彻底改观(51以及51兼容)。此间虽有某些精简指令集单片机(RISC)问世,但依然沿袭对时钟分频的作法。
<pre>U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)


  AVR单片机的推出,彻底打破这种旧设计格局,废除了机器周期,抛弃复杂指令计算机 (CISC)追求指令完备的做法;采用精简指令集,以字作为指令长度单位,将内容丰富的操作数与操作码安排在一字之中(指令集中占大多数的单周期指令都是如此),取指周期短,又可预取指令,实现流水作业,故可高速执行指令。当然这种速度上的升跃,是以高可靠性为其后盾的。
CPU:  Freescale i.MX6ULL rev1.1 696 MHz (running at 396 MHz)
CPU:  Industrial temperature grade (-40C to 105C) at 42C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:  FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT7016 (1024x600)
Video: 1024x600x24
In:    serial
Out:  serial
Err:  serial
Net:  No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0
## Error: &quot;findtee&quot; not defined
switch to partitions #0, OK
mmc1(part 0) is current device                    &lt;&lt;&lt;&lt;&lt;&lt;&lt;
switch to partitions #0, OK
mmc1(part 0) is current device                    &lt;&lt;&lt;&lt;&lt;&lt;&lt;
</pre>
//调试环境如下: [[File:vertopal_d4a9bdf9044e4bffbe844f8299b82f2d/0e162767e613040b5356a8442a70011a041716d8.png|image]]


  AVR单片机硬件结构采取8位机与16位机的折中策略,即采用局部寄存器存堆(32个寄存器文件)和单体高速输入/输出的方案(即输入捕获寄存器、输出比较匹配寄存器及相应控制逻辑)。提高了指令执行速度(1Mips/MHz),克服了瓶颈现象,增强了功能;同时又减少了对外设管理的开销,相对简化了硬件结构,降低了成本。故AVR单片机在软/硬件开销、速度、性能和成本诸多方面取得了优化平衡,是高性价比的单片机。
虚拟机的配置类似如下: [[File:vertopal_d4a9bdf9044e4bffbe844f8299b82f2d/b589a98b40c7bce7fd7f389403a7327f36360011.png|image]]


  AVR单片机内嵌高质量的Flash程序存储器,擦写方便,支持ISP和IAP,便于产品的调试、开发、生产、更新。内嵌长寿命的EEProm可长期保存关键数据,避免断电丢失。片内大容量的RAM不仅能满足一般场合的使用,同时也更有效的支持使用高级语言开发系统程序,并可像MCS-51单片机那样扩展外部 RAM。
vscode使用ssh remote插件远程登陆vmware的代码:


  AVR单片机的I/O线全部带可设置的上拉电阻、可单独设定为输入/输出、可设定(初始)高阻输入、驱动能力强(可省去功率驱动器件)等特性,使的得I/O口资源灵活、功能强大、可充分利用。
<img src="https://img2022.cnblogs.com/blog/1974711/202210/1974711-20221009232455525-267471114.png" width="40%">


  AVR单片机片内具备多种独立的时钟分频器,分别供URAT、I2C、SPI使用。其中与 8/16位定时器配合的具有多达10 位的预分频器,可通过软件设定分频系数提供多种档次的定时时间。AVR单片机独有的“以定时器/计数器(单)双向计数形成三角波,再与输出比较匹配寄存器配合,生成占空比可变、频率可变、相位可变方波的设计方法(即脉宽调制输出PWM)”更是令人耳目一新。
效果图:


  增强性的高速同/异步串口,具有硬件产生校验码、硬件检测和校验侦错、两级接收缓冲、波特率自动调整定位(接收时)、屏蔽数据帧等功能,提高了通信的可靠性,方便程序编写,更便于组成分布式网络和实现多机通信系统的复杂应用,串口功能大大超过 MCS-51/96单片机的串口,加之AVR单片机高速,中断服务时间短,故可实现高波特率通讯。
<img src="https://img2022.cnblogs.com/blog/1974711/202210/1974711-20221009232532859-1841111653.png" width="40%">


  面向字节的高速硬件串行接口TWI、SPI。TWI与I2C接口兼容,具备ACK信号硬件发送与识别、地址识别、总线仲裁等功能,能实现主/从机的收/发全部4种组合的多机通信。SPI支持主/从机等4种组合的多机通信。
//开发板配置: ifconfig eth0 192.168.5.9 为了避免每次开机配置,可以: 设置 IP 为固定静态 IP(开机不变) 设置 eth0 为静态 IP 地址, 开发板/etc/network/目录下对 interfaces 文件进行修改 。 <code>[root@100ask:~]# vi /etc/network/interfaces</code> 修改并为如下内容,执行 :wq 保存并退出,执行/etc/init.d/S40network restart 重启网络服务。


  AVR单片机有自动上电复位电路、独立的看门狗电路、低电压检测电路BOD,多个复位源(自动上下电复位、外部复位、看门狗复位、BOD复位),可设置的启动后延时运行程序,增强了嵌入式系统的可靠性。
<pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
    address 192.168.5.9
    netmask 255.255.255.0
    gateway 192.168.5.1</pre>
《4.4.1 文件系统内使用 nfs 挂载 ubuntu 目录》


  AVR单片机具有多种省电休眠模式,且可宽电压运行(5-1.8V),抗干扰能力强,可降低一般8位机中的软件抗干扰设计工作量和硬件的使用量。
<pre>[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt</pre>
<span id="在windows-虚拟机环境下开发参考第四-b-章-使用路由器配置网络"></span>
==== 在windows +虚拟机环境下开发(参考《第四 B 章 使用路由器配置网络》) ====


  AVR单片机技术体现了单片机集多种器件(包括FLASH程序存储器、看门狗、EEPROM、同/异步串行口、TWI、SPI、A/D模数转换器、定时器/计数器等)和多种功能(增强可靠性的复位系统、降低功耗抗干扰的休眠模式、品种多门类全的中断系统、具输入捕获和比较匹配输出等多样化功能的定时器/计数器、具替换功能的I/O端口…… )于一身,充分体现了单片机技术的从“片自为战”向“片上系统SoC”过渡的发展方向。
1.windows PC的wifi和路由器连接,比如获得IP是192.168.3.240.虚拟机使用“桥接模式-直接连接物理网络”,比如获得IP是192.168.3.10 2.开发板启动wifi,可以直接执行如下start_wifi.sh的shell脚本:


  综上所述,AVR单片机博采众长,又具独特技术,不愧为8位机中的佼佼者。
<pre>#!/bin/bash
#启用 wlan0 无线网络设备
ifconfig wlan0 up
#扫描周围网络设备
#iw dev wlan0 scan |grep SSID
#配置网络连接参数
rm -rf /etc/wpa_supplicant.conf
wpa_passphrase weiba1985 19560206 &gt;&gt; /etc/wpa_supplicant.conf
#连接 wifi 设备
wpa_supplicant -B -iwlan0 -c /etc/wpa_supplicant.conf
#查看连接状态
iw wlan0 link
#为 wlan0 获取 ip 地址,确认与PC可以相互ping通
udhcpc -i wlan0
#查看所有网络设备
ifconfig -a</pre>
比如获得路由器分配的IP是192.168.3.6 3.用mobaxterm可以分别ssh连接到虚拟机和开发板的终端,在开发板的终端把虚拟机的文件系统加入mnt: <code>mount -t nfs -o nolock,vers=3 192.168.3.10:/home/book/nfs_rootfs /mnt</code>


  总结,与其它8-bit MCU相比,AVR 8-bit MCU最大的特点是:
== 代码编译 ==


  ● 哈佛结构,具备1MIPS / MHz的高速运行处理能力;
=== 代码下载 ===


  ● 超功能精简指令集(RISC),具有32个通用工作寄存器,克服了如8051 MCU采用单一ACC进行处理造成的瓶颈现象;
执行以下4条命令,为方便大家复制,第3条是很长的命令,使用了,需要一并拷贝:


  ● 快速的存取寄存器组、单周期指令系统,大大优化了目标代码的大小、执行效率,部分型号FLASH非常大,特别适用于使用高级语言进行开发;
<pre>book@100ask:~ git clone https://e.coding.net/codebug8/repo.git
book@100ask:~$ mkdir -p 100ask_imx6ull-sdk &amp;&amp; cd 100ask_imx6ull-sdk
book@100ask:~/100ask_imx6ull-sdk$ ../repo/repo init -u \
https://gitee.com/weidongshan/manifests.git -b \
linux-sdk -m imx6ull/100ask_imx6ull_linux4.9.88_release.xml  --no-repo-verify
book@100ask:~/100ask_imx6ull-sdk$  ../repo/repo sync -j4</pre>
在 ~/.bashrc 的行尾添加如下:


  ● 作输出时与PIC的HI/LOW相同,可输出40mA(单一输出),作输入时可设置为三态高阻抗输入或带上拉电阻输入,具备10mA-20mA灌电流的能力;
<pre>export ARCH=arm
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export  PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin</pre>
设置完毕后,要执行 source ~/.bashrc 命令使其生效,


  ● 片内集成多种频率的RC振荡器、上电自动复位、看门狗、启动延时等功能,外围电路更加简单,系统更加稳定可靠;
=== 应用程序的编译和执行 ===


  ● 大部分AVR片上资源丰富:带E2PROM,PWM,RTC,SPI,UART,TWI,ISP,AD,Analog Comparator,WDT等;
我们要想给 ARM 板编译出 hello 程序,需要使用交叉编译工具链,比如:


  ● 大部分AVR除了有ISP功能外,还有IAP功能,方便升级或销毁应用程序
<pre>$ arm-buildroot-linux-gnueabihf-gcc -o hello hello.c</pre>
这样编译出来的 hello 程序才可以在 ARM 板子上运行。 先把编译生成的 hello 文件拷贝到 Ubuntu nfs 服务目录下,备用:


  AVR系列单片机的选型
<pre>$ cp  hello  /home/book/nfs_rootfs</pre>
<span id="调试开发板方法1使用nfs方式"></span>
=== 调试开发板方法1:使用nfs方式 ===


  AVR单片机系列齐全,可适用于各种不同场合的要求。AVR单片机有3个档次:
这种方式一般不自己从头开始编译busybox,只用于调试uboot+linux kernel+dts,文件系统即busybox不需要调整的场景。 #### uboot


  低档Tiny系列AVR单片机: 主要有Tiny11/12/13/15/26/28等;
<pre>u-boot的编译过程如下(编译uboot前必须先配置好工具链等开发环境):
book@100ask: ~/100ask_imx6ull-sdk$ cd Uboot-2017.03
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make distclean
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make  mx6ull_14x14_evk_defconfig
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make</pre>
编译后检查是否生效,需要看看开机时间戳是否改变了,如下:


  中档AT90S系列AVR 单片机: 主要有AT90S1200/2313/8515/8535等; (正在淘汰或转型到Mega中)
<pre>U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)</pre>
<span id="linux内核dts"></span>
==== LINUX内核+dts ====


  高档ATmega系列AVR单片机: 主要有ATmega8/16/32/64/128( 存储容量为8/16/32/64/128 KB)以及ATmega8515/8535等。
为了防止编译没有生效,除了留意打印的编译时间戳,还可以修改一些标记处,烧入单板时检查标记是否生效了,比如kernel顶层Makefile的:


  AVR也是自动电压调节器的缩写
<pre>VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 88
EXTRAVERSION = 20221029_by_nishengyue        &lt;------  增加标记</pre>
烧入单板后应该有类似的打印,说明编译真正生效了:


==16bit系统==
<pre>[  0.000000] Booting Linux on physical CPU 0x0
16位单片机目前市场上常见的有MSP430和PIC
[  0.000000] Linux version 4.9.8820221029_by_nishengyue (book@100ask) (gcc version 7.5.0 (Buildroot 2020.02-gee85cab) ) #1 SMP PREEMPT Sun Oct 30 11:46:38 CST 2022</pre>
在 <code>~/100ask_imx6ull-sdk/Linux-4.9.88</code> 路径下,kernel的编译过程如下(编译内核前需要先配置好工具链等一些环境变量):


==32bit系统==
<pre>make mrproper
===ARM架构系统===
make 100ask_imx6ull_defconfig
'''粗体文字'''
make zImage  -j4
make dtbs V=1
cp arch/arm/boot/zImage ~/nfs_rootfs
cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb  ~/nfs_rootfs</pre>
如果出现 multiple definition of `yylloc` 报错,请参考该链接解决:https://blog.csdn.net/qq_36393978/article/details/117695708


===MIPS、龙芯架构系统===
这样在nfs_rootfs 能看到zImage和100ask_imx6ull-14x14.dtb 文件。


=嵌入式操作系统=
<span id="编译内核module"></span>
==== 编译内核MODULE ====


==常见的开源嵌入式非linux RTOS==
<pre>book@b ook-virtual-machine:~$ cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
===Nut/OS===
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-
====相关介绍====
gnueabihf- modules</pre>
官方网站 http://www.ethernut.de,Nut/OS 作为 德国的Ethernut Project的软件部分,是一个为嵌入式平台设计的模块化开源实时操作系统,它易于配置与优化来运行于8位AVR与32位ARM微控制器上。
安装内核module执行以下命令:


因为使用了模块化的结构,操作系统只会包含那些应用程序真正需要的部件,对目标系统的变化会自动适应。为了易于调整,还发布了Linux,Windows于 OS X 下的图形化用户配置界面,这一点有点类似ecos,但该操作系统要比ecos轻量化。
<pre>book@book-virtual-machine:~$ cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$  sudo  make    ARCH=arm  INSTALL_MOD_PATH=/home/book/nfs_rootfs/ modules_install</pre>
这样在 nfs_rootfs 能看到 lib 文件夹。


Nut/OS 的多线程使用起来安全并且容易。其协作式线程调度机制使得线程只在明确界定的时间点上让出处理器。在大多数情况下访问共享资源不需要任何锁机制。如此可以使得应用代码更小并且简单,同时较大地减少竞争与死锁的风险。
<span id="安装编译的内核设备树module"></span>
==== 安装编译的内核+设备树+module ====


确定性的中断延迟可以在严格的期限内提供硬实时响应,而跟系统现有的可用资源无关。
执行命令拷贝:


===eCos===
<pre>cp  /mnt/zImage  /boot
====相关介绍====
cp  /mnt/*.dtb  /boot
中文维基百科的“ecos"词条    http://zh.wikipedia.org/w/index.php?title=ECOS&variant=zh-cn
cp  /mnt/lib/modules  /lib  -rfd</pre>
==== uboot从nfs网络启动 ====


====安装步骤====
1.编译的结果拷贝到nfs目录下:
参考ecos网站的Downloading and Installation ( http://ecos.sourceware.org/getstart.html ),在terminal中敲入命令就可以安装好toolchain


===FreeRTOS===
<pre>book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp zImage  ~/nfs_rootfs/
英文维基百科的“freertos"词条  http://en.wikipedia.org/wiki/FreeRTOS
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp 100ask_imx6ull-14x14.dtb  ~/nfs_rootfs/
从Freertos的官方网站可以下载到其移植到很多平台的demo,但这个操作系统还是显得很简单,其内核只有三个文件(tasks.c, queue.c 和 list.c,如果使用联合程序则会加上croutine.c),有些功能如task间发消息机制没有实现,因此建议操作系统选型时注意。
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp -rf  rootfs.tar.bz2  ~/nfs_rootfs/
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cd ~/nfs_rootfs
book@100ask:~/nfs_rootfs$ sudo tar  xjf  rootfs.tar.bz2</pre>
2.ubuntu开启tftp: 在 Ubuntu 中执行以下命令安装 TFTP 服务:


===RTEMS===
<pre>sudo apt-get install tftp-hpa tftpd-hpa </pre>
====相关介绍====
然后,创建 TFTP 服务器工作目录,并打开 TFTP 服务配置文件,如下:
中文维基百科的“RTEMS"词条    http://zh.wikipedia.org/w/index.php?title=RTEMS&variant=zh-cn
英文维基百科的“RTEMS"词条    http://en.wikipedia.org/wiki/RTEMS


==常见的开源嵌入式linux RTOS==
<pre>sudo vim /etc/default/tftpd-hpa </pre>
英文维基百科的“Embedded Linux"词条    http://en.wikipedia.org/wiki/Embedded_Linux
在配置文件/etc/default/tftpd-hpa 中,添加以下字段:
===μClinux===
====相关介绍====
英文维基百科的“μClinux"词条        http://en.wikipedia.org/wiki/%CE%9CClinux


<pre>TFTP_DIRECTORY=&quot;/home/book/nfs_rootfs&quot;
TFTP_OPTIONS=&quot;-l  -c  -s&quot; </pre>
最后,重启 TFTP 服务:


<pre>sudo service tftpd-hpa restart </pre>
查看 tftp 服务是否在运行,运行如下命令,即可查看是否在后台运行。


==常见的商业嵌入式RTOS==
<pre>ps -aux | grep &quot;tftp&quot;</pre>
===μC/OS===
3.ubooot阶段启动停住后,输入如下:


一个开源但商业并不免费的RTOS,作为学习还是挺不错的,资料很多。μC/OS-II目前用的较多的一个版本,最新版本为μC/OS-III。详细介绍可登录wiki或上其官网做更多了解。
<pre>=&gt; setenv serverip 192.168.5.11    //设置服务器的 IP 地址,这里指的是 Ubuntu 主机 IP
=&gt; setenv ipaddr 192.168.5.9        //设置开发板的 IP 地址。
=&gt; ping 192.168.5.11    //检查是否能ping通
=&gt; setenv nfsroot /home/book/nfs_rootfs  //设置 nfs 文件系统所在目录。
=&gt; run netboot            //设置完成后,运行网络启动系统命令 </pre>
<span id="调试开发板方法2使用编译buildroot套件并烧录进单板"></span>
=== 调试开发板方法2:使用编译buildroot套件并烧录进单板 ===


===Nucleus OS===
这种方式一般可以一次性编译uboot+linux kernel+dts+文件系统busybox,操作简单长,但是如果全编译时间长。


==== buildroot套件的全编译 ====


==相关链接==
下面以100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig配置文件为例,在ubuntu终端上说明 Buildroot 的配置过程,在 <code>~/100ask_imx6ull-sdk/Buildroot_2020.02.x</code> 路径下:
英文维基百科的"rtos"词条:          http://en.wikipedia.org/wiki/RTOS


英文维基百科之 “List of real-time operating systems”              http://en.wikipedia.org/wiki/List_of_real-time_operating_systems
<pre>make clean
make 100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig
make all</pre>
注:其中buildroot支持的配置如下:


=常用开发工具=
<pre>book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x$  make list-defconfigs
==Proteus==
Built-in configs:
Proteus软件是初学者入门的首选软件,它是Labcenter Electronics公司的一款商业版电路设计与仿真软件,它包括ISIS、ARES等软件模块,ARES模块主要用来完成PCB的设计,ISIS模块用来完成电路原理图的布图与仿真。Proteus的软件仿真基于VSM技术,它与其他软件最大的不同也是最大的优势就在于它能仿真大量的单片机芯片,比如MCS-51系列、PIC系列等等,甚至ARM处理器,以及单片机外围电路,比如键盘、LED、LCD等等,该软件附带了一些案例和丰富的帮助文件。
  100ask_imx6ull_mini_ddr512m_systemV_core_defconfig - Build for 100ask_imx6ull_mini_ddr512m_systemV_core
==Keil C51==
  100ask_imx6ull_mini_ddr512m_systemV_qt5_defconfig - Build for 100ask_imx6ull_mini_ddr512m_systemV_qt5
Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。用过汇编语言后再使用C来开发,体会更加深刻。
  100ask_imx6ull_pro_ddr512m_systemV_core_defconfig - Build for 100ask_imx6ull_pro_ddr512m_systemV_core
==SDCC==
  100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig - Build for 100ask_imx6ull_pro_ddr512m_systemV_qt5
SDCC支持8051单片机,Z80单片机,以及PIC单片机。为跨平台软件。生成的代码执行速度比 Keil C51 更加快速。并且汇编代码具有良好的可读性。跨平台的IDE有mcu8051ide。
  100ask_stm32mp157_pro_ddr512m_busybox_core_defconfig - Build for 100ask_stm32mp157_pro_ddr512m_busybox_core
....
  qemu_aarch64_virt_defconfig        - Build for qemu_aarch64_virt
  qemu_arm_versatile_defconfig        - Build for qemu_arm_versatile
  qemu_arm_versatile_nommu_defconfig  - Build for qemu_arm_versatile_nommu
  qemu_arm_vexpress_defconfig        - Build for qemu_arm_vexpress
  qemu_arm_vexpress_tz_defconfig      - Build for qemu_arm_vexpress_tz
......
  raspberrypi0_defconfig              - Build for raspberrypi0
  raspberrypi0w_defconfig            - Build for raspberrypi0w
  raspberrypi2_defconfig              - Build for raspberrypi2
  raspberrypi3_64_defconfig          - Build for raspberrypi3_64
  raspberrypi3_defconfig              - Build for raspberrypi3
  raspberrypi3_qt5we_defconfig        - Build for raspberrypi3_qt5we
  raspberrypi4_64_defconfig          - Build for raspberrypi4_64
  raspberrypi4_defconfig              - Build for raspberrypi4
  raspberrypi_defconfig              - Build for raspberrypi
  .......</pre>
<span id="在-buildroot-下进入-menuconfig-包选择配置配置界面"></span>
==== 在 buildroot 下进入 menuconfig 包选择配置配置界面 ====


=常见的开源项目=
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make menuconfig</pre>
==Android==
<span id="buildroot-下单独编译-u-boot"></span>
===相关介绍===
==== buildroot 下单独编译 u-boot ====
英文维基百科的"Android"词条:
 
http://en.wikipedia.org/wiki/Android_google
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make uboot-rebuild </pre>
=== 安装步骤===
<span id="buildroot-下单独编译内核dts"></span>
http://source.android.com/download#TOC-Ubuntu-Linux-32-bit-x86
==== buildroot 下单独编译内核+dts ====
 
在 <code>book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/dl/linux/git</code> 路径下
 
<pre>find . -iname *.o|xargs rm -rf *.o
make mrproper
make 100ask_imx6ull_defconfig
make zImage  -j4
make dtbs
cp arch/arm/boot/zImage  /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images/
cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb  /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images/</pre>
//nisy:这个zImage是真正重编译的,但是buildroot的sdcard.img 的kernel没有重新编译,如何解决?
 
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make linux-rebuild    //存疑,似乎仅仅是重新打包了zImage</pre>
<span id="buildroot-下进入内核-make-menuconfig-配置选项界面"></span>
==== buildroot 下进入内核 make menuconfig 配置选项界面 ====
 
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make linux-menuconfig </pre>
<span id="buildroot-下单独编译某个软件包"></span>
==== buildroot 下单独编译某个软件包 ====
 
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make &lt;pkg&gt;-rebuild </pre>
<span id="buildroot-下进入-busybox-配置界面"></span>
==== buildroot 下进入 busybox 配置界面 ====
 
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make busybox-menuconfig </pre>
buildroot 下生成系统 sdk,最后生成的目录在 output/images/目录下
 
<pre>book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make sdk </pre>
<span id="buildroot-下检查文件系统是否真正重编译"></span>
==== buildroot 下检查文件系统是否真正重编译 ====
 
可以在这个文件中做标记:
 
<pre>vi /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/board/100ask/nxp-imx6ull/rootfs-overlay/systemV/etc/issue </pre>
烧入单板后,检查登陆后,是否有自己标记的字符串。

2023年6月18日 (日) 17:01的版本

基于NXP IMX6ULL芯片的开发板

百问网100ask IMX6ULL开发板

在windows +虚拟机环境下开发(参考《第四 A 章 使用 USB 网卡直连配置网络》)

//启动方式如下: image

注意:这个拨码仅仅是uboot的启动,而uboot有可能启动的是sd卡(mmc=0),也考虑启动的是emmc(mmc=1),可以在uboot的环境变量中配置:

=> printenv
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
......
......
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1      //原始是mmc=1即emmc启动
mmcpart=2
mmcroot=/dev/mmcblk1p2 rootwait rw      //原始是mmc=1即emmc启动
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
......
......

Environment size: 2738/8188 bytes
=> setenv mmcdev 0      //改为mmc=0即sd卡启动
=> setenv mmcroot/dev/mmcblk0p2 rootwait rw      //改为mmc=0即sd卡启动
=> saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
=>

从开机log可以看到到底是mmc=0即sd卡启动:

U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)

CPU:   Freescale i.MX6ULL rev1.1 696 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 39C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT7016 (1024x600)
Video: 1024x600x24
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0
## Error: "findtee" not defined
switch to partitions #0, OK
mmc0 is current device                    <<<<<<<
switch to partitions #0, OK
mmc0 is current device                    <<<<<<<

还是mmc=1即emmc启动:

U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)

CPU:   Freescale i.MX6ULL rev1.1 696 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 42C
Reset cause: POR
Model: Freescale i.MX6 ULL 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT7016 (1024x600)
Video: 1024x600x24
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0
## Error: "findtee" not defined
switch to partitions #0, OK
mmc1(part 0) is current device                    <<<<<<<
switch to partitions #0, OK
mmc1(part 0) is current device                    <<<<<<<

//调试环境如下: image

虚拟机的配置类似如下: image

vscode使用ssh remote插件远程登陆vmware的代码:

<img src="1974711-20221009232455525-267471114.png" width="40%">

效果图:

<img src="1974711-20221009232532859-1841111653.png" width="40%">

//开发板配置: ifconfig eth0 192.168.5.9 为了避免每次开机配置,可以: 设置 IP 为固定静态 IP(开机不变) 设置 eth0 为静态 IP 地址, 开发板/etc/network/目录下对 interfaces 文件进行修改 。 [root@100ask:~]# vi /etc/network/interfaces 修改并为如下内容,执行 :wq 保存并退出,执行/etc/init.d/S40network restart 重启网络服务。

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
    address 192.168.5.9
    netmask 255.255.255.0
    gateway 192.168.5.1

《4.4.1 文件系统内使用 nfs 挂载 ubuntu 目录》

[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

在windows +虚拟机环境下开发(参考《第四 B 章 使用路由器配置网络》)

1.windows PC的wifi和路由器连接,比如获得IP是192.168.3.240.虚拟机使用“桥接模式-直接连接物理网络”,比如获得IP是192.168.3.10 2.开发板启动wifi,可以直接执行如下start_wifi.sh的shell脚本:

#!/bin/bash
#启用 wlan0 无线网络设备
ifconfig wlan0 up
#扫描周围网络设备
#iw dev wlan0 scan |grep SSID
#配置网络连接参数
rm -rf /etc/wpa_supplicant.conf
wpa_passphrase weiba1985 19560206 >> /etc/wpa_supplicant.conf
#连接 wifi 设备
wpa_supplicant -B -iwlan0 -c /etc/wpa_supplicant.conf
#查看连接状态
iw wlan0 link
#为 wlan0 获取 ip 地址,确认与PC可以相互ping通
udhcpc -i wlan0
#查看所有网络设备
ifconfig -a

比如获得路由器分配的IP是192.168.3.6 3.用mobaxterm可以分别ssh连接到虚拟机和开发板的终端,在开发板的终端把虚拟机的文件系统加入mnt: mount -t nfs -o nolock,vers=3 192.168.3.10:/home/book/nfs_rootfs /mnt

代码编译

代码下载

执行以下4条命令,为方便大家复制,第3条是很长的命令,使用了,需要一并拷贝:

book@100ask:~ git clone https://e.coding.net/codebug8/repo.git
book@100ask:~$ mkdir -p 100ask_imx6ull-sdk && cd 100ask_imx6ull-sdk
book@100ask:~/100ask_imx6ull-sdk$ ../repo/repo init -u \
 https://gitee.com/weidongshan/manifests.git -b \
linux-sdk -m imx6ull/100ask_imx6ull_linux4.9.88_release.xml  --no-repo-verify
book@100ask:~/100ask_imx6ull-sdk$  ../repo/repo sync -j4

在 ~/.bashrc 的行尾添加如下:

export ARCH=arm
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export   PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin

设置完毕后,要执行 source ~/.bashrc 命令使其生效,

应用程序的编译和执行

我们要想给 ARM 板编译出 hello 程序,需要使用交叉编译工具链,比如:

$ arm-buildroot-linux-gnueabihf-gcc -o hello hello.c

这样编译出来的 hello 程序才可以在 ARM 板子上运行。 先把编译生成的 hello 文件拷贝到 Ubuntu nfs 服务目录下,备用:

$ cp  hello   /home/book/nfs_rootfs

调试开发板方法1:使用nfs方式

这种方式一般不自己从头开始编译busybox,只用于调试uboot+linux kernel+dts,文件系统即busybox不需要调整的场景。 #### uboot

u-boot的编译过程如下(编译uboot前必须先配置好工具链等开发环境):
book@100ask: ~/100ask_imx6ull-sdk$ cd Uboot-2017.03
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make distclean
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make  mx6ull_14x14_evk_defconfig 
book@100ask: ~/100ask_imx6ull-sdk/Uboot-2017.03$ make

编译后检查是否生效,需要看看开机时间戳是否改变了,如下:

U-Boot 2017.03 (Oct 29 2022 - 21:06:24 -0400)

LINUX内核+dts

为了防止编译没有生效,除了留意打印的编译时间戳,还可以修改一些标记处,烧入单板时检查标记是否生效了,比如kernel顶层Makefile的:

VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 88
EXTRAVERSION = 20221029_by_nishengyue        <------  增加标记

烧入单板后应该有类似的打印,说明编译真正生效了:

[  0.000000] Booting Linux on physical CPU 0x0
[  0.000000] Linux version 4.9.8820221029_by_nishengyue (book@100ask) (gcc version 7.5.0 (Buildroot 2020.02-gee85cab) ) #1 SMP PREEMPT Sun Oct 30 11:46:38 CST 2022

~/100ask_imx6ull-sdk/Linux-4.9.88 路径下,kernel的编译过程如下(编译内核前需要先配置好工具链等一些环境变量):

make mrproper
make 100ask_imx6ull_defconfig
make zImage  -j4
make dtbs V=1
cp arch/arm/boot/zImage ~/nfs_rootfs
cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb  ~/nfs_rootfs

如果出现 multiple definition of `yylloc` 报错,请参考该链接解决:https://blog.csdn.net/qq_36393978/article/details/117695708

这样在nfs_rootfs 能看到zImage和100ask_imx6ull-14x14.dtb 文件。

编译内核MODULE

book@b ook-virtual-machine:~$ cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-
gnueabihf- modules

安装内核module执行以下命令:

book@book-virtual-machine:~$ cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$   sudo   make     ARCH=arm   INSTALL_MOD_PATH=/home/book/nfs_rootfs/ modules_install

这样在 nfs_rootfs 能看到 lib 文件夹。

安装编译的内核+设备树+module

执行命令拷贝:

cp  /mnt/zImage  /boot
cp  /mnt/*.dtb   /boot
cp  /mnt/lib/modules  /lib  -rfd

uboot从nfs网络启动

1.编译的结果拷贝到nfs目录下:

book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp zImage  ~/nfs_rootfs/
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp 100ask_imx6ull-14x14.dtb  ~/nfs_rootfs/
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cp -rf  rootfs.tar.bz2  ~/nfs_rootfs/
book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images$ cd ~/nfs_rootfs
book@100ask:~/nfs_rootfs$ sudo tar  xjf  rootfs.tar.bz2

2.ubuntu开启tftp: 在 Ubuntu 中执行以下命令安装 TFTP 服务:

sudo apt-get install tftp-hpa tftpd-hpa 

然后,创建 TFTP 服务器工作目录,并打开 TFTP 服务配置文件,如下:

sudo vim /etc/default/tftpd-hpa 

在配置文件/etc/default/tftpd-hpa 中,添加以下字段:

TFTP_DIRECTORY="/home/book/nfs_rootfs" 
TFTP_OPTIONS="-l  -c  -s" 

最后,重启 TFTP 服务:

sudo service tftpd-hpa restart 

查看 tftp 服务是否在运行,运行如下命令,即可查看是否在后台运行。

ps -aux | grep "tftp"

3.ubooot阶段启动停住后,输入如下:

=> setenv serverip 192.168.5.11     //设置服务器的 IP 地址,这里指的是 Ubuntu 主机 IP 
=> setenv ipaddr 192.168.5.9         //设置开发板的 IP 地址。 
=> ping 192.168.5.11     //检查是否能ping通
=> setenv nfsroot /home/book/nfs_rootfs   //设置 nfs 文件系统所在目录。 
=> run netboot            //设置完成后,运行网络启动系统命令 

调试开发板方法2:使用编译buildroot套件并烧录进单板

这种方式一般可以一次性编译uboot+linux kernel+dts+文件系统busybox,操作简单长,但是如果全编译时间长。

buildroot套件的全编译

下面以100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig配置文件为例,在ubuntu终端上说明 Buildroot 的配置过程,在 ~/100ask_imx6ull-sdk/Buildroot_2020.02.x 路径下:

make clean
make 100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig
make all

注:其中buildroot支持的配置如下:

book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x$  make list-defconfigs
Built-in configs:
  100ask_imx6ull_mini_ddr512m_systemV_core_defconfig - Build for 100ask_imx6ull_mini_ddr512m_systemV_core
  100ask_imx6ull_mini_ddr512m_systemV_qt5_defconfig - Build for 100ask_imx6ull_mini_ddr512m_systemV_qt5
  100ask_imx6ull_pro_ddr512m_systemV_core_defconfig - Build for 100ask_imx6ull_pro_ddr512m_systemV_core
  100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig - Build for 100ask_imx6ull_pro_ddr512m_systemV_qt5
  100ask_stm32mp157_pro_ddr512m_busybox_core_defconfig - Build for 100ask_stm32mp157_pro_ddr512m_busybox_core
....
  qemu_aarch64_virt_defconfig         - Build for qemu_aarch64_virt
  qemu_arm_versatile_defconfig        - Build for qemu_arm_versatile
  qemu_arm_versatile_nommu_defconfig  - Build for qemu_arm_versatile_nommu
  qemu_arm_vexpress_defconfig         - Build for qemu_arm_vexpress
  qemu_arm_vexpress_tz_defconfig      - Build for qemu_arm_vexpress_tz
......
  raspberrypi0_defconfig              - Build for raspberrypi0
  raspberrypi0w_defconfig             - Build for raspberrypi0w
  raspberrypi2_defconfig              - Build for raspberrypi2
  raspberrypi3_64_defconfig           - Build for raspberrypi3_64
  raspberrypi3_defconfig              - Build for raspberrypi3
  raspberrypi3_qt5we_defconfig        - Build for raspberrypi3_qt5we
  raspberrypi4_64_defconfig           - Build for raspberrypi4_64
  raspberrypi4_defconfig              - Build for raspberrypi4
  raspberrypi_defconfig               - Build for raspberrypi
  .......

在 buildroot 下进入 menuconfig 包选择配置配置界面

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make menuconfig

buildroot 下单独编译 u-boot

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make uboot-rebuild 

buildroot 下单独编译内核+dts

book@100ask:~/100ask_imx6ull-sdk/Buildroot_2020.02.x/dl/linux/git 路径下

find . -iname *.o|xargs rm -rf *.o
make mrproper
make 100ask_imx6ull_defconfig
make zImage  -j4
make dtbs
cp arch/arm/boot/zImage  /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images/
cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb  /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/images/

//nisy:这个zImage是真正重编译的,但是buildroot的sdcard.img 的kernel没有重新编译,如何解决?

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make linux-rebuild    //存疑,似乎仅仅是重新打包了zImage

buildroot 下进入内核 make menuconfig 配置选项界面

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make linux-menuconfig 

buildroot 下单独编译某个软件包

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make <pkg>-rebuild 

buildroot 下进入 busybox 配置界面

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make busybox-menuconfig 

buildroot 下生成系统 sdk,最后生成的目录在 output/images/目录下

book@100ask: ~/100ask_imx6ull-sdk/Buildroot_2020.02.x$ make sdk 

buildroot 下检查文件系统是否真正重编译

可以在这个文件中做标记:

vi /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/board/100ask/nxp-imx6ull/rootfs-overlay/systemV/etc/issue 

烧入单板后,检查登陆后,是否有自己标记的字符串。