Merge pull request 'support auto mount usb host on nuttx for xidatong' (#31) from ok1052 into prepare_for_master

support auto mount usb host on nuttx for xidatong
This commit is contained in:
wgzAIIT 2022-04-08 10:44:04 +08:00
commit e49af0e48c
3 changed files with 200 additions and 2 deletions

View File

@ -53,4 +53,35 @@ config XIDATONG_SDHC_AUTOMOUNT_UDELAY
endif # XIDATONG_SDHC_AUTOMOUNT endif # XIDATONG_SDHC_AUTOMOUNT
config XIDATONG_USB_AUTOMOUNT
bool "USB Mass Storage automounter"
default n
depends on USBHOST_MSC && USBHOST_MSC_NOTIFIER
if XIDATONG_USB_AUTOMOUNT
config XIDATONG_USB_AUTOMOUNT_FSTYPE
string "USB file system type"
default "vfat"
config XIDATONG_USB_AUTOMOUNT_BLKDEV
string "USB block device prefix"
default "/dev/sd"
config XIDATONG_USB_AUTOMOUNT_MOUNTPOINT
string "USB mount point prefix"
default "/mnt/usb"
config XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV
int "Number of block devices to monitor."
range 1 26
default 4
config XIDATONG_USB_AUTOMOUNT_UDELAY
int "USB unmount retry delay (milliseconds)"
default 2000
endif # XIDATONG_USB_AUTOMOUNT
endif endif

View File

@ -27,8 +27,6 @@ CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_HELLO=y
CONFIG_IMXRT_GPIO1_0_15_IRQ=y
CONFIG_IMXRT_GPIO_IRQ=y
CONFIG_IMXRT_LPUART1=y CONFIG_IMXRT_LPUART1=y
CONFIG_INTELHEX_BINARY=y CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_NBUFFERS=24

View File

@ -27,17 +27,21 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <sched.h> #include <sched.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <debug.h> #include <debug.h>
#include <sys/mount.h>
#include <nuttx/fs/fs.h>
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/kthread.h> #include <nuttx/kthread.h>
#include <nuttx/usb/usbdev.h> #include <nuttx/usb/usbdev.h>
#include <nuttx/usb/usbhost.h> #include <nuttx/usb/usbhost.h>
#include <nuttx/usb/usbdev_trace.h> #include <nuttx/usb/usbdev_trace.h>
#include <nuttx/usb/ehci.h> #include <nuttx/usb/ehci.h>
#include <nuttx/wdog.h>
#include <imxrt_ehci.h> #include <imxrt_ehci.h>
@ -74,6 +78,12 @@
static struct usbhost_connection_s *g_ehciconn; static struct usbhost_connection_s *g_ehciconn;
#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT
/* Unmount retry timer */
static struct wdog_s g_umount_tmr[CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV];
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -118,6 +128,148 @@ static int ehci_waiter(int argc, char *argv[])
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT
/****************************************************************************
* Name: usb_msc_connect
*
* Description:
* Mount the USB mass storage device
*
****************************************************************************/
static void usb_msc_connect(FAR void *arg)
{
int index = (int)arg;
char sdchar = 'a' + index;
int ret;
char blkdev[32];
char mntpnt[32];
DEBUGASSERT(index >= 0 &&
index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV);
wd_cancel(&g_umount_tmr[index]);
/* Resetup the event. */
usbhost_msc_notifier_setup(usb_msc_connect, WORK_USB_MSC_CONNECT,
sdchar, arg);
snprintf(blkdev, sizeof(blkdev), "%s%c",
CONFIG_XIDATONG_USB_AUTOMOUNT_BLKDEV, sdchar);
snprintf(mntpnt, sizeof(mntpnt), "%s%c",
CONFIG_XIDATONG_USB_AUTOMOUNT_MOUNTPOINT, sdchar);
/* Mount */
ret = nx_mount((FAR const char *)blkdev, (FAR const char *)mntpnt,
CONFIG_XIDATONG_USB_AUTOMOUNT_FSTYPE, 0, NULL);
if (ret < 0)
{
ferr("ERROR: Mount failed: %d\n", ret);
}
}
/****************************************************************************
* Name: unmount_retry_timeout
*
* Description:
* A previous unmount failed because the volume was busy... busy meaning
* the volume could not be unmounted because there are open references
* the files or directories in the volume. When this failure occurred,
* the unmount logic setup a delay and this function is called as a result
* of that delay timeout.
*
* This function will attempt the unmount again.
*
* Input Parameters:
* Standard wdog timeout parameters
*
* Returned Value:
* None
*
****************************************************************************/
static void unmount_retry_timeout(wdparm_t arg)
{
int index = arg;
char sdchar = 'a' + index;
finfo("Timeout!\n");
DEBUGASSERT(index >= 0 &&
index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV);
/* Resend the notification. */
usbhost_msc_notifier_signal(WORK_USB_MSC_DISCONNECT, sdchar);
}
/****************************************************************************
* Name: usb_msc_disconnect
*
* Description:
* Unmount the USB mass storage device
*
****************************************************************************/
static void usb_msc_disconnect(FAR void *arg)
{
int index = (int)arg;
char sdchar = 'a' + index;
int ret;
char mntpnt[32];
DEBUGASSERT(index >= 0 &&
index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV);
wd_cancel(&g_umount_tmr[index]);
/* Resetup the event. */
usbhost_msc_notifier_setup(usb_msc_disconnect, WORK_USB_MSC_DISCONNECT,
sdchar, arg);
snprintf(mntpnt, sizeof(mntpnt), "%s%c",
CONFIG_XIDATONG_USB_AUTOMOUNT_MOUNTPOINT, sdchar);
/* Unmount */
ret = nx_umount2((FAR const char *)mntpnt, MNT_FORCE);
if (ret < 0)
{
/* We expect the error to be EBUSY meaning that the volume could
* not be unmounted because there are currently reference via open
* files or directories.
*/
if (ret == -EBUSY)
{
finfo("WARNING: Volume is busy, try again later\n");
/* Start a timer to retry the umount2 after a delay */
ret = wd_start(&g_umount_tmr[index],
MSEC2TICK(CONFIG_XIDATONG_USB_AUTOMOUNT_UDELAY),
unmount_retry_timeout, index);
if (ret < 0)
{
ferr("ERROR: wd_start failed: %d\n", ret);
}
}
/* Other errors are fatal */
else
{
ferr("ERROR: Unmount failed!\n");
}
}
}
#endif /* CONFIG_XIDATONG_USB_AUTOMOUNT */
/**************************************************************************** /****************************************************************************
* Name: imxrt_usbhost_initialize * Name: imxrt_usbhost_initialize
* *
@ -133,6 +285,9 @@ int imxrt_usbhost_initialize(void)
{ {
pid_t pid; pid_t pid;
int ret; int ret;
#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT
int index;
#endif
imxrt_clockall_usboh3(); imxrt_clockall_usboh3();
@ -163,6 +318,20 @@ int imxrt_usbhost_initialize(void)
#ifdef CONFIG_USBHOST_MSC #ifdef CONFIG_USBHOST_MSC
/* Register the USB host Mass Storage Class */ /* Register the USB host Mass Storage Class */
#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT
/* Initialize the notifier listener for automount */
for (index = 0; index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV; index++)
{
char sdchar = 'a' + index;
usbhost_msc_notifier_setup(usb_msc_connect,
WORK_USB_MSC_CONNECT, sdchar, (FAR void *)(intptr_t)index);
usbhost_msc_notifier_setup(usb_msc_disconnect,
WORK_USB_MSC_DISCONNECT, sdchar, (FAR void *)(intptr_t)index);
}
#endif
ret = usbhost_msc_initialize(); ret = usbhost_msc_initialize();
if (ret != OK) if (ret != OK)
{ {