RT-Thread:GD32E103 移植USB HOST
文章目录
- 前言
- 一、复制外部源文件到工程中
- 二、添加源文件和头文件路径
- 三、修改源码
- 四、源码下载
- 总结
前言
在原本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相关推荐
- RT-thread应用讲解——U盘(usb host)
RT-thread应用讲解--U盘(usb host) 目录 RT-thread应用讲解--U盘(usb host) 前言 一.STM32CubeMX配置 二.ENV配置 1.使能USB Host 2 ...
- STM32之独立版USB(Host)驱动+MSC+Fatfs移植
源:STM32之独立版USB(Host)驱动+MSC+Fatfs移植 STM32之USB驱动库详解(架构+文件+函数+使用说明+示例程序)
- 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 ...
- RT Thread Free Modbus移植问题整理
RT Thread Free Modbus移植问题整理 问题描述: 在读写寄存器中,写数据正常,只能读1个寄存器的值,多个值会异常. 在移植过程中发现串口(或RS485)数据接收长度异常. 一.环境描 ...
- 正点原子delay函数移植到rt thread操作系统(HAL库)
正点原子教程中涉及到的操作系统只涉及了UCOS的教程,其中例程的system文件夹中的delay.c函数只是适配了UCOS. 下面将delay.c函数移植到rt thread中,使用的bsp是rt t ...
- Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32
1.前言 [2014年4月重写该博文] 经过若干时间的努力终于搞定了STM32+LwIP和yeelink平台的数据互通,在学习的过程中大部分时间花在以太网协议栈学习上,但是在RT Th ...
- 基于rt thread smart构建EtherCAT主站
我把源码开源到到了gitee,https://gitee.com/rathon/rt-thread-smart-soem 有兴趣的去可以下载下来跑一下 软件工程推荐用vscode 打开.rt thre ...
- 安卓USB开发教程 二 USB Host
USB Host(主机模式) 当 Android 设备处于 USB 主机模式时,它充当 USB 主机,为总线供电,并枚举连接的 USB 设备.Android 3.1 及更高版本支持 USB 主机模式. ...
- Linux驱动移植USB网卡r8156驱动(详细)总结
目录 一.简介 二.驱动移植 2.1 驱动源码解压 2.2 驱动Kconfig和Makefile配置 2.2.1 驱动上层目录识别驱动文件 2.2.2 驱动目录新建驱动Kconfig和Makefile ...
最新文章
- Sublime Text安装与使用
- 用MATLAB画桌子,怎样用matlab编写桌子的动态变化图
- 最新Kernel 2.6.29正式版发布啦
- 200道物理学难题——038蚱蜢跃树
- 安卓通过js与网页的H5页面进行交换
- Pytest之自定义mark
- MATLAB信号处理之离散时间系统的时域分析
- 数据结构之二叉树--转载
- UOJ#269. 【清华集训2016】如何优雅地求和
- 变形金刚图纸_变形金刚救援
- Linux--进程组 作业 会话 守护(精灵)进程
- 车牌识别sdk android,Android车牌识别sdk
- 图像任意角度旋转和翻转(C#)
- 2021年计算机网络工程师真题,2021年计算机四级网络工程师题库完整版完整答案.doc...
- 如何配置android的adb环境变量,windows系统下配置adb环境变量的方法步骤
- 关于Hilbert矩阵的几道编程题
- 公主与骑士-ZZUOJ
- UI入门必读!完整的UI设计学习流程是怎样的?
- 树莓派博通BCM2835芯片手册导读及io口驱动代码的实现
- 基于python和Opencv将多张图片结合为一张图片的办法