提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本文章的目的是为了让初学者学会开发板-windows-ubutun能通过网络传输文件,极大程度方便开发者进行开发工作。
确定开发板网口连接的是哪个网卡,要是路由器上的网卡就直接通过网络适配器擦看网络的IP地址-子网掩码;要是直连网卡就通过网络适配器设置IP地址-子网掩码-默认网关。
1)安装nfs指令:sudo apt-get install nfs-kernel-server
2)配置nfs挂载目录:vim /etc/exports;在脚本中添加/home/book *(rw,nohide,insecure,no_subtree_check,async,no_root_squash);表示nfs网络服务的mnt下面 挂载了 /home/book 所有文件
3)重启nfs服务:sudo /etc/init.d/nfs-kernel-server restart
4)验证nfs服务:在ubuntu下挂载自己:sudo mount -t nfs -o nolock,vers=3 127.0.0.1:/home/book /mnt 其中127.0.0.1 为ubuntu的IP地址
5)在开发板中挂载nfs服务 mount -t nfs -o nolock,vers=3 127.0.0.1:/home/book /mnt 其中127.0.0.1 为开发板的IP地址,将ubuntu下的/home/book 挂载到开发板中,假设在book下有hello文件,
执行 cp /mnt/hello ./hello,将nfs目录下的hello文件拷贝到开发板的根目录。
6)使用 ls /mnt 查看目录有没有挂载。
7) 卸载nfs服务 umount /mnt-Point
1)安装tftp指令sudo apt-get install tftp-hpa tftpd-hpa
2)创建TFTP服务器工作目录,并打开TFTP服务配置文件
mkdir -p /home/book/tftpboot
sudo chmod 777 /home/book/tftpboot
sudo vim /etc/default/tftpd-hpa
在配置文件/etc/default/tftpd-hpa中,添加以下字段
TFTP_DIRECTORY=“/home/book/tftpboot”
TFTP_OPTIONS=“-l -c -s”
3)重启TFTP服务
sudo service tftpd-hpa restart
4)查看tftp服务是否在ubuntu下运行
ps -aux | grep “tftp”
5)在开发板上使用tftp命令下载文件
假设tftp服务目录内有zImage文件
tftp -g -r zImage 192.168.1.123
6)在开发板上使用tftp命令上传文件
tftp -p -l 1.txt 192.168.1.123
傻瓜式传输
在Ubuntu终端上执行如下命令git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git
01_all_series_quickstart
04_嵌入式Linux应用开发基础知识\source\01_hello
1)设置交叉编译工具链
交叉编译工具链用来在Ubuntu主机上编译应用程序,而这些应用程序是在ARM等其他平台上运行。
设置交叉编译工具主要是设置PATH, ARCH和CROSS_COMPILE三个环境变量,下面介绍具体设置方法。
在本文档中,源码、交叉编译工具链都是存放于/home/book目录下;如果你的目录不一样,请自行修改本节所讲述的命令。
设置这3个环境变量有多种方法,任意选择其中一种方法即可,建议使用“永久生效”的方法。录制视频时我会使用多种开发板,所以在视频里我总是使用“临时生效”的方法
2)永久生效
vim ~/.bashrc
在行尾添加或修改,加上下面几行(第3行第4行为一行命令)
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
3)设置完毕后,要执行 source ~/.bashrc 命令使其生效,这条命令是加载 这些设置的环境变量。
4)临时生效
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
5)手动指定
先设置PATH环境变量,然后在make编译时指定ARCH架构 CROSS_COMPILE交叉编译工具链(执行make命令时指定的参数,只对当前命令有效;下次执行make时仍需要再次指定那些参数)
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
6)测试环境变量
echo $ARCH
echo $CROSS_COMPILE
7)测试编译器
arm-buildroot-linux-gnueabihf-gcc -v
$ gcc -o hello hello.c
$ ./hello
Hello, world!
$ ./hello weidongshan
Hello, weidongshan!
上述命令编译得到的可执行程序hello可以在Ubuntu中运行,但是如果把它放到ARM板子上去,它是无法执行的。因为它是使用gcc编译的,是给PC机编译的,里面的机器指令是x86的。
我们要想给ARM板编译出hello程序,需要使用交叉编译工具链,比如:
$ arm-buildroot-linux-gnueabihf-gcc -o hello hello.c
这样编译出来的hello程序才可以在ARM板子上运行。
先把编译生成的 hello 文件拷贝到Ubuntu nfs服务目录下,备用:
$ cp hello /home/book/nfs_rootfs
开发板启动后通过nfs挂载Ubuntu目录的方式,将相应的文件拷贝到开发板上。
如果你使用的是VMware桥接方式,假设Ubuntu IP为192.168.1.100,在开发板上执行以下命令:
[root@imx6ull:~]# mount -t nfs -o nolock,vers=3 192.168.1.100:/home/book/nfs_rootfs /mnt
[root@imx6ull:~]# cp /mnt/hello ./hello
最后,执行如下操作添加可执行权限,并运行它:
[root@imx6ull:~]# chmod +x hello
[root@imx6ull:~]# ./hello
请按前面第八章使用GIT下载源码、使用repo下载工具链,并配置了交叉编译工具链。
为什么编译驱动程序之前要先编译内核?
① 驱动程序要用到内核文件:
比如驱动程序中这样包含头文件:#include
② 编译驱动时用的内核、开发板上运行到内核,要一致:
开发板上运行到内核是出厂时烧录的,你编译驱动时用到内核是你自己编译的,这两个内核不一致时会导致一些问题。
所以我们编译驱动程序前,要把自己编译出来到内核放到板子上去,替代原来的内核。
③ 更换板子上的内核后,板子上的其他驱动也要更换:
板子使用新编译出来的内核时,板子上原来的其他驱动也要更换为新编译出来的。
所以在编译我们自己的第1个驱动程序之前,要先编译内核、模块,并且放到板子上去
从Git仓库驱动源码相关文件,在Ubuntu终端上执行如下命令。
git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git
使用GIT获取到源码后,可查看本节源码所在目录,目录位置如下:
01_all_series_quickstart/05_嵌入式Linux驱动开发基础知识
/source/02_led_drv/02_led_drv_for_boards/100ask_imx6ull_src_bin
不同的开发板对应不同的配置文件,配置文件位于内核源码arch/arm/configs/目录
book@100ask:~/100ask_imx6ull-sdk$ cd Linux-4.9.88
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make mrproper
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make 100ask_imx6ull_defconfig
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make zImage -j4
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make dtbs
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ cp arch/arm/boot/zImage ~/nfs_rootfs
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs
编译步骤参考如下,编译完成zImage后才可编译设备树文件。
编译完成后,在arch/arm/boot目录下生成zImage内核文件, 在arch/arm/boot/dts目录下生成设备树的二进制文件100ask_imx6ull-14x14.dtb。
把这2个文件复制到/home/book/nfs_rootfs目录下备用,如下图:
无论是哪个版本的IMX6ULL开发板,编译内核模块的命令是一样的。
进入内核源码目录后,就可以编译内核模块了 (注意 下述命令 = 前后没有空格):
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
可以先把内核模块安装到nfs根文件系统(/home/book/nfs_rootfs为安装目录)。
注意:下面会执行tree命令,如果提示没有该命令,需要执行“sudo apt install tree”命令安装tree工具(前提是Ubuntu能上网)。
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
假设:执行上述命令后,在Ubuntu的/home/book/nfs_rootfs目录下已经有了zImage、dtb文件,并且有lib/modules子目录(里面含有各种模块)。
下面,要把这些文件复制到开发板上。
如果你使用的是VMware桥接方式,假设Ubuntu IP为192.168.1.100,在开发板上执行以下命令:
mount -t nfs -o nolock,vers=3 192.168.1.100:/home/book/nfs_rootfs /mnt
cp /mnt/zImage /boot
cp /mnt/*.dtb /boot
cp /mnt/lib/modules /lib -rfd
最后重启开发板,它就使用新的zImage、dtb、模块了。
注意:编译驱动程序前,需要先编译内核,因为驱动程序要用到内核中的一些文件。
注意:安装驱动程序前,需要先更新内核,就是把你编译出来的zImage放到开发板上去并重启。否则安装你新编译的驱动时,内核会提示如下错误:你的驱动会污染(taint)内核,版本不匹配不允许使用某些函数。
注意:我们推荐参考《第二篇 第十章10.3编译内核镜像》编译内核,所以你要复制的是/home/book/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/zImage。
注意:如果要使用Buildroot目录中这个output/images/zImage文件时,驱动程序Makefile中要指定KERN_DIR为如下目录:
KERN_DIR = /home/book/100ask_imx6ull-sdk/Buildroot_2019.02/output/build/linux-origin_master
修改完内核所在目录后,就可以编译led模块驱动了,如下图 红框1 所示,执行 make all命令就可以编译,编译完成后会生成 100ask_led.ko ledtest 两个文件。
此时,我们可以把这两个文件拷贝到 Ubuntu nfs服务 目录下,备用:
cp 100ask_led.ko ledtest ~/nfs_rootfs
1)下载编译好的内核镜像和驱动模块到开发板
开发板启动后通过nfs挂载Ubuntu目录的方式,将相应的文件拷贝到开发板内。
如果你使用的是VMware桥接方式,假设Ubuntu IP为192.168.1.100,在开发板上执行以下命令:
[root@imx6ull:~]# mount -t nfs -o nolock,vers=3 192.168.1.100:/home/book/nfs_rootfs /mnt
[root@imx6ull:~]# cp /mnt/100ask_led.ko ./
[root@imx6ull:~]# cp /mnt/ledtest
2)关闭系统默认cpu状态灯
可能开发板上的led灯已被设置为 CPU状态灯(可以看到绿色LED在闪),我们需要将其关闭,才可以使用我们的驱动对其进行操作,关闭方法如下所示:
[root@imx6ull:~]# echo none > /sys/class/leds/cpu/trigger
我们后面出厂的开发板,已经把CPU状态灯禁止了,所以上述命令可能出错:这没影响。
3)安装驱动模块
在开发板串口终端上执行如下命令,即可安装相应的驱动模块。
[root@imx6ull:~]# insmod 100ask_led.ko
安装完成后可以执行lsmod 命令来查看是否安装成功。
执行测试程序
驱动模块安装成功后,执行先前编译好的测试程序,来控制led灯的状态,如下图所示,操作led灯时可同时观察开发板串口旁的灯是否有亮灭的变化。
[root@imx6ull:~]# chmod +x ./ledtest
[root@imx6ull:~]# ./ledtest
Usage: ./ledtest
[root@imx6ull:~]# ./ledtest /dev/100ask_led0 on //打开led0灯
[root@imx6ull:~]# ./ledtest /dev/100ask_led0 off //关闭led0灯
从Git仓库驱动源码相关文件,在Ubuntu终端上执行如下命令。
git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git
代码获取示意图如下所示。
比如设置交叉编译工具链时,要先确定Ubuntu上有这个目录:
/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
然后执行以下命令:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
1)序的编译需要在Ubuntu下进行,所以:
① 如果你是在Windows上下载源码,先用FileZilla把windows下的4_led目录上传到Ubuntu中
② 如果你是在Ubuntu下使用git命令下载源码,那就更方便了,在Ubuntu下可以直接访问源码
③ 进入Ubuntu中4_led目录
④ 最后在Ubuntu中4_led目录下执行make命令即可生成led.imx、led.img
2)把编译好的程序传回Windows
编译完成后,我们需要把相应的文件拷贝到windwos下进行烧写执行,可以使用Filezilla 工具从Ubuntu传文件到Windows,操作如下图所示:
下载完成后,我们就可以参考后面章节进行烧写测试了。
注意:建议在Ubuntu中目录名不要含空格。从git下载源码后目录名可能太长,你可以修改目录名。
注意:执行make命令后会编译程序、制作映象文件,具体过程以后介绍,这不是本章关注的内容。
参考后面《第10篇 裸机开发》里《第三章 IMX6ULL启动流程》的《 映像文件烧写、运行》。