Petalinux 入门指南:第一个Petalinux工程

#1 Petalinux BSP

参考:
homepage: https://www.xilinx.com/products/design-tools/embedded-software/petalinux-sdk.html
ug1144: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug1144-petalinux-tools-reference-guide.pdf

Petalinux 中的一个工程被称为一个BSP,BSP包含运行系统所需的所有文件,BSP的出现使得跨团队的开发变得更为便捷。自定义的Petalinux可以通过打包再交付给下一级的开发人员,使得其不需要重新配置就可以直接使用上级开发人员的产出。
Xilinx和二级开发板制造商可能会提供“参考BSP”,一个由供应商开发人员打包的完整BSP,可以做到即载即用,并且这些设计可以作为用户进行进一步开发的基础。
综上,有两种方法建立Petalinux工程:

  • 下载官方的参考BSP,并创建工程
  • 使用自行设计的硬件平台创建新的工程

#2 根据参考BSP创建工程

参考:
homepage: https://www.xilinx.com/products/design-tools/embedded-software/petalinux-sdk.html
ug977: https://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug977-petalinux-getting-started.pdf

你只需找到对应开发板的参考BSP包,下载载入即可。参考BSP已经预先编译好了系统和Demo,无需用户再次编译,可以直接下载至开发板或会使用QEMU进行模拟。
首先请手动创建预期的工程目录,并将工作路径切换至目录中,随后加载Petalinux环境变量,然后根据BSP创建新的工程:

1
$ petalinux-create -t project -s /path/to/your/bspfile.bsp -n custom-project-name

请修改命令中的BSP文件路径至实际的路径。

随后可以尝试在QEMU虚拟机中启动预编译的系统镜像:

1
$ petalinux-boot --qemu --kernel

如果一切正常,你应该可以看见u-boot和kernel启动过程中的log输出,直至最后停留在登陆命令处,可以使用root账户(默认密码为”root”)登入。


#3 根据自定义硬件平台创建工程

参考:
ug1144: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug1144-petalinux-tools-reference-guide.pdf

对于绝大多数的非官方参考开发板,都需要根据设计好的硬件平台手动创建工程。

#3.1 获取硬件平台设计文件

首先,你需要在Vivado中进行硬件设计,为了让Linux可以正常在zynq芯片的arm核上运行,你需要分配一定的硬件资源。根据ug1144,对于使用Petalinux的参考Linux,需要提供以下的资源:

  • TTC模块,作为系统时钟
  • 至少32MiB存储空间
  • UART模块(可选)用于输出控制台
  • NV存储器(可选)
  • 以太网接口(可选)

如果要使用Microblaze等其他处理器,请参考ug1144。

在Vivado中启用并预留好相应的硬件资源、设计实现PL部分,进行综合,实现,使用“Export Hardware”功能导出Petalinux需要的硬件平台设计文件,包括用于描述硬件配置的xsa文件和保存比特流的bit文件。

#3.2 创建Petalinux工程

将需要文件拷贝至期望的新Petalinux工程目录下,对于zynq芯片平台,执行如下命令:

1
$ petalinux-create --type project --template zynq --name custom-project-name

你应该可以在终端上看到成功创建工程的输出信息,若是其余硬件平台请修改”template”参数。

随后需要载入之前导出的硬件设计文件,使用如下命令,Petalinux会自动在当前目录中寻找可用的硬件设计文件:

1
$ petalinux-config --get-hw-description

因为是新的工程,Petalinux会自动进入配置界面,在里面我们可以配置一些系统参数,主要的配置包括:启动方式,启动存储器分区表,启动文件名称等等。请根据硬件平台的设计选择对应的u-boot和kernel启动方式,如果希望使用QEMU虚拟机进行仿真则无需修改启动选项,QEMU虚拟机将直接读取kernel镜像。
退出至配置根目录,使用左右方向键移动下方功能光标,选择“Save”保存配置文件,之后退出配置界面,Petalinux会自动根据配置文件配置当前工程。
配置过程需要进行文件复制,所需时间从10分钟至半小时不等,配置过程中不需要进行人工确认。

如果你需要配置kernel,比如加入硬件支持或者进行内核裁剪,请使用如下命令打开kernel配置界面:

1
$ petalinux-config -c kernel

与正常的kernel配置界面并无区别(实际上就是调用了menuconfig)。

此外,还有如下配置可以进行:

1
2
3
4
5
$ petalinux-config -c u-boot
#配置u-boot

$ petalinux-config -c rootfs
#配置rootfs

#3.3 设备树配置

Petalinux能够根据硬件描述文件自动地把IP外设添加至设备树中,但是对于其他的非IP外设则需要手动修改设备树以告知系统该硬件的存在。
设备树文件的目录为:./subsystems/linux/configs/device-tree
具体方法与常规的ARM Linux设备树修改无异,这里就不再赘述。

修改设备树后,可以使用如下命令编译设备树文件,而不进行全局编译:

1
$ petalinux-build -c device-tree

#3.4 编译

请确保电脑的供电稳定,能够顺利访问境外服务器,磁盘上有至少20GiB的剩余空间,以及4GiB的空闲内存

在工程目录下,执行如下命令:

1
$ petalinux-build

Petalinux将编译u-boot,kernel以及rootfs,编译过程可能需要联网下载文件,总耗时取决于电脑配置和境外网速,从30分钟至4小时不等。

自然,你可单独编译这三个部分,具体命令如下:

1
2
3
4
5
$ petalinux-build -c u-boot

$ petalinux-build -c kernel

$ petalinux-build -c rootfs

编译完成后的镜像文件位于:./images/linux
其中四个文件在接下来会被用到,

  • zynq_fsbl.elf (zynq引导文件)
  • image.ub (Linux系统镜像)
  • u-boot.elf (u-boot引导文件)
  • your-bitstream.bit (比特流文件)

这里可以顺便一提,zynq使用三阶段引导,分别是

  • rom boot loader,固化在rom中
  • fsbl,用于加载bitstream并启动下一阶段引导
  • u-boot或其他boot loader,负责arm核的初始化和系统镜像的引导。

#4 打包制作BOOT.BIN文件

参考:
ug1144: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug1144-petalinux-tools-reference-guide.pdf

BOOT.BIN文件为zynq系列芯片的启动引导的标准名称,包含fsbl、uboot和比特流文件,使用sd卡或者u盘或者其他外部存储进行启动时,都需要先将引导打包成BOOT.BIN文件。

在Petalinux工程目录下,执行如下命令进行打包:

1
$ petalinux-package --boot --fsbl zynq_fsbl.elf --fpga your-bitstream.bit --u-boot u-boot.elf

请根据实际情况,修改比特流文件的名称。


#5 启动系统

参考:
ug1144: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug1144-petalinux-tools-reference-guide.pdf
ug982: https://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug982-petalinux-system-simulation.pdf

#5.1 从QEMU启动系统

QEMU虚拟机可以直接加载系统镜像,而不需要其他引导,具体命令如下:

1
$ petalinux-boot --qemu --kernel

root账户的默认密码为 root

如果想退出虚拟机,请按下 Ctrl+a*,然后按下 *x

#5.2 从jtag启动系统

连接至开发板串口,并将波特率设置为115200以正确读取输出,执行如下命令启动系:

1
$ petalinux-boot --jtag --prebuilt 3

–prebuilt 3 意味着linux kernel。
root账户的默认密码为 root

如果只需要将程序下载至开发板而不进行启动,可以执行如下命令:

1
2
3
$ petalinux-boot --jtag --fpga --bitstream <BITSTREAM>
$ petalinux-boot --jtag --u-boot
$ petalinux-boot --jtag --kernel

遇到问题请优先考虑ug1144,善用目录和查找功能。

Petalinux 入门指南:Petalinux的介绍与安装

#1 序

Xilinx的文档一向以“烂”著称,而Petalinux有关的文档则是集大成者,如果你发现某处出现了magic command,那很可能只是在某文档的小字里面淡淡描述过。
该文章系列一共有三部分,分别是Petalinux的介绍与安装,你的第一个Petalinux工程,以及Petalinux的应用开发,有关IP核的开发和设备树等涉及硬件的开发这个系列不涉及,不过可能有番外篇来讲述一下QEMU的网络配置。如果安装过程中出现某些奇怪的报错内容,还请google一下。
考虑到Xilinx的服务器全部位于海外,如果你正在看着这篇文章,并试图去跟着完成Petalinux的开发,那么请现在就去开始下载。注意,下载与你所使用的硬件开发工具(如Vivado)大版本号相同的Petalinux
Petalinux本身并不复杂,许多功能也不magic,只是你不知道,Xilinx也不告诉你,我会试图分析并解释这些功能。考虑到部分内容也只是我的经验之谈,如有错误还请指正。


#2 Petalinux 101

参考:
homepage: https://www.xilinx.com/products/design-tools/embedded-software/petalinux-sdk.html
ug1144: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug1144-petalinux-tools-reference-guide.pdf

按照较为商业的说法,Petalinux是一个“解决方案”,而非Linux发行版,Petalinux为用户提供从定制内核和rootfs,编译内核和rootfs以及打包启动镜像并部署至开发板的全套功能。同时为了提升效率,Petalinux可以与类似Vivado之类的“Xilinx 硬件开发工具”配合使用,比如可以导入Vivado导出的硬件描述文件和bitstream文件构建一个PS+PL的项目。
Petalinux是随着zynq等arm+fpga这类组合芯片的出现而诞生的,解决了在这类arm+fpga芯片上移植linux等等琐事。如果不使用Petalinux,用户需要手动编译kernel和u-boot,然后将编译得到的镜像在Vivado等工具中,与FSBL、bitstream手动打包成启动镜像,然后拷贝至sd卡进行启动,Petalinux则将这所有工作集中到一套sdk中,同时提供独立的qemu虚拟机便于测试应用程序能否在fpga板上正确运行。

Petalinux本身主要由两大部分组成:

  • 一个配置、编译、开发工具包 (PetaLinux Tools)
  • 一个Xilinx开发的Linux发行版 (Reference Linux Distribution)

接下来我们一一介绍这两个部分。

PetaLinux Tools (host)

Petalinux Tools是一个大的“软件合集”,包括如Petalinux的cli,应用、驱动的模板,系统镜像打包工具,QEMU模拟器以及GCC工具链等等工具,提供从创建文件夹到在开发板运行系统的一条龙服务。
开发人员可以使用这些工具来自定义引导加载程序,Linux内核或Linux应用程序。他们可以通过QEMU进行仿真,或网络和JTAG在物理硬件上运行系统内核,添加设备驱动程序,应用程序,库以及启动和测试软件。
根据其功能,这些工具主要被分为三类,分别是:

  • 自定义板机支持包生成工具:
    可以通过“Xilinx 硬件开发工具”导出的文件自动生成一个定制的Linux Board Support Package,其中包括内核和引导加载程序的配置,以及IP核驱动程序。
  • Linux配置工具:
    用于自定义引导加载程序,Linux内核,文件系统,库和系统参数的工具。与普通kernel的配置工具不同,这些配置工具将“完全知晓Xilinx硬件开发工具,并且可以读取自定义硬件有关的文件”。
    换句话说,这些工具能够配置一些fpga特有的功能,同时可以读取你开发的PL部分(如IP,或者什么其他的Verilog代码),并进行正确的配置(如获取正确的GPIO寄存器地址)。
  • 软件开发工具:
    用于开发驱动程序、应用程序以及函数库。能够创建相应的工程模板,并能够编译、打包和分发软件组件(software components),使开发人员不需要过多关心编译相关的底层问题,并能够轻松的在开发板上安装和使用自己开发的程序。

Reference Linux Distribution

PetaLinux提供一个完整的参考Linux发行版,该发行版已针对Xilinx的FPGA设备进行了集成和测试。
这个发行版包含以下内容:

  • Boot loader
  • 优化过的kernel
  • 基本的Linux软件和运行库
  • Debug工具
  • 对多线程和FPU计算的支持
  • 集成式web服务器

当然,你可以使用其他的Linux发行版作为rootfs,比如ubuntu minimal等等,但是一般来说使用Petalinux自带的参考Linux发行版就足够了。

自此,我们完整的介绍了Petalinux,所以Petalinux是什么?工具包+Linux发行版。


#3 安装Petalinux

参考:
ug976: https://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug976-petalinux-installation.pdf

大体上用户只需要执行安装包即可,但是Petalinux的安装脚本仅仅适配了REHL系发行版,这意味在其他发行版可能存在环境问题,需要我们手动配置环境。
注意:请确保安装Petalinux的磁盘有至少50GiB的空闲容量,推荐至少有100GiB的空闲容量

step 1 下载安装包

考虑到Petalinux的“安装包”实际上是一个“脚本”,并且在安装过程中需要进行解压操作,如果压缩部分出现少量错误,极有可能耗费数个小时但无功而返,因此请务必在下载完成后检查下载文件的hash值是否一致,若不一致还请重新下载。
此外,请尽可能保证Petalinux和硬件开发工具的大版本号一致(如”2019.2”中的”2019”),以确保硬件描述文件等等是通用、可接受的。

step 2 配置运行环境

参见ug976 11页表格,请根据你的发行版安装所需要的软件包。
如果你使用的是Debian/Ubuntu发行版,那么可以尝试以下指令:

1
sudo apt install tofrodos iproute gawk make net-tools libncurses5-dev tftpd zlib1g:i386 libssl-dev flex bison libselinux1 gnupg wget diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential screen pax gzip

如果报错,请查看报错的软件包是否因为版本更新而改用其他名称

step 3 安装

执行petalinux-vxxxx.xx-final-installer.run,即你下载的安装包,它会默认安装至当前工作目录,即你执行安装包的目录。

  1. 安装过程需要解压缩,安装总耗时取决于磁盘性能,从半小时到数小时不等。
  2. 安装中途需要进行数次手动确认,因此请时不时看一下安装进度。
  3. 如果提示“tftp server”未运行,请暂时忽视,这并不会影响Petalinux的安装。
  4. 使用systemctl或者init.d启动tftp server即可,可能需要手动创建tftp用于收发文件的目录,根据错误提示手动创建目录即可。
  5. 运行安装包请勿使用root权限,如果报出权限错误,请检查该安装包是否未被赋予可执行权限

step 4 验证安装

安装完成后,进入安装目录
如果你是bash/zsh用户,请source setting.sh:

1
$ source ./setting.sh

如果你还仍然坚持使用c shell,请source setting.csh:

1
$ source ./setting.csh

你应该在终端上看见类似如下所示的输出:

1
2
3
4
5
6
PetaLinux environment set to ’/opt/petalinux-v2019.1-final’
INFO: Finalising PetaLinux installation
INFO: Checking free disk space
INFO: Checking installed tools
INFO: Checking installed development libraries
INFO: Checking network and other services

随后,请检查工作目录环境变量是否配置正确:

1
2
$ echo $PETALINUX
/opt/petalinux-v2019.1-final

该环境变量的值应该指向Petalinux的安装目录。

Arch Linux Installation

ddl是检验生产力的唯一标准

本次的安装是在VBox虚拟机环境下进行,物理机可能会有所出入,一切还请以Arch Linux官方wiki为准。


安装准备

安装介质

  1. https://www.archlinux.org/download/ 页面下载最新的iso镜像文件;
  2. 使用dd(linux下)或者rufus(Windows下)制造安装介质。

磁盘准备

至少10GB的空闲空间,如果想日常使用,则建议至少50GB,否则连大的开发环境都不便于配置。

BIOS设置

在BIOS中将启动项设置我们制作的安装u盘,对于虚拟机安装而言,则为将启动项设为加载了镜像文件的虚拟光驱。


安装过程

进入 Live CD 系统

  1. 做好安装准备后,启动便会看到如下界面:
    select
  2. 选择第一项进入 Live CD 系统,屏幕显示如下内容:
    loading
    加载完成后,将进入一有命令提示符的界面:
    done
    这时便成功启动了 Live CD 系统,接下来将 Arch Linux 安装到硬盘上

联网

Arch的安装需要通过互联网来下载组件,故在开始正式的安装前我们要先联网。

  • 如果为有线网,并且路由器开启DHCP服务的话,则执行:
    1
    dhcpcd
  • 如果为无线网。则执行:
    1
    wifi-menu
    这是一个命令行下的wifi管理工具,有字符形式的图形界面。
  • 使用类似以下的命令来检测网络是否连接:
    1
    ping www.baidu.com
  • 对于部分机器,可能存在无线网卡驱动兼容性问题,但是有线网一般是可以使用的,可以插网线装好系统后再慢慢解决驱动问题。

更新系统时间

执行以下命令以启用ntp服务来自动同步系统时间:

1
timedatectl set-ntp true

分区与格式化

首先检测现有的分区表,执行以下命令:

1
fdisk -l

可得到如下输出:
fdisk
可以看到在这块硬盘上没有分区表的存在。

考虑到虚拟机采用BIOS/MBR的引导方式,故我们使用MBR分区表以便于操作。

  1. 输入命令:
    1
    cfdisk /dev/sdx (将sdx替换之前看到的磁盘)
  2. 选择“dos”分区方式
    dospar
    这样我们便在磁盘上创建了一个MBR分区表,当然所有的修改在确认写入前都是没有改动实际的磁盘数据的。
    随后便会看到以下界面:
    cfdisk
    可以再次看到,这块磁盘上没有分区存在。
  3. 使用上下左右键来移动下面的光标,选择“NEW”来新建一个分区。
    我们新建一个占据全部空间的“Linux File System”类型的主分区,注意是主分区,即primal partition,对于MBR分区表,只有主分区是可以作为启动引导分区的。随后再次移动光标,选择下方的“Bootable”,将该分区设置为可引导分区。最终效果如图:
    cfdisk
  4. 确认无误后,移动光标选择“Write”,将我们所有的改动写入到实际的磁盘上,一旦执行了这步之后就回不了头了,所以需要多次确认后再执行,我们这次是一个空硬盘,所以怎么折腾都是可以的。最终退出该程序,分区结果如下图所示:
    parares
  5. 输入以下命令来格式化刚刚创建的分区:
    1
    mkfs.ext4 /dev/sdxY (将sdxY替换为刚刚创建的分区)

    挂载分区

    执行以下命令来挂载将刚刚创建的分区挂载:
    1
    mount /dev/sdxY /mnt (将sdxY替换为刚刚创建的分区)

    安装基本软件包

    接下来要开始字面意义上的安装过程了,将要把Archlinux安装到磁盘上,注意,这个过程需要保持互联网的接入。
    执行以下命令开始安装:
    1
    pacstrap /mnt base base-devel
    命令提示行出现以下画面,等待安装结束、命令提示符重新出现即可进行下一步。
    insa

生成fstab

安装过程中我们是手动挂载了根目录,但是不可能每次开机都进行一次挂载操作,因此我们需要生成自动挂载分区的fstab文件。
执行以下命令:

1
genfstab -L /mnt >> /mnt/etc/fstab

使用cat命令将该文件输出到屏幕,如下图所示:
fstab
可以看到 /dev/sda1被挂载到根目录。

chroot

到这一步,我们需要把操作权交给我们刚刚安装到磁盘上的操作系统,执行这步后,所以的操作都是在新装的系统进行的。
执行以下命令:

1
arch-chroot /mnt

设置时区

依次执行以下命令:

1
2
ln -sf /usr/share/zoneinfo/Asis/Shanghai /etc/localtime
hwclocl --systohc

如下图所示:
zone

安装必要的软件包

通过 pacman 安装vim,等接下来需要使用的软件包。
执行以下命令:

1
pacman -S vim

设置语言数据

  1. 首先使用vim打开 /etc/locale.gen 文件,并将zh_CN.UTF-8 UTF-8、zh_HK.UTF-8 UTF-8、zh_TW.UTF-8 UTF-8、en_US.UTF-8 UTF-8四行前的注释符号去除,然后保存退出。如下图所示:
    locale
    然后执行:
    1
    locale-gen
  2. 配置语言首选项
    使用vim打开/etc/locale.conf文件
    在文件第一行输入:
    1
    LANG=en_US.UTF-8
    然后保存退出。

设置主机名

  1. 使用vim打开/etc/hostname文件,在第一行输入你想要的主机名,保存并退出。
  2. 使用vim打开/etc/hosts文件,在文件末尾添加如下三行:
    1
    2
    3
    127.0.0.1 localhost
    ::1 localhost
    127.0.1.1 yourhostname (替换为你之前设定的主机名)
    保存并退出。

安装intel-ucode

对于intel CPU,使用pacman安装:

1
pacman -S intel-ucode

安装bootloader

我们使用grub作为bootloader:

  1. 安装grub包:
    1
    pacman -S grub
  2. 部署grub到引导扇区:
    1
    grub-install --target=i386-pc /dev/sdx (将sdx替换之前看到的磁盘)
  3. 生成grub配置文件:
    1
    grub-mkconfig -o /boot/grub/grub.cfg
    bootlo
    至此Bootloader的安装便结束了,建议安装后检查grub.cfg文件的生成是否正确,至于如何读懂该文件,可以参照Archlinux官方wiki。

修改root密码

执行以下命令:

1
passwd

依照提示设置密码,注意密码输入无回显。

重启

接下来到了最为激动人心的环节,之前的所有努力与付出都将在此时得到检验,成败再次一举。
执行如下命令:

1
2
exit
reboot

如果是物理机,则在关机后拔出u盘,如果是虚拟机,则将虚拟光驱弹出即可。
如果一切顺利,你将看到如下画面,并可以使用root用户进行登陆:
finish1

配置虚拟内存

我们采用文件形式的交换空间,便于我们的管理。
先分配一块空间(512M大小为例):

1
fallocate -l 512M /swapfile

然后更改该空间的权限:

1
chmod 600 /swapfile

设置为交换文件:

1
mkswap /swapfile

启用交换文件:

1
swapon /swapfile

swapset
最后还需要修改fstab文件来实现自动启用交换文件,如下图所示进行修改:
swapfstab

新建用户

我们的日常操作不可能以root用户的身份进行,这样是极不安全的。因此我们新建一个权限较低的用户日常使用。

1
useradd -m -G wheel username

我们新建了一个名为username的用户,并将它加入了wheel组,同时也为它在/home目录下新建了同名的家目录。

配置sudo

首先使用pacman安装sudo软件包:

1
pacman -S sudo

当然,在使用pacman之前,你需要先连接网络,具体操作与 Live CD 系统的操作一致。
然后使用visudo编辑sudo的配置文件:

1
# %wheel ALL=(ALL) ALL

前的注释去除,退出保存即可。
visudo
配置好sudo以后,我们再次重启电脑,并且以新建的用户登陆系统,并且记得需要重新进行联网操作。

安装图形化界面

我使用了xfce作为本次安装的桌面管理器,其他桌面的安装大同小异。
直接使用pacman安装图形界面和桌面的软件包:

1
sudo pacman -S xorg xfce sddm

同时我们需要安装桌面使用的网络连接管理软件networkmanager:

1
sudo pacman -S networkmanager

随后安装完毕后,我们需要启用我们刚刚安装的sddm桌面管理器,以方便我们在开机后进行登陆并选择使用的桌面。
使用systemctl来管理系统服务:

1
sudo systemctl enable sddm

同时我们需要提前配置网络,将自带的netctl换为networkmanager:

1
2
sudo systemctl disable netctl
sudo systemctl enable NetworkManger

然后重启,如果一切顺利,你将成功看到桌面管理器界面,输入用户名和密码后便可以进入桌面环境。
desktop

最后

依照惯例:
res

使用 Travis CI 自动部署 HEXO 博客到 GitHub

本来只是想给博客换个主题(旧的主题引用的某个js源炸了,懒得改代码,于是决定重新换个主题),但是翻着翻着就发现了个叫 Tarvis CI 的好玩的网站,(突然感觉自己弱爆了,以前居然连这种东西都不知道),于是打算折腾一通,试一试感觉如何。最终的结论是,效率提升≈0,逼格提升≈1000000(穷人,只有一台电脑,不存在环境问题)。

无论如何,写篇博客记录一下吧(理论上这篇博客也是 Tarvis CI 托管生成的)。

准备阶段

Tarvis

你要用 Tarvis ,好歹得有个账号吧,所幸 Tarvis 和 GitHub 关系比较暧昧特殊,可以直接用GitHub账号登陆;(请猛击那个Sign in with GayHub)
Login
之后就需要选择自动生成哪些repo;
repo
在Tarvis的操作目前到此为止,但我们之后还是要回来的。


GitHub

仓库:

首先先把博客的 repo clone 到本地来,然后签出一个新的分支(叫 dev 还是什么其他看个人兴趣,我的叫 hexo ,这个就不放图了啊),这个分支用于保存博客的 raw 文件,渲染之后再将其push到master分支,这样的话不需要新开一个 repo 。

然后,重头戏,把这个 branch 里的文件给删!光!光!然后再把本地用于生成博客的文件拷贝进来,然后push(别忘记创建远程分支)。

之后就应该是这样

branch

  • master分支用于存放 渲染完的博客网页文件
  • hexo分支用于存放 用于渲染博客的文件

密钥:

然后我们还需要一个让 Tarvis 的服务器能够向我们在 GitHub 上 Push 代码的凭证。但是问题在于,我们博客的仓库是开源的,如果将密钥或是其他的什么直接明文存储,呵呵。。。

所以我们需要一个加密存储的方式,Tarvis 上可用的有两种:

  • 使用 ssh key
  • 使用 Tarvis 的环境变量来存储 GitHub Token

我这里选择了第二种(一般来说第一种安全些,各位可以从网上参照一下)。

在个人设置里面,

setting

新建一个新的个人 token ,

token
token1

token 需要给予 repo 的控制权限,记得在创建完成后复制生成的 token ,之后是无法查询到这个 token 的数值的。

token2

然后我们需要重新回到 Tarvis , 点击你激活的那个 repo 左边的齿轮图标进入设置界面,将我们刚刚拿到的 token 设置为环境变量。

env_token

至此,准备工作彻底完毕,接下来就要开始掉头发码代码了。

具体配置

“.travis.yml”

请在当前本地仓库的 hexo 分支根目录下创建如章节名称的文件(注意以 “.” 开头),然后用代码编辑器打开这个文件(废话),关于这个文件的编写可以参照这篇博客:持续集成服务 Travis CI 教程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 选择使用的语言
language: node_js
node_js: stable

sudo: false

# 为了提速,我们在这里使用缓存来把node的package都保存下来
cache:
directories:
- "node_modules"

# Tarvis 给你发提醒的配置
notifications:
# 我们选择使用邮件
email:
recipients:
# 你的邮件地址
- youremail@xxx.com
# 是否在成功时发生邮件
on_success: never
# 是否在失败时发送邮件
on_failure: always

# S: Build Lifecycle
install:
- npm install

before_script:
- export TZ='Asia/Shanghai'
- chmod +x _travis.sh

# hexo标准操作,注意没有"hexo d",即不进行部署
script:
- hexo clean && hexo g

after_success:

# 没有这个文件?有才见了鬼,这个文件我们待会手写!
after_script:
- ./_travis.sh

# E: Build LifeCycle

# 选择进行操作的分支,即 Tarvis 需要监测和处理的分支,也可以使用黑白名单,用法请自行Google
branches:
only:
- hexo

# 设置环境变量,注意这里的环境变量是没有加密的
env:
global:
# 你的GitHub地址
- GH_REF: github.com/milkybird98/milkybird98.github.io.git

博主本人也是自行摸索+借鉴,有可能在设置上存在问题,还请指出(可以在GitHub上留个issue之类的)。


“_travis.sh”

在 “.tarvis.yml” 里面我们没有执行 “hexo d” 命令,因为我们需要手动部署。(这一段是直接使用的shenliyang大大的代码,在此感谢shenliyang大大)

Ps. 貌似可以用 hexo 的 deploy,各位可以去研究一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#--------------------------------------------
# !/bin/bash
# author:shenliyang
# website:https://github.com/shenliyang
# slogan:梦想还是要有的,万一实现了呢。
#--------------------------------------------

#定义时间
time=`date +%Y-%m-%d\ %H:%M:%S`

#执行成功
function success(){
echo "success"
}

#执行失败
function failure(){
echo "failure"
}

#默认执行
function default(){

git clone https://${GH_REF} .deploy_git
cd .deploy_git

git checkout master
cd ../

mv .deploy_git/.git/ ./public/
cd ./public

cat <<EOF >> README.md
部署状态 | 集成结果 | 参考值
---|---|---
完成时间 | $time | yyyy-mm-dd hh:mm:ss
部署环境 | $TRAVIS_OS_NAME + $TRAVIS_NODE_VERSION | window \| linux + stable
部署类型 | $TRAVIS_EVENT_TYPE | push \| pull_request \| api \| cron
启用Sudo | $TRAVIS_SUDO | false \| true
仓库地址 | $TRAVIS_REPO_SLUG | owner_name/repo_name
提交分支 | $TRAVIS_COMMIT | hash 16位
提交信息 | $TRAVIS_COMMIT_MESSAGE |
Job ID | $TRAVIS_JOB_ID |
Job NUM | $TRAVIS_JOB_NUMBER |
EOF

git init
# 输入你自己的GitHub的name和email
git config user.name "milkybird98"
git config user.email "milkybird98@outlook.com"
git add .
git commit -m "Build by Travis CI"
# ${GH_TOKEN}替换为你设定的 token 的环境变量名称${xxxx},${GH_REF}是在上一节中设定的
git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master
}

case $1 in
"success")
success
;;
"failure")
failure
;;
*)
default
esac

至此,文件上的处理就完成了,现在只需要把 hexo 分支的代码 push 一次, Tarvis CI那边检测到 request 后就会自动去进行处理。


  • 问题:如果你出现了 build 成功但是博客打开后却是一片白,或者远程仓库里主题文件夹一片空白(一般情况是连theme文件夹都没有);
  • 解决:使用如下指令而非clone,将主题的仓库作为子模块使用,或者直接将主题的仓库变为普通的本地代码。
1
git add submodule git://github.com/xxxxxxxxxx/xxxxxxxx.git theme/${你的主题名称}/
  • 问题:build 成功但是仓库的 master 分支没有变化;
  • 解决:请确定你输入的 token 是否正确(其实根本没法确认,删掉旧的再申请个新的吧),以及权限是否正确。

Tips

可以将主题 fork 一份,然后使用子模块的方式将主题加载自己的博客仓库中,并且在”.tarvis.yml”中”hexo clean & hexo g”之前的加入如下指(貌似不加也可以,git 执行 “git clone” 应该是会同时下载子模块的)。

1
2
3
- git submodule init
- git submodule update
- hexo clean & hexo g

这个小绿标是不是很诱人,加上去其实很简单:

little_green

首先让我们再次回到 Tarvis CI
点一下这个灰色的按钮(不用管这个的颜色,因为我们的master分支是不进行托管的,所以是灰色的);

grey_little

然后在弹出框中选择你进行处理和分支,语言选择Markdown;

bounce_little

复制最后的地址,将其粘贴到”_travis.sh”文件中生成README.MD的代码处,同时你也可以做一些修改,比如这是我的README.MD:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat <<EOF >> README.md
# Milkybird98 唯一指定blog。

Stella Splendida.

[![Build Status](https://travis-ci.org/milkybird98/milkybird98.github.io.svg?branch=hexo)](https://travis-ci.org/milkybird98/milkybird98.github.io)

部署状态 | 集成结果 | 参考值
---|---|---
完成时间 | $time | yyyy-mm-dd hh:mm:ss
部署环境 | $TRAVIS_OS_NAME + $TRAVIS_NODE_VERSION | window \| linux + stable
部署类型 | $TRAVIS_EVENT_TYPE | push \| pull_request \| api \| cron
启用Sudo | $TRAVIS_SUDO | false \| true
仓库地址 | $TRAVIS_REPO_SLUG | owner_name/repo_name
提交分支 | $TRAVIS_COMMIT | hash 16位
提交信息 | $TRAVIS_COMMIT_MESSAGE |
Job ID | $TRAVIS_JOB_ID |
Job NUM | $TRAVIS_JOB_NUMBER |
EOF

结语

感觉根本没啥卵用啊,只不过是从

1
2
3
hexo clean
hexo g
hexo d

变成了

1
2
3
git add .
git commit -am "xxx"
git push

到头来还是三个指令(哭唧唧)。

STM32驱动LCD屏幕

本文中使用的LCD驱动芯片为ili9341,下文中简称为驱动芯片。
官方的PDF就不摆上来了,自己去这找找就行了Google

配置

  • MCU为STM32F103ZE,主频72Mhz,使用Spi与驱动芯片通讯,Spi时钟频率为18Mhz。
  • 鉴于驱动芯片可以设定显示窗口(即改写选定部分的显存数据,如将窗口设定为x=20;y=30;宽=50;高=70),可以使用DMA来提高数据传输效率,尤其是在显示文字的过程中,可以直接将文字对于的点阵转换为一个n*n的图片,再一次性的发送给驱动芯片。
  • 但是使用时需要注意检测前一次的DMA发送是否已经完成,否则会出现数据传输不完整的错误。
  • 使用PB1,2引脚作为驱动芯片的DC引脚和RST引脚。

底层IO函数

  • 驱动芯片在写入寄存器时不再明显的区分指令寄存器和显存寄存器,写入指令不在是“索引+对于寄存器的数据”,而改为“指令+[参数/数据]”的格式,简而言之,无论是修改设置还是发送图像数据,其实都是一条指令以及相应的数据。
  • 在发送指令时,先应将DC脚拉低,在通过Spi发送两个字节的数据,随后将RS脚拉高即可。
  • 发送数据较为简单,在指定寄存器索引后直接在Spi上传出数据即可。
  • 同时应注意到,有些指令是没有数据的,如“开始显示画面”,有些指令的数据量则十分巨大,如“写入显存”,这也是“索引+数据”和“指令+[参数/数据]”模式最大的区别,即后者发送的指令本身的功能就不仅仅只是指定寄存器,亦可以修改某些数据。
  • 如果需要硬重启需要将RST引脚从高电位拉低,再拉高,同时应当适当加入延时。

发送指令

1
2
3
4
5
void writeCommand(uint8_t cmd){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,&cmd,1,2);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
}

发送数据

1
2
3
void spiWrite(uint8_t data){
HAL_SPI_Transmit(&hspi1,&data,1,2);
}

重启

1
2
3
4
5
6
7
8
void lcdRestart(void){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);
HAL_Delay(200);
}

初始化

初始化过程参见PDF,主要包括电源控制,内存访问控制和屏幕刷新相关设置的初始化(暂时先鸽了),其中伽马矫正部分需LCD屏幕供应者提供相应的参数(或者随便输一点)。


初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
writeCommand(0xEF);
spiWrite(0x03);
spiWrite(0x80);
spiWrite(0x02);

writeCommand(0xCF);
spiWrite(0x00);
spiWrite(0XC1);
spiWrite(0X30);

writeCommand(0xED);
spiWrite(0x64);
spiWrite(0x03);
spiWrite(0X12);
spiWrite(0X81);

writeCommand(0xE8);
spiWrite(0x85);
spiWrite(0x00);
spiWrite(0x78);

writeCommand(0xCB);
spiWrite(0x39);
spiWrite(0x2C);
spiWrite(0x00);
spiWrite(0x34);
spiWrite(0x02);

writeCommand(0xF7);
spiWrite(0x20);

writeCommand(0xEA);
spiWrite(0x00);
spiWrite(0x00);

writeCommand(ILI9341_PWCTR1); //Power control
spiWrite(0x23); //VRH[5:0]

writeCommand(ILI9341_PWCTR2); //Power control
spiWrite(0x10); //SAP[2:0];BT[3:0]

writeCommand(ILI9341_VMCTR1); //VCM control
spiWrite(0x3e);
spiWrite(0x28);

writeCommand(ILI9341_VMCTR2); //VCM control2
spiWrite(0x86);

writeCommand(ILI9341_MADCTL); //Memory Access Control
spiWrite(0x48);

writeCommand(ILI9341_VSCRSADD); //Vertical scroll
spiWrite(0x00);
spiWrite(0x00); //Zero

writeCommand(ILI9341_PIXFMT);
spiWrite(0x55);

writeCommand(ILI9341_FRMCTR1);
spiWrite(0x00);
spiWrite(0x18);

writeCommand(ILI9341_DFUNCTR); //Display Function Control
spiWrite(0x08);
spiWrite(0x82);
spiWrite(0x27);

writeCommand(0xF2); //3Gamma Function Disable
spiWrite(0x00);

writeCommand(ILI9341_GAMMASET); //Gamma curve selected
spiWrite(0x01);

writeCommand(ILI9341_GMCTRP1); //Set Gamma
spiWrite(0x0F);
spiWrite(0x31);
spiWrite(0x2B);
spiWrite(0x0C);
spiWrite(0x0E);
spiWrite(0x08);
spiWrite(0x4E);
spiWrite(0xF1);
spiWrite(0x37);
spiWrite(0x07);
spiWrite(0x10);
spiWrite(0x03);
spiWrite(0x0E);
spiWrite(0x09);
spiWrite(0x00);

writeCommand(ILI9341_GMCTRN1); //Set Gamma
spiWrite(0x00);
spiWrite(0x0E);
spiWrite(0x14);
spiWrite(0x03);
spiWrite(0x11);
spiWrite(0x07);
spiWrite(0x31);
spiWrite(0xC1);
spiWrite(0x48);
spiWrite(0x08);
spiWrite(0x0F);
spiWrite(0x0C);
spiWrite(0x31);
spiWrite(0x36);
spiWrite(0x0F);

writeCommand(ILI9341_SLPOUT); //Exit Sleep
HAL_Delay(120);
writeCommand(ILI9341_DISPON); //Display on
HAL_Delay(120);

To be continued.

简易debug手册

Debug手册

ddl是检验真理的唯一标准

单片机方面

1.外部设变传输速率不够排查项目:

  • 本地缓存加载速度
  • 缓存发送逻辑
  • 传输时钟频率
  • 传输信号质量
  • 电源稳定性
  • 接受端芯片时钟频率

2.硬件错误排查项目:

  • 栈内存分配是否冲足
  • 指针是否正常(是否有野指针问题)
  • 可以单步调试,查看出错前的PC寄存器

3.sdio错误排查项目

  • sdio外设时钟频率是否过快
  • SD卡槽是否接触不良,信号质量是否不好
  • SD卡初始化是否正常进行(断电再上电)

4.fatfs问题排查

  • 目录不带最后一个’/‘
  • 未开启长文件名模式时的文件名长度限制
  • 目录/文件名字符串结尾处的空字符是否存在