update rtt dfs port
This commit is contained in:
@@ -137,12 +137,15 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
|||||||
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
|
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
|
||||||
src += Glob('demo/usb_host.c')
|
src += Glob('demo/usb_host.c')
|
||||||
|
|
||||||
|
if GetDepend('RT_USING_DFS'):
|
||||||
|
src += Glob('third_party/rt-thread-5.0/dfs_usbh_msc.c')
|
||||||
|
|
||||||
if GetDepend(['PKG_CHERRYUSB_HOST_CP210X']):
|
if GetDepend(['PKG_CHERRYUSB_HOST_CP210X']):
|
||||||
path += [cwd + '/class/vendor/cp201x']
|
path += [cwd + '/class/vendor/cp201x']
|
||||||
src += Glob('class/vendor/cp201x/usbh_cp210x.c')
|
src += Glob('class/vendor/cp201x/usbh_cp210x.c')
|
||||||
src += Glob('third_party/rt-thread-4.1.1/dfs/drv_usbh_cp210x_rtt.c')
|
src += Glob('third_party/rt-thread-4.1.1/dfs/drv_usbh_cp210x_rtt.c')
|
||||||
|
|
||||||
src += Glob('third_party/rt-thread-4.1.1/msh_cmd.c')
|
src += Glob('third_party/rt-thread-5.0/msh_cmd.c')
|
||||||
|
|
||||||
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
|
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
|
||||||
|
|
||||||
|
|||||||
@@ -1,299 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file usbh_cp210x.c
|
|
||||||
* @author 262666882@qq.com
|
|
||||||
* @brief 从linux驱动移植过来的,支持cp210x芯片。目前只做了简单测试,基本功能可用。
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2023-07-05
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "rtthread.h"
|
|
||||||
#include "rtdevice.h"
|
|
||||||
|
|
||||||
#include "usbh_cp210x.h"
|
|
||||||
|
|
||||||
struct usbh_cp210x_static_device {
|
|
||||||
struct rt_device parent;
|
|
||||||
|
|
||||||
struct usbh_cp210x *p_device;
|
|
||||||
struct rt_mutex lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CS5 00000000
|
|
||||||
#define CS6 00000400
|
|
||||||
#define CS7 00001000
|
|
||||||
#define CS8 00001400
|
|
||||||
|
|
||||||
#define CSTOPB 00002000
|
|
||||||
#define PARENB 00010000
|
|
||||||
#define PARODD 00020000
|
|
||||||
|
|
||||||
#define CMSPAR 010000000000 /* mark or space (stick) parity */
|
|
||||||
|
|
||||||
#define DEV_COUNT 4
|
|
||||||
static struct usbh_cp210x_static_device g_devices[DEV_COUNT];
|
|
||||||
|
|
||||||
void drv_usbh_cp210x_run(struct usbh_cp210x *p_device)
|
|
||||||
{
|
|
||||||
struct usbh_cp210x_static_device *p_dev_static = g_devices + p_device->index;
|
|
||||||
rt_mutex_take(&p_dev_static->lock, RT_WAITING_FOREVER);
|
|
||||||
p_dev_static->p_device = p_device;
|
|
||||||
rt_mutex_release(&p_dev_static->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drv_usbh_cp210x_stop(struct usbh_cp210x *p_device)
|
|
||||||
{
|
|
||||||
int index = p_device->index;
|
|
||||||
rt_mutex_take(&g_devices[index].lock, RT_WAITING_FOREVER);
|
|
||||||
g_devices[index].p_device = 0;
|
|
||||||
rt_mutex_release(&g_devices[index].lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1 /** FIXME: not tested */
|
|
||||||
static void __cp210x_set(struct usbh_cp210x *p_dev, int brate, int bits, int stopb, int parity, int hwctrl)
|
|
||||||
{
|
|
||||||
memset(&p_dev->drv_data.termios, 0, sizeof(p_dev->drv_data.termios));
|
|
||||||
p_dev->drv_data.termios.c_iflag = 0;
|
|
||||||
p_dev->drv_data.termios.c_oflag = 0;
|
|
||||||
if (bits == 8)
|
|
||||||
p_dev->drv_data.termios.c_cflag = CS8;
|
|
||||||
else if (bits == 7)
|
|
||||||
p_dev->drv_data.termios.c_cflag = CS7;
|
|
||||||
else if (bits == 6)
|
|
||||||
p_dev->drv_data.termios.c_cflag = CS6;
|
|
||||||
else if (bits == 5)
|
|
||||||
p_dev->drv_data.termios.c_cflag = CS5;
|
|
||||||
else
|
|
||||||
p_dev->drv_data.termios.c_cflag = CS8;
|
|
||||||
|
|
||||||
int c_cflag_p = 0;
|
|
||||||
switch (parity) {
|
|
||||||
case PARITY_NONE:
|
|
||||||
break;
|
|
||||||
case PARITY_EVEN:
|
|
||||||
c_cflag_p = PARENB;
|
|
||||||
break;
|
|
||||||
case PARITY_ODD:
|
|
||||||
c_cflag_p = PARENB | PARODD;
|
|
||||||
break;
|
|
||||||
//case PARITY_SPACE: c_cflag_p=PARENB|CMSPAR; break;
|
|
||||||
//case PARITY_MARK: c_cflag_p=PARENB|CMSPAR|PARODD; break;
|
|
||||||
}
|
|
||||||
int stopbits = 0; /* 1 stopbit default */
|
|
||||||
if (stopb == 2) {
|
|
||||||
stopbits = CSTOPB;
|
|
||||||
}
|
|
||||||
p_dev->drv_data.termios.c_cflag |= c_cflag_p | stopbits;
|
|
||||||
|
|
||||||
p_dev->drv_data.termios.c_lflag = 0;
|
|
||||||
p_dev->drv_data.termios.c_cc[0] = 0;
|
|
||||||
p_dev->drv_data.termios.c_ospeed = brate;
|
|
||||||
cp210x_set_termios(&p_dev->drv_data);
|
|
||||||
cp210x_break_ctl(&p_dev->drv_data, hwctrl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static rt_err_t __init(struct rt_device *dev)
|
|
||||||
{
|
|
||||||
rt_err_t result = RT_EOK;
|
|
||||||
/*struct usbh_cp210x_static_device *p_this;*/
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
/*p_this = (struct usbh_cp210x_static_device *)dev;*/
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t __open(struct rt_device *dev, rt_uint16_t oflag)
|
|
||||||
{
|
|
||||||
rt_uint16_t stream_flag = 0;
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
|
|
||||||
/* keep steam flag */
|
|
||||||
if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM))
|
|
||||||
stream_flag = RT_DEVICE_FLAG_STREAM;
|
|
||||||
|
|
||||||
/* get open flags */
|
|
||||||
dev->open_flag = oflag & 0xff;
|
|
||||||
/* set stream flag */
|
|
||||||
dev->open_flag |= stream_flag;
|
|
||||||
//dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t __close(struct rt_device *dev)
|
|
||||||
{
|
|
||||||
struct usbh_cp210x_static_device *p_this;
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
p_this = (struct usbh_cp210x_static_device *)dev;
|
|
||||||
(void)p_this;
|
|
||||||
|
|
||||||
/* this device has more reference count */
|
|
||||||
if (dev->ref_count > 1)
|
|
||||||
return RT_EOK;
|
|
||||||
|
|
||||||
dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_ssize_t __read(struct rt_device *dev,
|
|
||||||
rt_off_t pos,
|
|
||||||
void *buffer,
|
|
||||||
rt_size_t size)
|
|
||||||
{
|
|
||||||
struct usbh_cp210x_static_device *p_this;
|
|
||||||
rt_ssize_t ret;
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p_this = (struct usbh_cp210x_static_device *)dev;
|
|
||||||
|
|
||||||
rt_mutex_take(&p_this->lock, RT_WAITING_FOREVER);
|
|
||||||
struct usbh_cp210x *p_device = p_this->p_device;
|
|
||||||
if (!p_device) {
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
struct usbh_urb *urb = &p_device->bulkout_urb;
|
|
||||||
memset(urb, 0, sizeof(struct usbh_urb));
|
|
||||||
|
|
||||||
usbh_bulk_urb_fill(urb, p_device->bulkin, buffer, size, 500, NULL, NULL);
|
|
||||||
ret = usbh_submit_urb(urb);
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_ssize_t __write(struct rt_device *dev,
|
|
||||||
rt_off_t pos,
|
|
||||||
const void *buffer,
|
|
||||||
rt_size_t size)
|
|
||||||
{
|
|
||||||
struct usbh_cp210x_static_device *p_this;
|
|
||||||
rt_ssize_t ret;
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
if (size == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p_this = (struct usbh_cp210x_static_device *)dev;
|
|
||||||
|
|
||||||
rt_mutex_take(&p_this->lock, RT_WAITING_FOREVER);
|
|
||||||
struct usbh_cp210x *p_device = p_this->p_device;
|
|
||||||
if (!p_device) {
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
struct usbh_urb *urb = &p_device->bulkout_urb;
|
|
||||||
memset(urb, 0, sizeof(struct usbh_urb));
|
|
||||||
|
|
||||||
usbh_bulk_urb_fill(urb, p_device->bulkout, (uint8_t *)buffer, size, 500, NULL, NULL);
|
|
||||||
ret = usbh_submit_urb(urb);
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t __control(struct rt_device *dev,
|
|
||||||
int cmd,
|
|
||||||
void *args)
|
|
||||||
{
|
|
||||||
rt_err_t ret = RT_EOK;
|
|
||||||
struct usbh_cp210x_static_device *p_this;
|
|
||||||
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
p_this = (struct usbh_cp210x_static_device *)dev;
|
|
||||||
|
|
||||||
(void)p_this;
|
|
||||||
|
|
||||||
rt_mutex_take(&p_this->lock, RT_WAITING_FOREVER);
|
|
||||||
struct usbh_cp210x *p_device = p_this->p_device;
|
|
||||||
if (!p_device) {
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case RT_DEVICE_CTRL_SUSPEND:
|
|
||||||
/* suspend device */
|
|
||||||
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RT_DEVICE_CTRL_RESUME:
|
|
||||||
/* resume device */
|
|
||||||
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RT_DEVICE_CTRL_CONFIG:
|
|
||||||
/** FIXME: not tested */
|
|
||||||
#if 1
|
|
||||||
if (args) {
|
|
||||||
struct serial_configure *pconfig = (struct serial_configure *)args;
|
|
||||||
__cp210x_set(p_device, pconfig->baud_rate, pconfig->data_bits, pconfig->stop_bits, pconfig->parity, pconfig->flowcontrol);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_mutex_release(&p_this->lock);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RT_USING_DEVICE_OPS
|
|
||||||
const static struct rt_device_ops p_this_ops = {
|
|
||||||
__init,
|
|
||||||
__open,
|
|
||||||
__close,
|
|
||||||
__read,
|
|
||||||
__write,
|
|
||||||
__control
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void __device_register(const char *name, int index)
|
|
||||||
{
|
|
||||||
rt_uint32_t flag = 0;
|
|
||||||
struct rt_device *device;
|
|
||||||
|
|
||||||
struct usbh_cp210x_static_device *p_dev = g_devices + index;
|
|
||||||
|
|
||||||
memset(p_dev, 0, sizeof(*p_dev));
|
|
||||||
|
|
||||||
device = &(p_dev->parent);
|
|
||||||
|
|
||||||
device->type = RT_Device_Class_Char;
|
|
||||||
device->rx_indicate = RT_NULL;
|
|
||||||
device->tx_complete = RT_NULL;
|
|
||||||
|
|
||||||
#ifdef RT_USING_DEVICE_OPS
|
|
||||||
device->ops = &p_this_ops;
|
|
||||||
#else
|
|
||||||
device->init = __init;
|
|
||||||
device->open = __open;
|
|
||||||
device->close = __close;
|
|
||||||
device->read = __read;
|
|
||||||
device->write = __write;
|
|
||||||
device->control = __control;
|
|
||||||
#endif
|
|
||||||
device->user_data = 0;
|
|
||||||
rt_mutex_init(&p_dev->lock, "USBx", 0);
|
|
||||||
|
|
||||||
/* register a character device */
|
|
||||||
rt_device_register(device, name, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_all_ttyusb_devices(void)
|
|
||||||
{
|
|
||||||
__device_register("ttyU0", 0);
|
|
||||||
__device_register("ttyU1", 1);
|
|
||||||
__device_register("ttyU2", 2);
|
|
||||||
__device_register("ttyU3", 3);
|
|
||||||
}
|
|
||||||
343
third_party/rt-thread-4.1.1/dfs/udisk.c
vendored
343
third_party/rt-thread-4.1.1/dfs/udisk.c
vendored
@@ -1,343 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-12-12 Yi Qiu first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <dfs_fs.h>
|
|
||||||
|
|
||||||
#include "usbh_core.h"
|
|
||||||
#include "usbh_msc.h"
|
|
||||||
|
|
||||||
#define MAX_PARTITION_COUNT 5
|
|
||||||
#define CONFIG_DFS_MOUNT_POINT "/"
|
|
||||||
|
|
||||||
struct ustor_data {
|
|
||||||
struct dfs_partition part;
|
|
||||||
struct usbh_msc *msc_class;
|
|
||||||
int udisk_id;
|
|
||||||
const char path;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ustor {
|
|
||||||
rt_uint32_t capicity[2];
|
|
||||||
|
|
||||||
struct rt_device dev[MAX_PARTITION_COUNT];
|
|
||||||
rt_uint8_t dev_cnt;
|
|
||||||
};
|
|
||||||
typedef struct ustor *ustor_t;
|
|
||||||
|
|
||||||
#define UDISK_MAX_COUNT 8
|
|
||||||
static rt_uint8_t _udisk_idset = 0;
|
|
||||||
|
|
||||||
ustor_t stor_r;
|
|
||||||
|
|
||||||
static int udisk_get_id(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < UDISK_MAX_COUNT; i++) {
|
|
||||||
if ((_udisk_idset & (1 << i)) != 0)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* it should not happen */
|
|
||||||
if (i == UDISK_MAX_COUNT)
|
|
||||||
RT_ASSERT(0);
|
|
||||||
|
|
||||||
_udisk_idset |= (1 << i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void udisk_free_id(int id)
|
|
||||||
{
|
|
||||||
RT_ASSERT(id < UDISK_MAX_COUNT)
|
|
||||||
|
|
||||||
_udisk_idset &= ~(1 << id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize the udisk device
|
|
||||||
*
|
|
||||||
* @param dev the pointer of device driver structure
|
|
||||||
*
|
|
||||||
* @return RT_EOK
|
|
||||||
*/
|
|
||||||
static rt_err_t rt_udisk_init(rt_device_t dev)
|
|
||||||
{
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
|
||||||
rt_size_t size)
|
|
||||||
{
|
|
||||||
rt_err_t ret;
|
|
||||||
struct usbh_msc *msc_class;
|
|
||||||
struct ustor_data *data;
|
|
||||||
|
|
||||||
/* check parameter */
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
RT_ASSERT(buffer != RT_NULL);
|
|
||||||
|
|
||||||
data = (struct ustor_data *)dev->user_data;
|
|
||||||
msc_class = data->msc_class;
|
|
||||||
|
|
||||||
ret = usbh_msc_scsi_read10(msc_class, pos, (rt_uint8_t *)buffer, size);
|
|
||||||
|
|
||||||
if (ret != RT_EOK) {
|
|
||||||
rt_kprintf("usb mass_storage read failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
static rt_size_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
|
||||||
rt_size_t size)
|
|
||||||
{
|
|
||||||
rt_err_t ret;
|
|
||||||
struct usbh_msc *msc_class;
|
|
||||||
struct ustor_data *data;
|
|
||||||
|
|
||||||
/* check parameter */
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
RT_ASSERT(buffer != RT_NULL);
|
|
||||||
|
|
||||||
data = (struct ustor_data *)dev->user_data;
|
|
||||||
msc_class = data->msc_class;
|
|
||||||
|
|
||||||
ret = usbh_msc_scsi_write10(msc_class, pos, (rt_uint8_t *)buffer, size);
|
|
||||||
if (ret != RT_EOK) {
|
|
||||||
rt_kprintf("usb mass_storage write %d sector failed\n", size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args)
|
|
||||||
{
|
|
||||||
struct ustor_data *data;
|
|
||||||
|
|
||||||
/* check parameter */
|
|
||||||
RT_ASSERT(dev != RT_NULL);
|
|
||||||
|
|
||||||
data = (struct ustor_data *)dev->user_data;
|
|
||||||
|
|
||||||
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 = stor_r->capicity[1];
|
|
||||||
geometry->sector_count = stor_r->capicity[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RT_USING_DEVICE_OPS
|
|
||||||
const static struct rt_device_ops udisk_device_ops = {
|
|
||||||
rt_udisk_init,
|
|
||||||
RT_NULL,
|
|
||||||
RT_NULL,
|
|
||||||
rt_udisk_read,
|
|
||||||
rt_udisk_write,
|
|
||||||
rt_udisk_control
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will run udisk driver when usb disk is detected.
|
|
||||||
*
|
|
||||||
* @param intf the usb interface instance.
|
|
||||||
*
|
|
||||||
* @return the error code, RT_EOK on successfully.
|
|
||||||
*/
|
|
||||||
rt_err_t rt_udisk_run(struct usbh_msc *msc_class)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
rt_err_t ret;
|
|
||||||
char dname[8];
|
|
||||||
char sname[8];
|
|
||||||
rt_uint8_t max_lun, *sector, sense[18], inquiry[36];
|
|
||||||
struct dfs_partition part[MAX_PARTITION_COUNT];
|
|
||||||
|
|
||||||
/* check parameter */
|
|
||||||
RT_ASSERT(msc_class != RT_NULL);
|
|
||||||
stor_r = (struct ustor *)rt_malloc(sizeof(struct ustor));
|
|
||||||
rt_memset(stor_r, 0, sizeof(struct ustor));
|
|
||||||
|
|
||||||
/* get the first sector to read partition table */
|
|
||||||
sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE);
|
|
||||||
if (sector == RT_NULL) {
|
|
||||||
rt_kprintf("allocate partition sector buffer failed\n");
|
|
||||||
return -RT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_memset(sector, 0, SECTOR_SIZE);
|
|
||||||
|
|
||||||
/* get the partition table */
|
|
||||||
ret = usbh_msc_scsi_read10(msc_class, 0, sector, 1);
|
|
||||||
if (ret != RT_EOK) {
|
|
||||||
rt_kprintf("read parition table error\n");
|
|
||||||
|
|
||||||
rt_free(sector);
|
|
||||||
return -RT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_PARTITION_COUNT; i++) {
|
|
||||||
/* get the first partition */
|
|
||||||
ret = dfs_filesystem_get_partition(&part[i], sector, i);
|
|
||||||
if (ret == RT_EOK) {
|
|
||||||
struct ustor_data *data = rt_malloc(sizeof(struct ustor_data));
|
|
||||||
rt_memset(data, 0, sizeof(struct ustor_data));
|
|
||||||
data->msc_class = msc_class;
|
|
||||||
data->udisk_id = udisk_get_id();
|
|
||||||
rt_snprintf(dname, 6, "ud%d-%d", data->udisk_id, i);
|
|
||||||
rt_snprintf(sname, 8, "sem_ud%d", i);
|
|
||||||
data->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
|
|
||||||
|
|
||||||
/* register sdcard device */
|
|
||||||
stor_r->dev[i].type = RT_Device_Class_Block;
|
|
||||||
#ifdef RT_USING_DEVICE_OPS
|
|
||||||
stor->dev[i].ops = &udisk_device_ops;
|
|
||||||
#else
|
|
||||||
stor_r->dev[i].init = rt_udisk_init;
|
|
||||||
stor_r->dev[i].read = rt_udisk_read;
|
|
||||||
stor_r->dev[i].write = rt_udisk_write;
|
|
||||||
stor_r->dev[i].control = rt_udisk_control;
|
|
||||||
#endif
|
|
||||||
stor_r->dev[i].user_data = (void *)data;
|
|
||||||
|
|
||||||
rt_device_register(&stor_r->dev[i], dname, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
|
||||||
|
|
||||||
stor_r->dev_cnt++;
|
|
||||||
|
|
||||||
if (dfs_mount(stor_r->dev[i].parent.name, CONFIG_DFS_MOUNT_POINT, "elm", 0, 0) == 0) {
|
|
||||||
rt_kprintf("udisk part %d mount successfully\n", i);
|
|
||||||
} else {
|
|
||||||
rt_kprintf("udisk part %d mount failed\n", i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (i == 0) {
|
|
||||||
struct ustor_data *data = rt_malloc(sizeof(struct ustor_data));
|
|
||||||
rt_memset(data, 0, sizeof(struct ustor_data));
|
|
||||||
data->udisk_id = udisk_get_id();
|
|
||||||
|
|
||||||
/* there is no partition table */
|
|
||||||
data->part.offset = 0;
|
|
||||||
data->part.size = 0;
|
|
||||||
data->msc_class = msc_class;
|
|
||||||
data->part.lock = rt_sem_create("sem_ud", 1, RT_IPC_FLAG_FIFO);
|
|
||||||
|
|
||||||
rt_snprintf(dname, 7, "udisk%d", data->udisk_id);
|
|
||||||
|
|
||||||
/* register sdcard device */
|
|
||||||
stor_r->dev[0].type = RT_Device_Class_Block;
|
|
||||||
#ifdef RT_USING_DEVICE_OPS
|
|
||||||
stor->dev[i].ops = &udisk_device_ops;
|
|
||||||
#else
|
|
||||||
stor_r->dev[0].init = rt_udisk_init;
|
|
||||||
stor_r->dev[0].read = rt_udisk_read;
|
|
||||||
stor_r->dev[0].write = rt_udisk_write;
|
|
||||||
stor_r->dev[0].control = rt_udisk_control;
|
|
||||||
#endif
|
|
||||||
stor_r->dev[0].user_data = (void *)data;
|
|
||||||
|
|
||||||
rt_device_register(&stor_r->dev[0], dname, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
|
||||||
|
|
||||||
stor_r->dev_cnt++;
|
|
||||||
if (dfs_mount(stor_r->dev[0].parent.name, CONFIG_DFS_MOUNT_POINT, "elm", 0, 0) == 0) {
|
|
||||||
rt_kprintf("Mount FAT on Udisk successful.\n");
|
|
||||||
} else {
|
|
||||||
rt_kprintf("Mount FAT on Udisk failed.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_free(sector);
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will be invoked when usb disk plug out is detected and it would clean
|
|
||||||
* and release all udisk related resources.
|
|
||||||
*
|
|
||||||
* @param intf the usb interface instance.
|
|
||||||
*
|
|
||||||
* @return the error code, RT_EOK on successfully.
|
|
||||||
*/
|
|
||||||
rt_err_t rt_udisk_stop(struct usbh_msc *msc_class)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
struct ustor_data *data;
|
|
||||||
|
|
||||||
/* check parameter */
|
|
||||||
RT_ASSERT(msc_class != RT_NULL);
|
|
||||||
|
|
||||||
RT_ASSERT(stor_r != RT_NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < stor_r->dev_cnt; i++) {
|
|
||||||
rt_device_t dev = &stor_r->dev[i];
|
|
||||||
data = (struct ustor_data *)dev->user_data;
|
|
||||||
|
|
||||||
/* unmount filesystem */
|
|
||||||
dfs_unmount(CONFIG_DFS_MOUNT_POINT);
|
|
||||||
|
|
||||||
/* delete semaphore */
|
|
||||||
rt_sem_delete(data->part.lock);
|
|
||||||
udisk_free_id(data->udisk_id);
|
|
||||||
rt_free(data);
|
|
||||||
|
|
||||||
/* unregister device */
|
|
||||||
rt_device_unregister(&stor_r->dev[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_free(stor_r);
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
154
third_party/rt-thread-5.0/dfs_usbh_msc.c
vendored
Normal file
154
third_party/rt-thread-5.0/dfs_usbh_msc.c
vendored
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#include <rtconfig.h>
|
||||||
|
#include "usbh_core.h"
|
||||||
|
#include "usbh_msc.h"
|
||||||
|
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
|
#define DEV_FORMAT "sd%c"
|
||||||
|
|
||||||
|
#define CONFIG_DFS_MOUNT_POINT "/"
|
||||||
|
|
||||||
|
static rt_err_t rt_udisk_init(rt_device_t dev)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||||
|
rt_size_t size)
|
||||||
|
{
|
||||||
|
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = usbh_msc_scsi_read10(msc_class, pos, buffer, size);
|
||||||
|
if (ret < 0) {
|
||||||
|
rt_kprintf("usb mass_storage read failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||||
|
rt_size_t size)
|
||||||
|
{
|
||||||
|
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = usbh_msc_scsi_write10(msc_class, pos, buffer, size);
|
||||||
|
if (ret < 0) {
|
||||||
|
rt_kprintf("usb mass_storage write failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args)
|
||||||
|
{
|
||||||
|
/* check parameter */
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||||
|
|
||||||
|
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 = msc_class->blocksize;
|
||||||
|
geometry->block_size = msc_class->blocksize;
|
||||||
|
geometry->sector_count = msc_class->blocknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_DEVICE_OPS
|
||||||
|
const static struct rt_device_ops udisk_device_ops = {
|
||||||
|
rt_udisk_init,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
rt_udisk_read,
|
||||||
|
rt_udisk_write,
|
||||||
|
rt_udisk_control
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int udisk_init(struct usbh_msc *msc_class)
|
||||||
|
{
|
||||||
|
rt_uint8_t *sector = NULL;
|
||||||
|
rt_err_t ret = 0;
|
||||||
|
rt_uint8_t i;
|
||||||
|
struct dfs_partition part0;
|
||||||
|
struct rt_device *dev;
|
||||||
|
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||||
|
|
||||||
|
dev = rt_malloc(sizeof(struct rt_device));
|
||||||
|
memset(dev, 0, sizeof(struct rt_device));
|
||||||
|
|
||||||
|
snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
|
||||||
|
|
||||||
|
/* get the first sector to read partition table */
|
||||||
|
sector = (rt_uint8_t *)rt_malloc(512);
|
||||||
|
if (sector == RT_NULL) {
|
||||||
|
rt_kprintf("allocate partition sector buffer failed!\n");
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = usbh_msc_scsi_read10(msc_class, 0, sector, 1);
|
||||||
|
if (ret != RT_EOK) {
|
||||||
|
rt_kprintf("usb mass_storage read failed\n");
|
||||||
|
goto free_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
/* Get the first partition */
|
||||||
|
ret = dfs_filesystem_get_partition(&part0, sector, i);
|
||||||
|
if (ret == RT_EOK) {
|
||||||
|
rt_kprintf("Found partition %d: type = %d, offet=0x%x, size=0x%x\n",
|
||||||
|
i, part0.type, part0.offset, part0.size);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->type = RT_Device_Class_Block;
|
||||||
|
#ifdef RT_USING_DEVICE_OPS
|
||||||
|
dev->ops = &udisk_device_ops;
|
||||||
|
#else
|
||||||
|
dev->init = rt_udisk_init;
|
||||||
|
dev->read = rt_udisk_read;
|
||||||
|
dev->write = rt_udisk_write;
|
||||||
|
dev->control = rt_udisk_control;
|
||||||
|
#endif
|
||||||
|
dev->user_data = msc_class;
|
||||||
|
|
||||||
|
rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
||||||
|
|
||||||
|
ret = dfs_mount(name, CONFIG_DFS_MOUNT_POINT, "elm", 0, 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
rt_kprintf("udisk: %s mount successfully\n", name);
|
||||||
|
} else {
|
||||||
|
rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_res:
|
||||||
|
if (sector)
|
||||||
|
rt_free(sector);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_udisk_run(struct usbh_msc *msc_class)
|
||||||
|
{
|
||||||
|
udisk_init(msc_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_udisk_stop(struct usbh_msc *msc_class)
|
||||||
|
{
|
||||||
|
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||||
|
snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
|
||||||
|
|
||||||
|
dfs_unmount(CONFIG_DFS_MOUNT_POINT);
|
||||||
|
rt_device_unregister(rt_device_find(name));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user