1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

tests: add test application for usbus msc

Signed-off-by: Dylan Laduranty <dylan.laduranty@mesotic.com>
This commit is contained in:
Dylan Laduranty 2022-11-25 21:16:25 +01:00
parent 854d3b7e94
commit 3671b009d8
4 changed files with 269 additions and 0 deletions

30
tests/usbus_msc/Makefile Normal file
View File

@ -0,0 +1,30 @@
BOARD ?= same54-xpro
include ../Makefile.tests_common
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
USEMODULE += auto_init_usbus
USEMODULE += mtd
USEMODULE += mtd_write_page
USEMODULE += ps
USEMODULE += shell
USEMODULE += usbus_msc
USEMODULE += ztimer_msec
# Purposely disable auto_attach for this application
CFLAGS += -DCONFIG_USBUS_AUTO_ATTACH=0
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
USB_VID ?= $(USB_VID_TESTING)
USB_PID ?= $(USB_PID_TESTING)
include $(RIOTBASE)/Makefile.include

53
tests/usbus_msc/README.md Normal file
View File

@ -0,0 +1,53 @@
# USBUS Mass Storage Class (MSC) test application
## Overview
This application uses RIOT USBUS device stack to associate a MTD device and
exports it as Mass Storage Class on your host computer.
**Please note:** RIOT doesn't own any USB vendor and product ID. The test
application therefore uses `USB_VID_TESTING=0x1209` as manufacturer ID and
`USB_PID_TESTING=0x7d01` as product ID. Do not use these IDs outside of
test environments! They MUST NOT be used on any device that is redistributed,
sold or manufactured, as they are not unique!
To compile this application with your own vendor and product ID, set the
variables `USB_VID` and `USB_PID` in the makefile or at the command line,
for example
```
USB_VID=1234 USB_PID=5678 BOARD=... make -C tests/pkg_tinyusb_cdc_msc
```
## Usage
Once the application is flashed, the device should start a shell.
By default, the USB device is not attached to your host computer.
From RIOT shell, you should be able to list your MTD devices available onboard
with the command:
`add_lun` without arguments
From there you can decide to export one or several MTD devices using the
command:
`add_lun`
Once all the wanted MTD devices are selected, user should start the USB device
by attaching it to the host with the command:
`usb_attach`
At this point, the USBUS stack will export the selected MTD devices.
Devices should appears under /dev/sdX entries.
**Notes:** Depending on the MTD device and the USB speed, this operation can take some times.
USB operation can be stopped at any time using:
`usb_detach`
## Limitations
There is a few limitations that should be taken into account:
- MTD with less that 512 bytes of memory cannot be used with MSC.
- MTD devices with flashpage size > 4096 need to be implemented and thus, won't work for now.
## TODO
- Add support for MTD devices with flashpage size > 4096

View File

@ -0,0 +1,5 @@
CONFIG_MODULE_PS=y
CONFIG_MODULE_SHELL=y
CONFIG_MODULE_USBUS=y
CONFIG_MODULE_USBUS_MSC=y
CONFIG_MODULE_ZTIMER_MSEC=y

181
tests/usbus_msc/main.c Normal file
View File

@ -0,0 +1,181 @@
/*
* Copyright (C) 2019-2022 Mesotic SAS
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for demonstrating USBUS MSC implementation
*
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
*
* @}
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "mtd.h"
#include "shell.h"
#include "usb/usbus.h"
#include "usb/usbus/msc.h"
#include "ztimer.h"
#ifndef MTD_NUMOF
#define MTD_NUMOF 0
#endif
static char _stack[USBUS_STACKSIZE];
static usbus_t usbus;
static usbus_msc_device_t msc;
static mtd_dev_t *_get_mtd_dev(unsigned idx)
{
switch (idx) {
#ifdef MTD_0
case 0: return MTD_0;
#endif
#ifdef MTD_1
case 1: return MTD_1;
#endif
#ifdef MTD_2
case 2: return MTD_2;
#endif
#ifdef MTD_3
case 3: return MTD_3;
#endif
}
return NULL;
}
static int _cmd_add_lun(int argc, char **argv)
{
int dev, ret;
mtd_dev_t *mtd_dev;
if (argc < 2) {
printf("usage: %s <mtd dev>\n", argv[0]);
puts("\tMTD devices available:");
for (int i = 0; i < (int)MTD_NUMOF; i++) {
printf("\t\t%i: MTD_DEV(%i)\n", i, i);
}
return -1;
}
/* parse the given MTD device */
dev = atol(argv[1]);
if (dev < 0 || dev >= (int)MTD_NUMOF) {
puts("error: invalid MTD device specified");
return -2;
}
mtd_dev = _get_mtd_dev(dev);
ret = usbus_msc_add_lun(&usbus, mtd_dev);
if (ret != 0) {
printf("Cannot add LUN device (error:%d %s)\n", ret, strerror(-ret));
}
return 0;
}
static int _cmd_remove_lun(int argc, char **argv)
{
int dev, ret;
mtd_dev_t *mtd_dev;
if (argc < 2) {
printf("usage: %s <mtd dev>\n", argv[0]);
puts("\tMTD devices available:");
for (int i = 0; i < (int)MTD_NUMOF; i++) {
printf("\t\t%i: MTD_DEV(%i)\n", i, i);
}
return -1;
}
/* parse the given MTD device */
dev = atol(argv[1]);
if (dev < 0 || dev >= (int)MTD_NUMOF) {
puts("error: invalid MTD device specified");
return -2;
}
mtd_dev = _get_mtd_dev(dev);
ret = usbus_msc_remove_lun(&usbus, mtd_dev);
if (ret == -EAGAIN) {
printf("MTD device was not registered\n");
}
return 0;
}
static int _cmd_usb_attach(int argc, char **argv)
{
(void)argc;
(void)argv;
static const usbopt_enable_t _enable = USBOPT_ENABLE;
usbdev_set(usbus.dev, USBOPT_ATTACH, &_enable,
sizeof(usbopt_enable_t));
return 0;
}
static int _cmd_usb_detach(int argc, char **argv)
{
(void)argc;
(void)argv;
static const usbopt_enable_t _enable = USBOPT_DISABLE;
usbdev_set(usbus.dev, USBOPT_ATTACH, &_enable,
sizeof(usbopt_enable_t));
return 0;
}
static int _cmd_usb_reset(int argc, char **argv)
{
_cmd_usb_detach(argc, argv);
ztimer_sleep(ZTIMER_MSEC, 100);
_cmd_usb_attach(argc, argv);
return 0;
}
static const shell_command_t shell_commands[] = {
{ "add_lun", "Add a MTD device as new LUN", _cmd_add_lun },
{ "remove_lun", "Remove existing LUN", _cmd_remove_lun },
{ "usb_attach", "Attach USB to host", _cmd_usb_attach },
{ "usb_detach", "Detach USB from host", _cmd_usb_detach },
{ "usb_reset", "Combine Detach and Attach with a 100ms delay", _cmd_usb_reset },
{ NULL, NULL, NULL }
};
int main(void)
{
puts("RIOT USB MSC test application");
puts("Add one or more MTD devices as USB LUN");
puts("Then use the attach command to connect");
puts("your device and start USB operation");
/* Get driver context */
usbdev_t *usbdev = usbdev_get_ctx(0);
assert(usbdev);
/* Initialize basic usbus struct, don't start the thread yet */
usbus_init(&usbus, usbdev);
/* Initialize Mass Storage Class */
usbus_msc_init(&usbus, &msc);
/* Create USBUS thread */
usbus_create(_stack, USBUS_STACKSIZE, USBUS_PRIO, USBUS_TNAME, &usbus);
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
/* should be never reached */
return 0;
}