• 【STM32H7】第4章 RL-USB移植(MDK AC5)


    论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99710 

    第4章   RL-USB移植(MDK AC5)

    本章教程为大家讲解RL-USB协议栈的AC5编译器移植。

    4.1 初学者重要提示

    4.2 移植RL-USB整体说明

    4.3 了解RL-USB模板框架设计

    4.4 第1步,安装指定的MDK软件包

    4.5 第2步,准备一个工程模板

    4.6 第3步,添加RL-USB并配置

    4.7 第4步,强行运行一次CubeMX配置USB

    4.8 第5步,修改文件USBD_STM32H7xx.c

    4.9 第6步,修改文件stm32h7xx_hal_msp.c

    4.10 第7步,修改文件文件includes.h

    4.11 第8步,添加两个应用文件

    4.12 第9步,添加头文件路径

    4.13 第10步,创建应用任务(重要,注意启动任务)

    4.14 常见移植错误总结

    4.15 使用的MicroUSB接口并注意跳线帽设置

    4.16 实验例程

    4.17 总结

    4.1   初学者重要提示

    1.   学习RL-USB移植前,务必保证已经熟练掌握了RTX5内核的移植,因为本章节的移植要用到RTX5移植的一些操作方法:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93149
    2.   STM32H7使用MDK RTE环境添加RTX5和RL-USB,需要强制运行一次STM32CubeMX,因为H7已经没有配套RTE经典添加方式,而STM32F4是支持经典方式的,所以无需运行STM32CubeMX,详情可以看我们STM32F4开发板对应的RL-USB教程。
    3.   本章配套例子使用STM32内部RAM模拟一个U盘,使用的MicroUSB接口。

    4.2   移植RL-USB整体说明

    移植之前,有必要对移植过程有个整体的认识:

    •   第1步,准备一个RTX5工程模板。
    •   第2步,移植RL-USB。
      •   移植RL-USB是采用MDK的RTE环境直接添加。当前H7芯片使用RTX5强制运行STM32CubeMX,所以需要大家提前安装好STM32CubeMX V6.0或者以上版本。
    •   第3步,处理HAL库时间基准,MPU配置等。
    •   第4步,创建应用。

    总的来说,这4步就可以完成移植,下面将STM32H7的移植步骤和注意事项为大家做个说明。

    4.3   了解RL-USB模板框架设计

    移植RL-USB前,我们优先了解下移植好的RL-USB内核模板,方面大家后面移植:

     

    框图如下:

    4.4   第1步,安装指定的MDK软件包

    移植新版RL-USB需要大家下载当前最新的MDK软件包版本(如果有最新版,推荐大家用最新版):

    •   CMSIS 软件包使用当前最新的:V5.7.0
    •   STM32H7使用当前最新的:V2.6.0
    •   STM32F4使用当前最新的:V2.15.0
    •   STM32CubeMX使用当前最新的:V6.0.x
    •   ARM_Compiler使用当前最新的:V1.6.3
    •   RTX5中间件使用当前最新的:V7.12

    这些软件包的安装在STM32H7用户手册的第2章2.3小节有详细说明。

    http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

    •   所有这些软件包汇总下载地址:

    http://www.armbbs.cn/forum.php?mod=viewthread&tid=100490

    不管以后MDK的软件包版本如何升级,当前的软件包版本和以后的新版是可以同时安装的,也就是说可以安装多个不同版本,在这里可以选择指定版本:

     

    4.5   第2步,准备一个工程模板

    首先准备好一个简单的裸机工程模板,已经为大家做好:V7-4001_RTX5 Kernal Template,准备好的工程模板如下图所示(大家也可以制作其它任意的工程模板,不限制):

     

    4.6   第3步,添加RL-USB并配置

    看这部分内容前,务必保证已经熟练掌握了RTX5教程移植章节的添加方法。

    4.6.1      RL-USB相关文件和驱动

    CMSIS-Driver分组中添加USB Device驱动:

     

    添加USB驱动:

     

    添加RL-USB并配置:

     

    我们需要的都已经添加好,效果如下:

     

    红色方框里面驱动要隔离出来,隔离后的效果如下(隔离方法看RTX5教程移植章节):

     

    4.6.2      重新添加被隔离的CMSIS-Driver文件

    将我们提供的程序模板中制作好的RL-ARM文件夹复制粘贴到大家准备好的工程模板中。

     

    RL-ARM文件夹中有如下七个文件夹,其中只有RL-USB文件夹里面有文件

     

    内容如下,这些文件是来自MDK安装目录:

     

    然后将用到的两个文件添加进来:

     

    4.6.3      重新添加被隔离的HAL库USB文件

    文件stm32h7xx_hal_pcd.c,stm32h7xx_hal_pcd_ex.c和stm32h7xx_ll_usb.c被隔离出来了,我们单独在分组HAL_Driver里面添加。除了这三个文件,同时将两个pwr文件也添加进来:

     

    4.6.4      RL-USB配置

    添加完毕RL-USB所需的文件后,就是配置RL-USB,具体每个配置所代表的含义,会在后面章节专为大家讲解。

    USBD_Config_0.c文件配置:

     

    注意这个文件里面还有一个RL-USB内核线程的优先级配置,当前是将其配置为:

    osPriorityAboveNormal:

     

    USBD_Config_MSC_0.h文件的配置如下:

     

    这个文件里面有一个USB MSC任务的优先级配置,当前是将其配置为:osPriorityAboveNormal。

     

    4.7   第4步,强制运行一次CubeMX配置USB

    我们这里要强行运行一次STM32CubeMX来自动使能RL-USB的相关宏定义,并配置USB接口使用到的两个引脚PA11和PA12。

    打开RTE环境,点击如下按钮:

     

    弹出的STM32CubeMX配置如下:

     

    修改位置1:用于选择仅使用设备。

    修改位置2:用于使能USB FS中断。然后点击“GENERATE CODE”

     

    然后弹出如下对话框,点击Close即可,然后关闭STM32CubeMX。

    重新回到MDK,会有一个对话框,点击“是”即可:

     

    配置后,就可以看到stm32h7xx_hal_msp.c文件里面对USB引脚做了配置。

     

    4.8   第5步,修改文件USBD_STM32H7xx.C

    这个文件开头的头文件顺序要修改,否则编译会出错,原始的顺序如下:

    #include "OTG_STM32H7xx.h"
    #include "USBD_STM32H7xx.h"
    
    #include "stm32h7xx.h"

    修改后的顺序如下:

    #include "stm32h7xx.h"
    
    #include "OTG_STM32H7xx.h"
    #include "USBD_STM32H7xx.h"

    4.9   第6步,修改文件stm32h7xx_hal_msp.c

    需要在这个文件开头添加一个变量PCD_HandleTypeDef hpcd_USB_OTG_FS,此贴变量会被USB的CMSIS Driver文件所调用。最好将其放在如下位置,防止重新调用STM32CubeMX时将清除掉:

     

    4.10 第7步,修改文件includes

    添加USB头文件:#include "rl_usb.h"

    #ifndef  __INCLUDES_H__
    #define  __INCLUDES_H__
    
    /*
    *********************************************************************************************************
    *                                         标准库
    *********************************************************************************************************
    */
    #include  <stdarg.h>
    #include  <stdio.h>
    #include  <stdlib.h>
    #include  <math.h>
    
    
    /*
    *********************************************************************************************************
    *                                         其它库
    *********************************************************************************************************
    */
    
    
    /*
    *********************************************************************************************************
    *                                           OS和系统库
    *********************************************************************************************************
    */
    #include "cmsis_os2.h"
    #include "rl_usb.h"
    
    /*
    *********************************************************************************************************
    *                                           宏定义
    *********************************************************************************************************
    */
    
    
    
    /*
    *********************************************************************************************************
    *                                        APP / BSP
    *********************************************************************************************************
    */
    #include "bsp.h"
    
    
    
    /*
    *********************************************************************************************************
    *                                          变量和函数
    *********************************************************************************************************
    */
    /* 方便RTOS里面使用 */
    extern void SysTick_ISR(void);
    
    #define bsp_ProPer1ms  SysTick_ISR
    
    #endif
    
    /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

    4.11 第8步,添加两个应用文件

    为了验证移植的USB是否成功,我们这里使用内部RAM模拟一个U盘。需要添加的两个文件在MDK安装目录里面。方便起见,大家可以直接从本章配套例子里面复制粘贴(这两个文件位于User文件夹),添加后的效果如下:

     

    4.12 第9步,添加头文件路径

    添加头文件路径:

     

    4.13 第10步,创建应用任务(重要,注意启动任务)

    应用程序比较简单,大家可以直接复制本章教程配置例子的main.c文件中的内容到自己工程里面测试。主要创建了如下几个任务:

    AppTaskUserIF任务   : 按键消息处理。

    AppTaskLED任务      : LED闪烁。

    AppTaskMsgPro任务   : 消息处理,暂未使用。

    AppTaskStart任务    : 启动任务,也是最高优先级任务,这里实现按键扫描。

    osRtxTimerThread任务: 定时器任务,暂未使用。

    任务栈大小和任务控制块定义如下:

    /*
    **********************************************************************************************************
                                                 变量
    **********************************************************************************************************
    */
    /* 任务的属性设置 */
    const osThreadAttr_t ThreadStart_Attr = 
    {
        /* 未使用 */
    //    .cb_mem = &worker_thread_tcb_1,
    //    .cb_size = sizeof(worker_thread_tcb_1),
    //    .stack_mem = &worker_thread_stk_1[0],
    //    .stack_size = sizeof(worker_thread_stk_1),
    //    .priority = osPriorityAboveNormal,
    //    .tz_module = 0
        
        .name = "osRtxStartThread",
        .attr_bits = osThreadDetached, 
        .priority = osPriorityNormal4,
        .stack_size = 2048,
    };
    
    const osThreadAttr_t ThreadMsgPro_Attr = 
    {
        .name = "osRtxMsgProThread",
        .attr_bits = osThreadDetached, 
        .priority = osPriorityNormal3,
        .stack_size = 1024,
    };
    
    const osThreadAttr_t ThreadLED_Attr = 
    {
        .name = "osRtxLEDThread",
        .attr_bits = osThreadDetached, 
        .priority = osPriorityNormal2,
        .stack_size = 512,
    };
    
    const osThreadAttr_t ThreadUserIF_Attr = 
    {
        .name = "osRtxThreadUserIF",
        .attr_bits = osThreadDetached, 
        .priority = osPriorityNormal1,
        .stack_size = 1024,
    };

    任务创建:

    /*
    *********************************************************************************************************
    *    函 数 名: main
    *    功能说明: 标准c程序入口。
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    int main (void) 
    {    
        /* HAL库,MPU,Cache,时钟等系统初始化 */
        System_Init();
    
        /* 内核开启前关闭HAL的时间基准 */
        HAL_SuspendTick();
        
        /* 内核初始化 */
        osKernelInitialize();                                  
    
        /* 创建启动任务 */
        ThreadIdStart = osThreadNew(AppTaskStart, NULL, &ThreadStart_Attr);  
    
        /* 开启多任务 */
        osKernelStart();
        
        while(1);
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: AppTaskCreate
    *    功能说明: 创建应用任务
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void AppTaskCreate (void)
    {
        ThreadIdTaskMsgPro = osThreadNew(AppTaskMsgPro, NULL, &ThreadMsgPro_Attr);  
        ThreadIdTaskLED = osThreadNew(AppTaskLED, NULL, &ThreadLED_Attr);  
        ThreadIdTaskUserIF = osThreadNew(AppTaskUserIF, NULL, &ThreadUserIF_Attr);  
    }

    这里我们重点看下启动任务,主要做了五个工作:

    •   外设初始化bsp_Init。
    •   任务创建AppTaskCreate。
    •   初始化USB并连接电脑。
    •   需要周期性处理的程序bsp_ProPer1ms,对应裸机工程调用的SysTick_ISR。这个的实现非常重要,这样之前裸机里面使用的API,就可以直接在RTX5里面直接调用。
    /*
    *********************************************************************************************************
    *    函 数 名: AppTaskStart
    *    功能说明: 启动任务,这里用作BSP驱动包处理。
    *    形    参: 无
    *    返 回 值: 无
    *   优 先 级: osPriorityHigh4  
    *********************************************************************************************************
    */
    void AppTaskStart(void *argument)
    {
        const uint16_t usFrequency = 1; /* 延迟周期 */
        uint32_t tick;
        
        /* 初始化外设 */
        HAL_ResumeTick();
        bsp_Init();
    
        /* 创建任务 */
        AppTaskCreate();
    
        USBD_Initialize(0U);  /* 初始化USB设备 */
        USBD_Connect   (0U);  /* USB设备连接 */
    
        /* 获取当前时间 */
        tick = osKernelGetTickCount(); 
        
        while(1)
        {
            /* 需要周期性处理的程序,对应裸机工程调用的SysTick_ISR */
            bsp_ProPer1ms();
            
            /* 相对延迟 */
            tick += usFrequency;                          
            osDelayUntil(tick);
        }
    }

    4.14 常见移植错误总结

    •   编译后提示如下错误:

    error: 'Driver_USBD.h' file not found

    解决办法是将新版 CMSIS 软件包里面 Driver 文件夹全部复制到自己所创建工程里面的 CMSIS文件夹下,并添加路径:

     

    •   提示如下错误

    unknown type name 'HAL_StatusTypeDef'

    解决办法:本章4.8小节。

    4.15 使用的MicroUSB接口并注意跳线帽设置

    本周教程移植的例子使用内部RAM模拟了一个U盘,效果如下:

     

    注意使用的是MicroUSB接口:

     

    注意板子左下角跳线帽的设置:

     

    这里是用于选择CAN1 TX使用PB9或者PA12引脚,CAN1 RX使用PB8或者PA11引脚。大家这里可以什么都不接,或者CAN1 TX通过跳线帽短接PA12,CAN1 RX通过跳线帽短接PA11。切记不可以短接到PA12和PA11引脚上,USB要使用这两个引脚。

    4.16 实验例程

    本章节配套了如下几个例子供大家移植参考:

    •   V7-4001_RTX5 Kernal Template

    RTX5内核模板。

    •   V7-4002_RL-USB Template

    RL-USB工程内核模板,使用内部RAM模拟了一个U盘。

    MDK进入调试状态后,选择周期更新:

     

    然后打开调试组件,注意和RTX4的调试组件位置不同:

     

    然后点击MDK的全速运行,

     

    至此,就可以动态实时查看RL-USB的运行状态:

     

    4.17 总结

    本章节为大家讲解了RL-USB 在MDK AC5上的移植方法,移植涉及到的知识点比较多,初学的话,建议实际动手操作一遍。

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    杨老师课堂_VBA学习教程之根据部门列创建工作表
    杨老师课堂_Java核心技术下之控制台模拟微博用户注册案例
    杨老师课堂_Java核心技术下之控制台模拟记事本案例
    杨校老师课堂之JavaScript右下角广告弹框教程
    JavaScript的数组知识案例之随机点名器
    SET QUOTED_IDENTIFIER ON
    SET ANSI_NULLS ON
    OLEDB和ODBC的区别
    教你认识主板上的主要芯片
    递归和迭代有什么区别
  • 原文地址:https://www.cnblogs.com/armfly/p/14431358.html
Copyright © 2020-2023  润新知