文章目录

  • 前言
  • 一、复制外部源文件到工程中
  • 二、添加源文件和头文件路径
  • 三、修改源码
  • 四、源码下载
  • 总结

前言

在原本RTT框架下添加USB-Host,并且可以使用dfs。


一、复制外部源文件到工程中

1、复制之前博文中写到的《GD32E103的Flash芯片上挂载文件系统》的工程并将文件夹命名为test。

2、在rt-thread-rt-smart\bsp\test\drivers文件夹中新建MSC_Host文件夹,并复制官方USBFS例程中inc、src文件到里面,具体路径看截图。


3、将src文件中的main.c移到applications文件夹中,并命名为usb_host.c,新建usb_host.h也放在里面。

4、将rt-thread-rt-smart\bsp\test\drivers\MSC_Host\src中的gd32e10x_it.c删除。

5、将图中路径的udisk.c文件复制到rt-thread-rt-smart\bsp\test\Libraries\GD32E10x_usbfs_driver\Source中,并在rt-thread-rt-smart\bsp\test\Libraries\GD32E10x_usbfs_driver\Include中新建一个udisk.h头文件。

二、添加源文件和头文件路径

1、打开工程。这里注意一下,我强迫症把原本工程中USER_DEV文件夹里面的gd25qxx.c文件移动到Applications中了,其实这只是个人问题,对工程本身没什么影响。

2、新建文件夹USB_Dirver,并将图中文件添加到工程中,具体路径自己找,反正都在test文件夹下。
3、在Drivers文件夹下添加图中文件。
4、将usb_host.c文件添加到Applications。

5、添加头文件路径

三、修改源码

1、删除usb_host.c中的main函数,添加代码

#define USB_DEVICE_CONTROLLER_NAME      "usbd"
#define USB_THREAD_STACK_SIZE     1024/*!\brief      this function handles USBFS interrupt\param[in]  none\param[out] none\retval     none
*/
void  USBFS_IRQHandler (void)
{/* enter interrupt */rt_interrupt_enter();usbh_isr (&usb_core_dev);/* leave interrupt */rt_interrupt_leave();
}/*!\brief      this function handles Timer0 update interrupt request.\param[in]  none\param[out] none\retval     none
*/
void TIMER0_UP_TIMER9_IRQHandler(void)
{/* enter interrupt */rt_interrupt_enter();timer_delay_irq();/* leave interrupt */rt_interrupt_leave();
}/*!\brief      rt_usbh_thread_entry routine\param[in]  none\param[out] none\retval     none
*/
static void rt_usbh_thread_entry(void* parameter)
{rt_err_t res = -RT_ERROR;rt_device_t dev = RT_NULL;dev = (rt_device_t)rt_malloc(sizeof(struct rt_device));if (dev == RT_NULL){rt_kprintf("dev malloc failed\r\n");return;}rt_memset(dev, 0, sizeof(struct rt_device));res = rt_device_register(dev, "usbh", RT_DEVICE_FLAG_DEACTIVATE);if (res != RT_EOK){rt_kprintf("register usb host failed res = %d\r\n", res);}dev->init = rt_udisk_init;dev->read = rt_udisk_read;dev->write = rt_udisk_write;dev->control = rt_udisk_control;while(1){    host_state_polling_fun(&usb_core_dev, &usb_host, &usbh_state_core);rt_thread_mdelay(100);}
}/*!\brief      usb_host_init routine\param[in]  none\param[out] none\retval     none
*/
void usb_host_init(void)
{/* allocate memory for the usbh_usr_struct */if((usbh_usr = (usbh_usr_struct *)rt_malloc(sizeof(usbh_usr_struct))) == RT_NULL){rt_kprintf("malloc memory for usbh_usr_struct failed!\r\n");return;}rt_memset(usbh_usr, 0, sizeof(usbh_usr_struct));/* allocate memory for the usbh_data_in_buffer */if((usbh_data_in_buffer = (uint8_t *)rt_malloc(USBH_DATA_BUFFER_SIZE)) == RT_NULL){rt_kprintf("malloc memory for usbh_data_in_buffer failed!\r\n");return;}rt_memset(usbh_data_in_buffer, 0, USBH_DATA_BUFFER_SIZE);/* allocate memory for the usbh_data_in_buffer */if((usbh_data_out_buffer = (uint8_t *)rt_malloc(USBH_DATA_BUFFER_SIZE)) == RT_NULL){rt_kprintf("malloc memory for usbh_data_out_buffer failed!\r\n");return;}rt_memset(usbh_data_out_buffer, 0, USBH_DATA_BUFFER_SIZE);/* usb rcu init */usb_rcu_init();/* timer nvic initialization */timer_nvic_init();/* configure GPIO pin used for switching VBUS power */usb_hwp_vbus_config(&usb_core_dev);/* host de-initializations */usbh_deinit(&usb_core_dev, &usb_host, &usbh_state_core);/* start the USB core */hcd_init(&usb_core_dev, USB_FS_CORE_ID);/* init usr call back */usb_host.usr_cb->init();/* enable interrupts */usb_hwp_interrupt_enable(&usb_core_dev);rt_thread_t thread = rt_thread_create("usbh", rt_usbh_thread_entry, RT_NULL, USB_THREAD_STACK_SIZE, 8, 20);if(thread != RT_NULL){/* startup usb host thread */rt_thread_startup(thread);}
}
MSH_CMD_EXPORT(usb_host_init,udisk init);int udisk_mount(void)
{/*查找Flash设备*/if(rt_device_find("usbh") != RT_NULL) {/*挂载Flash*/if(dfs_mount("usbh", UDISK_MOUNTPOINT, "elm", 0, 0) == 0){rt_kprintf("flash mount success!\n");} else {rt_kprintf("flash mount failed!\n");}}return 0;
}
MSH_CMD_EXPORT(udisk_mount,udisk mount);void udisk_unmount(void)
{if(dfs_unmount(UDISK_MOUNTPOINT) == 0){rt_kprintf("unmount %s success!\n",UDISK_MOUNTPOINT);} else {rt_kprintf("unmount %s failed!\n",UDISK_MOUNTPOINT);}
}
MSH_CMD_EXPORT(udisk_unmount,udisk unmount);

2、修改usb_host.c文件最上面的头文件为图中文件。

3、在usb_host.h文件中添加代码。

#ifndef __USB_HOST_H
#define __USB_HOST_H#include <rtthread.h>
#include "usb_delay.h"
#include "usbh_core.h"
#include "usbh_usr.h"
#include "usbh_msc_core.h"
#include "usbh_std.h"
#include "usbh_ctrl.h"
#include "usbh_int.h"
#include "diskio.h"
#include "string.h"
#include "udisk.h"void usb_host_init(void);#endif

4、根据提示删除usb_conf.h中的#include “gd32e103r_start.h”,删除后如图所示。

5、修改udisk.c最上面代码,修改成图中代码。

6、添加以下代码到udisk.h中

#ifndef __UDISK_H
#define __UDISK_H#include <rtthread.h>
#include <dfs_fs.h>int udisk_get_id(void);
void udisk_free_id(int id);
rt_err_t rt_udisk_init(rt_device_t dev);
rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,rt_size_t size);
rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer,rt_size_t size);
rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args);#endif

7、添加全局宏USE_USBFS

8、将以下出现的函数替换掉usbh_usr.c中一样的函数。

/*!\brief      user operation for host-mode initialization\param[in]  none\param[out] none\retval     none
*/
void usbh_user_init(void)
{}/*!\brief      user operation for device attached\param[in]  none\param[out] none\retval     none
*/
void usbh_user_device_connected(void)
{usbh_usr->connected_status = USBH_USR_CONNECTED;rt_kprintf("udisk connected\r\n");
}/*!\brief      user operation for device disconnect event\param[in]  none\param[out] none\retval     none
*/
void usbh_user_device_disconnected (void)
{usbh_usr->connected_status = USBH_USR_DISCONNECTED;usbh_usr->init_status = USBH_USR_NOT_READY;rt_kprintf("udisk disconnected\r\n");
}/*!\brief      user action for application state entry\param[in]  none\param[out] none\retval     user response for user key
*/
usbh_user_status_enum usbh_user_userinput(void)
{//未就绪,准备初始化if(usbh_usr->init_status == USBH_USR_NOT_READY)return USBH_USER_RESP_OK;return USBH_USER_NO_RESP;
}/*!\brief      demo application for mass storage\param[in]  pudev: pointer to device\param[in]  id: no use here\param[out] none\retval     status
*/
int usbh_usr_msc_application(usb_core_handle_struct *pudev, uint8_t id)
{if(usbh_usr->init_status == USBH_USR_NOT_READY){rt_kprintf("usbh msc init successfully.\r\n");usbh_usr->init_status = USBH_USR_READY;}return 0;
}/*!\brief      deinit user state and associated variables\param[in]  none\param[out] none\retval     none
*/
void usbh_user_deinit(void)
{}

9、删除usbh_usr.c中explore_disk函数,注意也要删除对应头文件explore_disk函数声明。
10、修改usbh_usr.c图中部分。

#include <rtthread.h>
#include <string.h>
#include "usbh_usr.h"
#include "ff.h"
#include "usbh_msc_core.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"usbh_usr_struct *usbh_usr;

11、在usbh_usr.h中添加以下代码。

#include "ff.h"
#include "usbh_core.h"
#include "usb_conf.h"
#include "usbh_msc_core.h"
#include "usb_std.h"
#include <stdio.h>#define USBH_USR_CONNECTED          1
#define USBH_USR_DISCONNECTED       0#define USBH_USR_READY             1
#define USBH_USR_NOT_READY          0

12、编译根据提示的FALSE和TRUE修改成RT_FALSE和RT_TRUE。
13、修改usbh_msc_scsi.c和usbh_msc_scsi.h。



14、在rt_config.h添加以下代码

#define RT_USBH_MSTORAGE
#define UDISK_MOUNTPOINT "/udisk"

15、修改udisk.c中rt_udisk_read、rt_udisk_write、rt_udisk_control函数

/*** This function will read some data from a device.** @param dev the pointer of device driver structure* @param pos the position of reading* @param buffer the data buffer to save read data* @param size the size of buffer** @return the actually read size on successful, otherwise negative returned.*/
rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,rt_size_t size)
{BYTE status = USBH_MSC_OK;if (hcd_is_device_connected(&usb_core_dev)) stat &= ~USBH_MSC_STA_NOINIT;if (!size)return 0;if (stat & USBH_MSC_STA_NOINIT)return 0;if (hcd_is_device_connected(&usb_core_dev)){do{status = usbh_msc_read10(&usb_core_dev, buffer, pos, 512 * size);usbh_msc_handle_botxfer(&usb_core_dev, &usb_host,  &usbh_state_core);if(!hcd_is_device_connected(&usb_core_dev)){return 0;}}while(USBH_MSC_BUSY == status);}if(USBH_MSC_OK == status)return size;return 0;
}/*** This function will write some data to a device.** @param dev the pointer of device driver structure* @param pos the position of written* @param buffer the data buffer to be written to device* @param size the size of buffer** @return the actually written size on successful, otherwise negative returned.*/
rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer,rt_size_t size)
{BYTE status = USBH_MSC_OK;if (hcd_is_device_connected(&usb_core_dev)) stat &= ~USBH_MSC_STA_NOINIT;if (!size) return 0;if (stat & USBH_MSC_STA_NOINIT) return 0;if (stat & USBH_MSC_STA_PROTECT) return 0;if (hcd_is_device_connected(&usb_core_dev)) {do {status = usbh_msc_write10(&usb_core_dev, (BYTE*)buffer, pos, 512 * size);usbh_msc_handle_botxfer(&usb_core_dev, &usb_host,  &usbh_state_core);if (!hcd_is_device_connected(&usb_core_dev)) {return 0;}} while(USBH_MSC_BUSY == status);}if (USBH_MSC_OK == status) return size;return 0;
}/*** This function will execute SCSI_INQUIRY_CMD command to get inquiry data.** @param intf the interface instance.* @param buffer the data buffer to save inquiry data** @return the error code, RT_EOK on successfully.*/
rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args)
{if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME){struct rt_device_blk_geometry *geometry;geometry = (struct rt_device_blk_geometry *)args;if (geometry == RT_NULL) return -RT_ERROR;geometry->bytes_per_sector = SECTOR_SIZE;geometry->block_size = 512;geometry->sector_count = 512;}return RT_EOK;
}

16、删除udisk.c中rt_udisk_run和rt_udisk_stop函数。
16、在udisk.c中添加以下代码。

static volatile USBH_MSC_DSTATUS stat = USBH_MSC_STA_NOINIT; /* disk status */extern usb_core_handle_struct          usb_core_dev;
extern usbh_host_struct                usb_host;
extern usbh_state_handle_struct        usbh_state_core;

17、添加代码到udisk.h。

#ifndef __UDISK_H
#define __UDISK_H#include <rtthread.h>
#include <dfs_fs.h>int udisk_get_id(void);
void udisk_free_id(int id);
rt_err_t rt_udisk_init(rt_device_t dev);
rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,rt_size_t size);
rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer,rt_size_t size);
rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args);#endif

18、删掉udisk.c中udisk_get_id、udisk_free_id和rt_udisk_init函数的static。
19、修改可挂载数量为3。

20、扩大动态内存为31k。

21、编译通过,运行测试。

22、源码下载,里面有一个未移植USB-Host代码工程,一个是已移植USB-Host的代码工程。

四、源码下载

源码----

总结

下班躺尸...

RT-Thread:GD32E103 移植USB HOST相关推荐

  1. RT-thread应用讲解——U盘(usb host)

    RT-thread应用讲解--U盘(usb host) 目录 RT-thread应用讲解--U盘(usb host) 前言 一.STM32CubeMX配置 二.ENV配置 1.使能USB Host 2 ...

  2. STM32之独立版USB(Host)驱动+MSC+Fatfs移植

    源:STM32之独立版USB(Host)驱动+MSC+Fatfs移植 STM32之USB驱动库详解(架构+文件+函数+使用说明+示例程序)

  3. Real6410移植linux-2.6.39.1记录(3)-USB驱动移植(USB HOST以及USB OTG)

    // 主题:Real6410移植linux-2.6.39.1 // 作者:kevinjz2010@gmail.com // 版权:kevinjz原创 // 平台:linux-2.39.1 real64 ...

  4. RT Thread Free Modbus移植问题整理

    RT Thread Free Modbus移植问题整理 问题描述: 在读写寄存器中,写数据正常,只能读1个寄存器的值,多个值会异常. 在移植过程中发现串口(或RS485)数据接收长度异常. 一.环境描 ...

  5. 正点原子delay函数移植到rt thread操作系统(HAL库)

    正点原子教程中涉及到的操作系统只涉及了UCOS的教程,其中例程的system文件夹中的delay.c函数只是适配了UCOS. 下面将delay.c函数移植到rt thread中,使用的bsp是rt t ...

  6. Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32

    1.前言     [2014年4月重写该博文]     经过若干时间的努力终于搞定了STM32+LwIP和yeelink平台的数据互通,在学习的过程中大部分时间花在以太网协议栈学习上,但是在RT Th ...

  7. 基于rt thread smart构建EtherCAT主站

    我把源码开源到到了gitee,https://gitee.com/rathon/rt-thread-smart-soem 有兴趣的去可以下载下来跑一下 软件工程推荐用vscode 打开.rt thre ...

  8. 安卓USB开发教程 二 USB Host

    USB Host(主机模式) 当 Android 设备处于 USB 主机模式时,它充当 USB 主机,为总线供电,并枚举连接的 USB 设备.Android 3.1 及更高版本支持 USB 主机模式. ...

  9. Linux驱动移植USB网卡r8156驱动(详细)总结

    目录 一.简介 二.驱动移植 2.1 驱动源码解压 2.2 驱动Kconfig和Makefile配置 2.2.1 驱动上层目录识别驱动文件 2.2.2 驱动目录新建驱动Kconfig和Makefile ...

最新文章

  1. Sublime Text安装与使用
  2. 用MATLAB画桌子,怎样用matlab编写桌子的动态变化图
  3. 最新Kernel 2.6.29正式版发布啦
  4. 200道物理学难题——038蚱蜢跃树
  5. 安卓通过js与网页的H5页面进行交换
  6. Pytest之自定义mark
  7. MATLAB信号处理之离散时间系统的时域分析
  8. 数据结构之二叉树--转载
  9. UOJ#269. 【清华集训2016】如何优雅地求和
  10. 变形金刚图纸_变形金刚救援
  11. Linux--进程组 作业 会话 守护(精灵)进程
  12. 车牌识别sdk android,Android车牌识别sdk
  13. 图像任意角度旋转和翻转(C#)
  14. 2021年计算机网络工程师真题,2021年计算机四级网络工程师题库完整版完整答案.doc...
  15. 如何配置android的adb环境变量,windows系统下配置adb环境变量的方法步骤
  16. 关于Hilbert矩阵的几道编程题
  17. 公主与骑士-ZZUOJ
  18. UI入门必读!完整的UI设计学习流程是怎样的?
  19. 树莓派博通BCM2835芯片手册导读及io口驱动代码的实现
  20. 基于python和Opencv将多张图片结合为一张图片的办法

热门文章

  1. Windows 组策略 应用
  2. 计算机二级c语言预测,计算机二级C语言考前预测上机试题及解析
  3. 实验3-1 求一元二次方程的根 (20分)
  4. 程序员学c语言吗,为什么程序员要学C语言
  5. 关于如何关闭445端口
  6. 实现永久关闭445服务
  7. ubuntu的gnome环境下使用todesk远程工具
  8. 向Linux增加一个系统调用或内核模块
  9. linux进程调度算法,关于嵌入式Linux系统实时进程调度算法系统详解
  10. php生成值班表,EXCEL表制作自动排列值班表【excel值班表表格制作教程】