从yocto开始
什么是yocto
Yocto项目是一个开源协作项目,可帮助开发人员创建基于Linux的定制系统,这些系统专为嵌入式产品而设计
imx8搭建yocto环境
注意:不能使用root用户搭建yocto环境
基于yocto手册《i.MX Yocto Project User’s Guide》
- 安装必要的软件包
sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \
build-essential chrpath socat libsdl1.2-dev
2.设置repo下载功能
Repo 是一个构建在 Git 之上的工具,它可以更轻松地管理包含多个存储库的项目,这些存储库不需要位于同一台服务器上。 Repo 很好地补充了 Yocto 项目的分层特性,使用户可以更轻松地将自己的层添加到 BSP
要安装“repo”实用程序,请执行以下步骤
1. Create a bin folder in the home directory.
$ mkdir ~/bin (this step may not be needed if the bin folder already exists)
$ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
2.Add the following line to the .bashrc file to ensure that the ~/bin folder is in your PATH variable.
export PATH=~/bin:$PATH
3.设置yocto工程
1.首先确保使用以下命令正确设置了 git
$ git config --global user.name "Your Name"
$ git config --global user.email "Your Email"
$ git config --list
2.repo同步
$ cd /opt/yocto
$ mkdir fsl-release-bsp
$ cd fsl-release-bsp
$ repo init -u git://git.freescale.com/imx/fsl-arm-yocto-bsp.git -b imx-4.1-krogoth
$ repo sync
4.构建镜像
i.MX 提供了一个脚本 fsl-setup-release.sh,可简化 i.MX 开发板的设置,要使用该脚本,需要指定要为其构建的开发板的类型以及所需构建的镜像类型
1.设置脚本环境
$ DISTRO=<distro name> MACHINE=<machine name> source fsl-setup-release.sh -b <build dir>
distro name有如下选择
fsl-imx-x11 //Only X11 graphics
fsl-imx-wayland // Wayland weston graphics
fsl-imx-xwayland //Wayland graphics and X11. X11 applications using EGL are not
supported
fsl-imx-fb // Frame Buffer graphics - no X11 or Wayland
<machine name>有如下选择
imx6qpsabreauto•imx6qpsabresd•imx6ulevk•imx6ull14x14evk•imx6ull9x9evk•imx6dlsabreauto•
imx6dlsabresd•imx6qsabreauto•imx6qsabresd•imx6slevk•imx6solosabreauto•imx6solosabresd•
imx6sxsabresd•imx6sxsabreauto•imx6sllevk•imx7dsabresd•imx8qmlpddr4arm2•imx8mq_evk•
imx8qxplpddr4arm2• imx7ulpevk
根据需要选择fsl-imx-x11和imx8mq_evk
$ DISTRO=fsl-imx-x11 MACHINE=imx8mq_evk source fsl-setup-release.sh -b <build dir>
不同发行版本的配置信息在meta-fsl-bsp-release/imx/meta-sdk/conf/distro中可以查看
以fsl-imx-x11.conf为例,其内容为
# i.MX DISTRO for X11 with no wayland
include conf/distro/include/fsl-imx-base.inc
include conf/distro/include/fsl-imx-preferred-env.inc
DISTRO = "fsl-imx-x11"
# Remove conflicting backends.
DISTRO_FEATURES_remove = "wayland"
# These are X11 specific
DISTRO_FEATURES_append = " x11"
同样在meta-fsl-bsp-release/imx/meta-bsp/conf/machine下可以看到machine的配置信息
-b <build dir> 指定由fsl-setup-release.sh脚本创建的生成目录的名称 本例设为build
最终执行命令为
$ DISTRO=fsl-imx-x11 MACHINE=imx8mq_evk source fsl-setup-release.sh -b build dir10
2.接受EULA协议
当脚本运行时,它会提示用户接受 EULA。 接受 EULA 后,接受将存储在每个构建文件夹内的
local.conf 中,并且不再显示该构建文件夹的 EULA 接受查询。
当脚本执行完毕后,会在生成
# build/conf/bblayers.conf local.conf
其中bblayers.conf包含了 Yocto项目版本中使用的所有层(metalayer)
local.conf中记录了machine和distro信息,如果需要可以编辑此文本来修改machine信息
3.选择 i.MX Yocto 项目映像
可供选择的镜像包括:
core-image-minimal
core-image-base
core-image-sato
fsl-image-machine-test
fsl-image-gui
fsl-image-qt5
4.1使用bitbake命令构建镜像
本例选择 core-image-minimal
故命令为 $bitbake core-image-minimal
bitbake的详细教程可以参考《BitBake User Manual》
编译时间较长,如果编译过程中无意关掉了终端,那么重新打开终端进入fsl-release-bsp目录
后只需要执行以下命令就可以重新进入编译环境:
$ source setup-environment build
4.2编译交叉工具链:
bitbake meta-toolchain
编译完成后会在/opt/yocto/fsl-release-bsp/build/tmp/deploy/sdk目录下生成文件
5.u-boot的配置
U-Boot 配置在主机配置文件中定义。 配置是通过使用 UBOOT_CONFIG 设置来指定的。
这需要在 local.conf 中设置 UBOOT_CONFIG。 否则,U-Boot 构建默认使用 SDboot
6.镜像部署
构建完成后,创建的镜像位于 <build directory>/tmp/deploy/images。 大多数情况下,
映像特定于环境设置中的机器设置。 每个镜像构建都会根据机器配置文件中定义的 IMAGE_FSTYPES
创建
一个 U-Boot、一个内核和一个镜像类型。
大多数机器配置提供一个 SD 卡映像 (.sdcard)、一个 ext3 和 tar.bz2。 ext3 只是根文件系统。
.sdcard 映像包含 U-Boot、内核和 rootfs 完全设置为在 SD 卡上使用
7.烧录到sd卡
在imx-yocto-bsp/build/tmp/deploy/images目录下生成的imx8mqevk中包含 .sdcard 映像将其解压后
烧录到sd卡中
$ sudo dd if=<image name>.sdcard of=/dev/sd<partition> bs=1M && sync
使用fdisk -l 查看sd卡的<partition> 最终命令为
$ sudo dd if=core-image-minimal-imx8mqevk-20210812023532.rootfs.sdcard
of=/dev/sdb bs=1M && sync
8.设置开发板从sd启动
将拨码开关调成Table 7.Booting from TF on i.MX 8MQuad EVK所示,插入TF卡,连接开发板,
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1gDMlJTOjJmZ3U2YiJTZ4UDMkRTY1kDZiV2M3ITZkN2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
注意:当运行bitbake 是若显示 command not found 在poky目录下运行oe-init-build-env后即可使用bitbake命令
————————————————————————————————————————————
用户态控制GPIO点亮开发板LED
通过开发板电路图查找LED对应的GPIO,对应位PWM_LED,继续查找PWM_LED
PWM_LED对应GPIO1_IO13
GPIO序号计算
Led对应的GPIO为GPIO1_IO13,连接开发板后在/sys/class/gpio目录下可以看到每组GPIO增加32
故GPIO1_IO13对应需要为:
(n-1)*32 + i
n和i分别对应GPIO1_IO13中的1和13 故其序号为13
GPIO点亮LED
1.将标号13的GPIO导入到文件系统,在该路径下使用以下命令,在该目录下会生成gpio13目录
echo 13> export
实际使用时,GPIO13被内核占用作为电源指示灯,echo 13 > export会失败,需要修改内核源码解除其
对GPIO1_13的使用后(这部分内容仍需学习),echo 13 > export才会成功
2.控制GPIO为输出
echo out > direction
3.控制高低电平
echo 1 > value
以上通过用户态控制GPIO实现点亮LED
汇编点亮LED
- 使能GPIO1_13对应的时钟 查找发现其对应的GPIO时钟为CCGR11
总结与不足感悟 -
计算CCGR11地址
根据计算公式CCGR的地址为
3038_0000 + 4000 + (10 × 11) = 3038_40B0
将16转为十六进制计算
为方便 将其32位全部置为1
ldr r0,=0x3038_40B0
ldr r1,=0xffffffff
str r1,[r0]
-
设置引脚复用为GPIO
找到GPIO1_IO13复用对应地址为0x3033_005C,
并将其设置为普通IO总结与不足感悟 总结与不足感悟
ldr r0,=0x3033_005C
ldr r1,=0x0
srt r1,[r0]
- 设置引脚属性 默认设置为0x10b0
总结与不足感悟
ldr r0,=0x3033_02C4
ldr r1=0x10b0
str r1,[r0]
-
控制GPIO引脚为输出模式
当IOMUXC 处于GPIO 模式时,GPIO_GDIR 用作方向控制。 每个位指定一位信号的方向。 每个 DIR 位到相应 SoC 信号的映射由 SoC 的引脚分配和 IOMUX 表决定
总结与不足感悟 对应位设为0表示输入,设为1表示输出,及将其第13位设置为1
GPIO_DIR对应位置为基地址GIPIO1的地址+4的偏移
GIPIO1的地址为0x3020_0000
ldr r0,=0x3020_0004
ldr r1,=8192
str r1,[r0]
-
控制GPIO引脚输出1
如果 IOMUXC 处于 GPIO 模式并且设置了给定的 GPIO 方向位,则相应的 DR 位被驱动到输出。 如果给定的 GPIO 方向位被清零,则 GPIO_DR 的读取反映了相应信号的值
将GPIO13输出为低电平总结与不足感悟
ldr r0,=0x3020_0000
ldr r1,=0
str r1,[r0]
-
后续问题
将写好的汇编文件通过交叉编译得到二进制文件,但其不能在开发板上运行,缺少了启动相关信息。为二进制文件添加头部信息需要在后续学习补充
Makefile
通过C语言来点亮LED(通过在用户态控制GPIO13)
GPIO13_DRICTION地址和GPIO13_VALUE地址如下
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define GPIO13_DRICTION "/sys/devices/platform/30200000.gpio/gpiochip0/gpio/gpio13/direction"
#define GPIO13_VALUE "/sys/devices/platform/30200000.gpio/gpiochip0/gpio/gpio13/value"
int main(){
FILE*dri,*value;
printf("this is led swap \r\n");
dri = fopen(GPIO13_DRICTION,"w");
value = fopen(GPIO13_VALUE,"w");
if(dri<0||value<0){
printf("faile to open\r\n");
exit(1);
}
fwrite("out",3,1,dri);
fflush(dri);
while(1){
fwrite("1",1,1,value);
fflush(value);
printf("on\r\n");
sleep(1);
fwrite("0",1,1,value);
fflush(value);
printf("off\r\n");
sleep(1);
}
return 0;
}
通过交叉编译得到可执行文件,通过U盘拷贝到开发板后执行,可以实现LED闪烁
注意:U盘需要为FAT32格式
编写Makefile
将实现闪烁功能的led.c文件放在module1目录下,主函数main.c文件放在module2目录下,头文件led.h放在include目录下
main.c函数
#include<stdio.h>
#include "led.h"
#include<stdlib.h>
#include<unistd.h>
FILE*value;
FILE*dir;
int main(){
value = fopen(GPIO13_VALUE,"w");
dir = fopen(GPIO13_DRICTION,"w");
if(value<0||dir<0){
printf("open fail\r\n");
return 0;
}
fwrite("out",3,1,dir);
fflush(dir);
while(1){
on();
fflush(value);
sleep(1);
off();
fflush(value);
}
printf("ok\r\n");
return 0;
}
Makefile
ARCH ?= x86
ifeq ($(ARCH),x86)
CC=gcc
else
CC=aarch64-linux-gnu-gcc #arm平台下使用aarch64-linux-gnu-gcc
endif
TARGET=led #生成目标
#OBJS=main.o mp3.o
BUILD_DIR=build #生成目录
SRC_DIR=module1 module2 #源路径
INC_DIR=include #头文件路径
CFLAGS=$(patsubst %,-I%,$(INC_DIR)) #链接
INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h)) #include下所有的头文件
SOURCES=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c)) #所有的.c文件
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCES))) #根据.c文件对应的.o目标文件
VPATH=$(SRC_DIR) #搜索路径
$(BUILD_DIR)/$(TARGET):$(OBJS) #终极目标 在目录下生成目标 依赖于objs
$(CC) $^ -o $@
$(BUILD_DIR)/%.o:%.c $(INCLUDES) | create_build
$(CC) -c $< -o $@ $(CFLAGS)
.PHONY:clean create_build #伪目标
clean:
rm -r $(BUILD_DIR)
create_build:
mkdir -p $(BUILD_DIR)
执行 make ARCH=arm 命令 最终生成
make clean 删除build文件
感悟
入职至今,不觉中已有一月有余,感触颇深。入职前站在公司门口,对里面的一切充满了好奇与期望,很幸运,这里有着和谐的工作氛围、热情友善的同事以及耐心认真的导师,在大家的帮助下,我从刚进公司时的无知,渐渐地熟悉了这个全新的氛围,并深刻的体会到学习的重要性。
一、学习要有针对性
从学校到公司,一起都是陌生而又崭新的。新入职的一个月主要以学习和培训为主,公司的培训让我对公司的业务、发展有了全面的认识,同时对自己的职业发展有了更明确的规划;自我学习过程中,看着几千页的英文手册,也曾感到迷惘与失落,好在导师同事及时的指导让我明白了学习要有针对性和目的性,和以往学习过的内容相比,工作中更多的内容需要重新学习,在学习过程中不应有畏难情绪,要针对工作内容选择性和针对性的学习。“吾生也有涯,而知也无涯”,知识是无穷尽的,只有明确了自己的目标与方向,将工作与学习结合起来,才能在有限的时间中更高效的学习、更高效的工作。
二、学习要主动,不懂就要问
学习过程中有很多问题一时半会查不到,刚入职时,因为与同事导师还不是很熟悉,难免有些不好意思开口,时间一久,问题便落下了。后面在相处的过程中,导师同事的热情友善打消了我的顾虑,遇到困难时他们总会不厌其烦的给我讲解分析,并让我不要难为情,学习要主动,有了不懂就要问。
三、学习是为了自己
学习不是为了他人而学,最终受益的是自己,因此要多学习,公司为我们提供了良好的学习环境和完善的培养计划,就应该积极主动的抓住这些机会,将自身所学和公司所需结合起来,实现自己和公司的双赢发展,在实现自身价值的同时,为公司献上一份力,学习是为了更好的工作,工作也是在不断的学习!
以上是我一个多月来的总结,工作中还有很多的不足,烦请大家多多指教!