基于PYNQ的RT-Thread移植

  • 配置需求
  1. 操作系统:Windows 10
  2. 硬件设备:PYNQ-Z1
  3. 开发环境:Vivado2018.3
  4. RT-Thread系统版本:https://gitee.com/rtthread/rt-thread,标签:V4.0.3
  • 移植步骤
  1. 安装PYNQ-Z1的board file文件

通过网址https://github.com/cathalmccabe/pynq-z1_board_files将下载好的PYNQ-Z1.zip文件解压到安装好的vivado路径Vivado\2018.3\data\boards\board_files下面即可。

  1. 使用vivado创建工程文件

首先在E盘,也可以在其它磁盘创建一个空的文件夹用来存放工程,取名为workspace。打开vivado,选择新建一个工程。点击Next。工程路径存放在之前我们创建的workspace空文件夹下面,然后工程名称取名为rtthread。然后,点击Next选择“RTL project”,选择Next,选择“Boards”,找到PYNQ-Z1,选择Next(如下图所示)。

基于PYNQ的RT-Thread移植_第1张图片

 选择Finish即可完成工程的创建。

然后,选择左侧“Create Block Design”,跳出对话框,默认点OK,选择“+”添加IP,

选择类型为ZYNQ7。

基于PYNQ的RT-Thread移植_第2张图片

 选择“Run Block Automation”,跳出对话框,默认点OK,此时会自动连接引脚。将M_AXI_GP0_ACLK引脚连接到FCLK_CLK0,否则在生成HDL的时候会报错。

基于PYNQ的RT-Thread移植_第3张图片

切到“source”下,右击选择“Create HDL Wrapper…”,跳出对话框默认OK。

右击选择“Generate Output Product”。跳出对话框默认Generate即可。点击左侧“Generate Bitstream”,生成bit流文件。跳出对话框默认OK即可。

将硬件信息导出,如下图所示。

基于PYNQ的RT-Thread移植_第4张图片导出的时候比特流文件也要导出,记得勾选。否则后期生产BOOT.BIN缺失FPGA文件。

基于PYNQ的RT-Thread移植_第5张图片

 此时在工程文件下的SDK文件夹下面就会出现design_1_wrapper.hdf文件。即硬件描述文件。

  1. 通过SDK移植RT-Thread系统

接着之前的vivado工程,在FILE选择Lanch SDK打开SDK。跳出对话框默认选择ok。

选择“File”→“New”→“Application Project”,弹出New Project视图,输入工程名称rtthread,单击Next,选择Empty Application,单击Finish完成硬件平台的创建。

在rtthread.sdk\rtthread目录下,新建rt-thread目录。将下载的rtthread代码放入该目录。为了减少编译错误,先移植rtthread的内核以及shell功能,将源码的未用组件及无关目录进行删除,工程没有使用scons构建工具,其相关文件均可删除。

基于PYNQ的RT-Thread移植_第6张图片

其中,

  1. bsp文件夹,删除除zynq7000外的所有文件夹;
  2. components文件夹,删除除drivers、finsh外的所有文件夹;
  3. components\drivers文件夹,删除除include、serial、src外的所有文件夹;
  4. 删除documentation文件夹;
  5. 删除examples文件夹;
  6. libcpu文件夹,删除除arm外的所有文件夹;
  7. libcpu\arm文件夹,删除除zynq7000外的所有文件夹;
  8. 内核tools文件夹。
  9. 将bsp\zynq7000\applications目录下的application.c文件移到rtthread.sdk\rtthread\src目录下。

在rtthread项目文件夹上单击鼠标右键,选择Properties。在弹出的Properties for rtthread视图左侧选择“C/C++ Build”→“Settings”。在右侧Settings界面选择“Tool Settings”→“ARM v7 gcc compiler”→“Directories”。在Include Paths中依次添加需要的内核头文件库目录,单击Apply应用配置变更。内核头文件目录如下表所示:

rtthread\rtthread.sdk\rtthread\rt-thread\include

rtthread\rtthread.sdk\rtthread\rt-thread\bsp\zynq7000

rtthread\rtthread.sdk\rtthread\rt-thread\bsp\zynq7000\drivers

rtthread\rtthread.sdk\rtthread\rt-thread\libcpu\arm\zynq7000

rtthread\rtthread.sdk\rtthread\rt-thread\components\finsh

rtthread\rtthread.sdk\rtthread\rt-thread\components\drivers\include

添加链接配置文件。在右侧Settings界面选择“Tool Settings”→“ARM v7 gcc linker”→“Linker Script”。在Linker Script中添加需要的链接配置文件,此处选择rtthread.sdk\rtthread\rt-thread\bsp\zynq7000\zynq7000.ld文件,单击Apply应用配置变更。

修改application.c文件的rt_init_thread_entry()函数如下所示,为了方便看出rtthread启动任务的效果,在该函数添加while(1)循环。

/* thread phase init */

static void rt_init_thread_entry(void *parameter)

{

    /* do component initialization */

    rt_components_init();

    while (1) {

        rt_thread_delay(100);

        rt_kprintf("running on cpu %d\n", rt_cpu_get_smp_id() & 0x0f);

    }

    /* add your initialization here */

}

此时,刷新rtthread项目编译,编译通过。

  1. 调试

首先,板卡选择JTAG模式。

右键点击rtthread工程,选择“Debug As”→“Debug Configurations…”,进入到Debug Configurations对话框。

双击“Xilinx C/C++ application(System Debugger) ”,进入到“System Debugger using Debug_rtthread.elf on Local”。在Target Setup标签页,选择“Reset entire system”。在Applications标签页,“Application”选择编译生成的rtthread.elf文件。点击Debug,进入调试界面。点击“Suspend”,让程序进入到暂停状态。进入application.c文件,在rt_thread_delay(100)行,右键选择“Run to Line”,让程序运行到该任务。

  • 模块移植
  1. 时钟修改

参考时钟定义在board.h,参考数据手册或者创建工程中zynq模块中的时钟定义对该文件进行修改。

  1. 串口模块
  • 串口驱动文件有uart.c和uart_hw.h文件。
  • 修改uart0的管脚为MIO14和MIO15。
  • 打印为乱码,怀疑为波特率设置不对,确定Zynq7000_SLCR_UART_CLK_CTRL寄存器的配置存在问题,需要在配置之前将该寄存器置0。

__REG32(Zynq7000_SLCR_BASE+Zynq7000_SLCR_UART_CLK_CTRL) &= 0x0;

__REG32(Zynq7000_SLCR_BASE+Zynq7000_SLCR_UART_CLK_CTRL) |= (0x14 << 8) | 0x01;

经过修改,串口打印正常,如下图所示。

基于PYNQ的RT-Thread移植_第7张图片

  1. 网口模块

移植net目录下得lwip-1.4.1模块,

  • 删除无关代码。
  • 编译过程中,ethernetif.c文件提示如下三个宏未定义,源代码中,宏通过配置文件定义,因此在ethernetif.h添加宏定义。

#define RT_LWIP_IPADDR "192.168.1.9"

#define RT_LWIP_GWADDR "192.168.1.1"

#define RT_LWIP_MSKADDR "255.255.255.0"

  • 在开始运行过程中,网络可以ping通,但串口打印不正常,提示“(priority < RT_THREAD_PRIORITY_MAX) assertion failed at function:_rt_thread_init,”,判断是_rt_thread_init()函数中对优先级进行判断时出现问题。经过跟踪,发现在lwip模块中定义任务时,由于以下定义优先级的宏大于RT_THREAD_PRIORITY_MAX而导致出错,而以下几个宏在源代码中是通过配置文件处理的,因此,参考源代码中的配置文件修改宏结果如下:

#define TCPIP_THREAD_PRIO           10

#define RT_ETHERNETIF_THREAD_PREORITY   12

经过修改,网口可以正常ping,串口也打印正常,如下图所示。

基于PYNQ的RT-Thread移植_第8张图片

 

 

 

你可能感兴趣的:(操作系统,c语言,arm开发,ubuntu,arm)