Firefly开源社区

LabVIEW LINX工具包开发RK3308 Plus教程

38

积分

0

威望

0

贡献

技术小白

积分
38
发表于 2021-3-30 13:16:56     
本帖最后由 zzl88824 于 2021-4-15 14:59 编辑

一、固件编译和和烧写
http://wiki.t-firefly.com/zh_CN/Core-3308Y/sdkbuilding.html
Firefly的官网上提供了固件编译的教程,地址如上。但是官方教程目前只提供了Buildroot的编译方法,并没有提供Ubuntu或者Debian的编译方法,经过摸索,我找到了自行编译Ubuntu系统的方法,经过测试可以正常使用。
在正式开始编译固件之前,需要做的准备工作有:
下载RK驱动助手;
下载AndroidTool;
下载adb工具;
下载官方ROC-RK3308B-CC-PLUSUbuntu Public 固件;
下载RK3308BLinux SDK;
以上资源均可在官网上下载到,地址是:
编译的流程是:首先利用AndrodTool工具的解包功能,将官方的Ubuntu固件解包,解包后会生成boot.img、MiniLoaderAll.bin、parameter.txt、rootfs.img、trust.img和uboot.img六个文件,如果我们需要修改串口等外设的启用禁用状态,就需要重新编译boot.img文件,然后替换官方固件解包出来的boot.img内核文件,最后再利用官方提供的Windows平台下的打包工具重新打包即可。
1.1内核的编译方法
1)在PC上创建一台Ubuntu16.04的虚拟机,64位系统,硬盘不小于40G,内存不小于2G。
2)安装编译Kernel和U-Boot所需要的软件包和必要的的工具
sudo apt-get update
sudo apt-get install git-core gnupg flexbison gperf build-essential zip curl \
zlib1g-dev gcc-multilib g++-multiliblibc6-dev-i386 lib32ncurses5-dev \
x11proto-core-dev libx11-dev lib32z1-devccache libgl1-mesa-dev \
libxml2-utils xsltproc unzipdevice-tree-compiler
(经测试,安装gnupg后会造成Ubuntu无法进入桌面,可不安装这个工具包)
sudo apt-get install genext2fs
sudo apt-get install gawk
sudo apt-get install libncurses5-dev

3)解压并更新SDK
    mkdir -p ~/prj/Firefly-RK3308
cd~/prj/Firefly-RK3308
7zr xFirefly-RK3308_Linux_SDK_git_20190924.7z
git reset --hardHEAD
更新远程仓库地址:
    (官网的地址https://gitlab.com/TeeFirefly/rk3308-linux.git由于服务器在国外下载特别慢,因此我把仓库搬到了gitee上)
然后就可以从gitee处更新:
git pull gitlab firefly:firefly
4) 修改内核配置文件
    为了支持Ubuntu,Kernel需要进行一些修改:
   修改dts文件(kernel/arch/arm64/boot/dts/rockchip/ arm64 rk3308b-roc-cc-plus-amic_emmc.dts),以支持ext4文件系统,以及可读可写权限。加号表示增加这一行,减号表示删除这一行。

        
           compatible = "firefly,rk3308-firefly",    "firefly,rk3308";
   
   
           chosen {
   
-               bootargs =    "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0    root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait    snd_aloop.index=7";
   
+               bootargs =    "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 rw    root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait    snd_aloop.index=7";
   
           };
   
   
           adc-keys {
   
   

在DTS文件的末尾增加以下内容,以分别启用串口0、串口1和串口3:

   
   
&uart0 {
   
    current-speed    = <115200>;
   
    no-loopback-test;
   
    status = “okay”;
   
}
   
   
&uart1 {
   
    current-speed    = <115200>;
   
    no-loopback-test;
   
    status = “okay”;
   
}
   
   
&uart3 {
   
    current-speed    = <115200>;
   
    no-loopback-test;
   
    status = “okay”;
   
}
   
   


修改defconfig文件,支持ext4和CGROUP等

        
---    a/kernel/arch/arm64/configs/firefly-rk3308_linux_defconfig
   
+++    b/kernel/arch/arm64/configs/firefly-rk3308_linux_defconfig
   
@@ -6,6 +6,16 @@ CONFIG_FHANDLE=y
   
CONFIG_NO_HZ=y
   
CONFIG_HIGH_RES_TIMERS=y
   
CONFIG_LOG_BUF_SHIFT=18
   
+CONFIG_CGROUPS=y
   
+CONFIG_CGROUP_FREEZER=y
   
+CONFIG_CGROUP_DEVICE=y
   
+CONFIG_CPUSETS=y
   
+CONFIG_CGROUP_CPUACCT=y
   
+CONFIG_CGROUP_SCHED=y
   
+CONFIG_CFS_BANDWIDTH=y
   
+CONFIG_NAMESPACES=y
   
+CONFIG_USER_NS=y
   
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
   
CONFIG_BLK_DEV_INITRD=y
   
# CONFIG_RD_BZIP2 is not set
   
# CONFIG_RD_LZMA is not set
   
@@ -264,8 +274,17 @@    CONFIG_RK_SFC_NAND=y
   
CONFIG_RK_SFC_NOR=y
   
CONFIG_ROCKCHIP_SIP=y
   
CONFIG_EXT2_FS=y
   
-CONFIG_EXT4_FS=m
   
+CONFIG_EXT2_FS_XATTR=y
   
+CONFIG_EXT4_FS=y
   
+CONFIG_EXT4_FS_POSIX_ACL=y
   
+CONFIG_EXT4_FS_SECURITY=y
   
+CONFIG_XFS_FS=y
   
+CONFIG_BTRFS_FS=y
   
# CONFIG_DNOTIFY is not set
   
+CONFIG_FUSE_FS=y
   
+CONFIG_ISO9660_FS=y
   
+CONFIG_JOLIET=y
   
+CONFIG_ZISOFS=y
   
CONFIG_MSDOS_FS=y
   
CONFIG_VFAT_FS=y
   
CONFIG_FAT_DEFAULT_CODEPAGE=936
   
@@ -273,15 +292,24 @@    CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
   
CONFIG_NTFS_FS=y
   
CONFIG_NTFS_RW=y
   
CONFIG_TMPFS=y
   
   


        
+CONFIG_TMPFS_POSIX_ACL=y
   
CONFIG_SQUASHFS=y
   
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
   
+CONFIG_SQUASHFS_LZ4=y
   
+CONFIG_SQUASHFS_LZO=y
   
+CONFIG_SQUASHFS_XZ=y
   
CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
   
CONFIG_PSTORE=y
   
CONFIG_PSTORE_CONSOLE=y
   
CONFIG_PSTORE_RAM=y
   
-# CONFIG_NETWORK_FILESYSTEMS is not    set
   
+CONFIG_NFS_FS=y
   
+CONFIG_NFS_V3_ACL=y
   
+CONFIG_NFS_V4=y
   
+CONFIG_NFS_SWAP=y
   
CONFIG_NLS_DEFAULT="utf8"
   
+CONFIG_NLS_CODEPAGE_437=y
   
CONFIG_NLS_CODEPAGE_936=y
   
+CONFIG_NLS_ASCII=y
   
CONFIG_NLS_ISO8859_1=y
   
CONFIG_NLS_UTF8=y
   
CONFIG_PRINTK_TIME=y
   
@@ -302,7 +330,6 @@    CONFIG_RCU_CPU_STALL_TIMEOUT=60
   
CONFIG_STRICT_DEVMEM=y
   
CONFIG_DEBUG_SET_MODULE_RONX=y
   
# CONFIG_CRYPTO_ECHAINIV is not set
   
-CONFIG_CRYPTO_CRC32C=y
   
# CONFIG_CRYPTO_HW is not set
   
CONFIG_ARM64_CRYPTO=y
   
CONFIG_CRYPTO_SHA1_ARM64_CE=y
   
   

5)编译Kernel
cd kernel/
make ARCH=arm64firefly-rk3308b_linux_defconfig
make ARCH=arm64rk3308b-roc-cc-plus-amic_emmc.img
编译内核成功后会生成zboot.img文件,将该文件名修改为boot.img并替换官网固件的boot.img,最后再重新打包,就完成了内核的更新。
1.2固件的烧写
烧写方法参考官网《升级固件》。
http://wiki.t-firefly.com/zh_CN/Core-3308Y/burning_firmware.html


二、LINX工具包的安装
    本章介绍如何在RK3308BPlus开发板上安装LINX工具包。
2.1 修改软件包
LINX工具包默认不支持32bitCPU,而RK3308B是64bitCPU,因此这里需要对官方软件包做一些修改,使其能在RK3308等ARM64架构的CPU上正常运行(另:LINX工具包仅支持ARMv7及以上的CPU)。
通过Putty连接到开发板,使用以下命令在工作目录下创建新文件夹:
mkdir lvrt20-schroot
进入创建好的目录
cd lvrt20-schroot
添加labviewmakerhub软件源
echo "deb [trusted=yes] http://feeds.labviewmakerhub.com/debian/ binary/"| sudo tee -a /etc/apt/sources.list
更新软件源
sudo apt-get update
下载LINX包
apt-get download lvrt20-schroot:armhf
安装修改软件包所需的工具
sudo apt-get install schroot python avahi-daemon netbase binutils nano
解压deb包
arx lvrt20-schroot_20.0.0-4_armhf.deb
解压control.tar.gz压缩文件
tarxzf control.tar.gz
用文本编辑器打开control文件
nano control
找到Depends:line行,移除schroot、python
Ctrl+Y保存,文件名不变,Ctrl+x退出编辑器
重新打包control.tar.gz文件
tar--ignore-failed-read -cvzf control.tar.gz {post,pre}{inst,rm} md5sums control
如果报关于md5的错误,则从命令中移除md5sums,重新执行。
重新打包deb包
arrcs lvrt20-schroot.deb debian-binary control.tar.gz data.tar.gz
增加32位运行架构
sudo dpkg --add-architecture armhf
安装修改后的软件包
sudo dpkg -i lvrt20-schroot.deb
2.2 安装运行环境
上一节介绍了修改软件报的方法,其实这个操作执行一次即可,获取到lvrt20-schroot.deb文件后,以后安装时不需要在重新修改软件包,安装一些必要软件后,直接安装lvrt20-schroot.deb包即可。安装步骤简化为如下:
首先安装运行必要的环境
sudo apt-get install schroot python avahi-daemon
增加32位运行架构
sudo dpkg --add-architecture armhf
安装修改后的软件包
sudo dpkg -i lvrt20-schroot.deb

三、程序开发
3.1 开发流程
本章以一个简单程序为例,介绍开发一个LINX程序的流程。
>  创建一个空文件夹,命名为rk3308。
打开LabVIEW2020,创建一个空的项目,命名为new_linx_projec,并保存到rk3308文件夹下。
>  右击项目管理器顶部的Project:new_linx_project.lvproj相,依次选择New>>Targetsand Devices>>New target or device>>LINX>>Raspberry Pi 2B。(也可以选择BeagleBoneBlack,这里选哪个都一样)然后点击OK。
image.jpg

>  右击项目管理器出现的RaspberryPi 2B选项,选择Properties,弹出属性窗口。修改Name文本框为:FireflyRK3308,修改IP Address / DNS Name选项为开发板对应的IP地址(可通过ifconfig指令获取)。点击OK。
image.png
> 右击FireflyRK3308(*.*.*.*)选项,点击Connect,出现下图的提示说明连接成功。关闭该窗口。
image.jpg

>  右击FireflyRK3308(*.*.*.*)选项,选择New>>VI,新建一个空白VI,命名为main.vi,按照下图编写程序。
image.png

>  点击运行按钮,程序开始执行编译、部署操作,成功后,前面板的数字框开始增加,说明说明程序运行成功。
3.2 设置程序为自动启动
>  展开FireflyRK3308(*.*.*.*)选项,右击BuildSpecification选项>>New >> Real-Time Application。
>  在Category列表中选择SourceFiles选项,然后将main.vi设置为StartupVIs,点击OK按钮。在BuildSpecifications选项下会出现MyReal-Time Application选项,如下图所示。
image.png

>  右键点击MyReal-Time Application选项,依次点击Build、Deploy选项,分别编译和部署我们刚才编写的程序。
>  如果需要程序在系统启动时自动运行,需要右击MyReal-Time Application选项,选择Setas startup选项,并且重新部署。

四、驱动开发
4.1 在Windows下交叉编译Intelx64或ARM架构的动态链接库
(本文翻译自NI官网教程,原文参见https://knowledge.ni.com/Knowled ... 0000YGNdCAO&l=zh-CN
请按照以下指引,一步一步将源代码编译成.so文件。
>  安装Java(建议安装JavaSE 6以上版本),可以从(https://www.java.com/en/)下载
>  下载并安装C/C++Development Tools for NI Linux Real-Time, Eclipse版本工具包,版本选择2017。
>  启动C/C++Development Tools for NI Linux Real-Time, Eclipse版本工具包。
>  当弹出提示框时,选择一个文件夹用于保存Eclipse项目,并点击OK按钮。
>  在Eclipse欢迎窗口,选择右侧的Workbench图标打开Workbench视图。
>  导航到File>>New>>CProject选项,创建一个新的C/C++新的项目,并选择SharedLibrary(共享库)项目和Gross GCC工具链。
image.png
>  创建的时候同时选择Debug和Release配置选项。
>  当弹出配置CrossGCC前缀和路径,从下面的列表中选择对应的路径和前缀:
Prefix:
(ARM-based targets,2014 and 2017 software stack)
arm-nilrt-linux-gnueabi-
(Intel x64-basedtargets, 2014 and 2017 software stack)
x86_64-nilrt-linux-
Path:
(ARM-based targets,2017 software stack)
C:\build\17.0\arm\sysroots\i686-nilrtsdk-mingw32\usr\bin\arm-nilrt-linux-gnueabi
(Intel x64-basedtargets, 2017 software stack)
C:\build\17.0\x64\sysroots\i686-nilrtsdk-mingw32\usr\bin\x86_64-nilrt-linux
image.png

>  现在,右击项目文件夹,选择Import按钮,导入需要编译的.c源文件。选择的文件会被添加到项目路径下。
>  在项目浏览器选项卡中右击项目,然后选择属性。
>  在属性对话框左侧的选板中选择C/C++Build。
>  在Buildertype下拉列表中选择Internal builder。
>  在属性对话框左侧的在C/C++Build,选择Settings项。
>  在ToolSettings选项卡的Cross GCC Compiler项下选择Miscellaneous。在OtherFlags文本框中,在已经存在的文本后面添加一个空格,然后选择添加下面的内容。
(ARM-based targets, 2017 software stack)
--sysroot=C:\build\17.0\arm\sysroots\cortexa9-vfpv3-nilrt-linux-gnueabi
(Intel x64-based targets, 2017 software stack)
--sysroot=C:\build\17.0\x64\sysroots\core2-64-nilrt-linux
>  在ToolSettings选项卡的Cross GCC Linker项下,选择Miscellaneous,然后在Linkerflags文本框中选择输入下面的内容。
(ARM-based targets, 2017 software stack)
--sysroot=C:\build\17.0\arm\sysroots\cortexa9-vfpv3-nilrt-linux-gnueabi
(Intel x64-based targets, 2017 software stack)
--sysroot=C:\build\17.0\x64\sysroots\core2-64-nilrt-linux
>  在项目属性窗口中导航到C/C++General>>Path and Symbols选项。进入到Symbols选项并选择Add按钮。输入标记kNIOSLinux ,点击OK然后点击Apply。
>  在项目属性窗口中,选择C/C++Build>>Settings,然后选择ToolSettings>>Cross GCC Compiler>>Miscellaneous项。勾选PositionIndependent Code复选框,点击Apply按钮。
image.png
>  进入ErrorParsers选项,确保只有以下三个选型被勾选:GNU AssemblerError Parser、GNUgmake Error Parser 7.0、andthe GNU Linker Error Parser,然后点击Apply。
image.png

>  进入C/C++Build>>Settings>>Cross GCC Compiler,在编译命令后面添加-fvisibility=protected。点击Apply,然后点击OK关闭属性窗口。
>  在菜单栏选择Project>>BuildProject选型,编译.so文件,编译成功的文件在项目文件夹>>Debug路径下。

4.2串口驱动源代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<errno.h>

#defineUART_DEV  "/dev/ttyS1"

intlen;
charbuf_write[] = "hello ZZL!";
charbuf_read[1024];

//intopen(const char *pathname, int oflag, ... );
//初始化串口
intuart_init(void )
{
    int fd=0;
    fd = open(UART_DEV ,O_RDWR|O_NOCTTY|O_NDELAY, 0);
    if (fd < 0)
    {

        return -1;
    }
    return fd;
}

//设置串口波特率、停止位、校验位等参数
intset_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio,oldtio;
    if  (tcgetattr( fd,&oldtio)  !=  0)
    {
        perror("SetupSerial 1");
        return -1;
    }
    bzero( &newtio, sizeof( newtio ) );
    newtio.c_cflag  |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch( nBits )
    {
    case 7:
        newtio.c_cflag |= CS7;
        break;
    case 8:
        newtio.c_cflag |= CS8;
        break;
    }

    switch( nEvent )
    {
    case 'O':                     //奇校验
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= (INPCK | ISTRIP);
        break;
    case 'E':                     //偶校验
        newtio.c_iflag |= (INPCK | ISTRIP);
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        break;
    case 'N':                    //无校验
        newtio.c_cflag &= ~PARENB;
        break;
    }

switch(nSpeed )
    {
    case 2400:
        cfsetispeed(&newtio, B2400);
        cfsetospeed(&newtio, B2400);
        break;
    case 4800:
        cfsetispeed(&newtio, B4800);
        cfsetospeed(&newtio, B4800);
        break;
    case 9600:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    case 115200:
        cfsetispeed(&newtio, B115200);
        cfsetospeed(&newtio, B115200);
        break;
    default:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    }
    if( nStop == 1 )
    {
        newtio.c_cflag &=  ~CSTOPB;
    }
    else if ( nStop == 2 )
    {
        newtio.c_cflag |=  CSTOPB;
    }
    newtio.c_cc[VTIME]  = 0;
    newtio.c_cc[VMIN] = 0;
    tcflush(fd,TCIFLUSH);
    if((tcsetattr(fd,TCSANOW,&newtio))!=0)
    {
        perror("com set error");
        return -1;
    }
    printf("set done!\n");
    return 0;
}

//串口发送数据
intuart_write(int fd){
    len = write(fd, buf_write,sizeof(buf_write));
    return len;
}

//串口读取数据
char*uart_read(int fd){
    int len;
    char *aaa;
    char *empty = "no data";
       len = read(fd, buf_read,sizeof(buf_read));
       if (len < 0){
              return empty;
       }
    aaa = buf_read;
       return aaa;
}

//关闭串口
voiduart_close(int fd){
       close(fd);
}


4.3看门狗的使用方法
第一步:
      在DTS文件中增加以下内容:
      &wdt{
           status = “okay”;
}
第二步:确保/kernel/arch/arm64/configs/firefly-rk3308b_linux_defconfig配置文件中以下两项的配置如下:
       CONFIG_WATCHDOG=y
       CONFIG_DW_WATCHDOG=y
第三步:重新编译Kernel
看门狗使用方法
image.png
image.png









回复

使用道具 举报

13

积分

0

威望

0

贡献

技术小白

积分
13
发表于 2021-4-4 19:41:51     
感谢楼主分享!
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表