Skip to content

Commit 0812cae

Browse files
committed
mimxrt: Implement mutual write permission with MSC use.
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform. - When the board is mounted to a PC, local write access is blocked. - Local write access will be re-enabled again if the disk is ejected. - If the board is not connected to a PC on start-up, local write access is enabled. - The status of the write access can be determined by bdev.ioctl(7, 0). If the device is mounted to a PAC and thus local write access is blocked, it return 1, otherwise 0. - low level write/erase using the block device calls are still possible. It is up to the user to check the device status ahead. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent b653caa commit 0812cae

File tree

7 files changed

+63
-12
lines changed

7 files changed

+63
-12
lines changed

extmod/vfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define MP_BLOCKDEV_IOCTL_BLOCK_COUNT (4)
5252
#define MP_BLOCKDEV_IOCTL_BLOCK_SIZE (5)
5353
#define MP_BLOCKDEV_IOCTL_BLOCK_ERASE (6)
54+
#define MP_BLOCKDEV_IOCTL_STATUS (7)
5455

5556
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
5657
typedef struct _mp_vfs_proto_t {

extmod/vfs_fat_diskio.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ DRESULT disk_ioctl(
114114
[GET_SECTOR_COUNT] = MP_BLOCKDEV_IOCTL_BLOCK_COUNT,
115115
[GET_SECTOR_SIZE] = MP_BLOCKDEV_IOCTL_BLOCK_SIZE,
116116
[IOCTL_INIT] = MP_BLOCKDEV_IOCTL_INIT,
117+
[IOCTL_STATUS] = MP_BLOCKDEV_IOCTL_STATUS,
117118
};
118119
uint8_t bp_op = op_map[cmd & 7];
119120
mp_obj_t ret = mp_const_none;
@@ -147,16 +148,21 @@ DRESULT disk_ioctl(
147148
*((DWORD *)buff) = 1; // erase block size in units of sector size
148149
return RES_OK;
149150

150-
case IOCTL_INIT:
151-
case IOCTL_STATUS: {
152-
DSTATUS stat;
151+
case IOCTL_INIT: {
152+
DSTATUS stat = 0;
153153
if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) {
154154
// error initialising
155-
stat = STA_NOINIT;
156-
} else if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL) {
155+
stat = STA_NOINIT;
156+
}
157+
*((DSTATUS *)buff) = stat;
158+
return RES_OK;
159+
}
160+
161+
case IOCTL_STATUS: {
162+
DSTATUS stat = 0;
163+
if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL ||
164+
(ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0)) {
157165
stat = STA_PROTECT;
158-
} else {
159-
stat = 0;
160166
}
161167
*((DSTATUS *)buff) = stat;
162168
return RES_OK;

ports/mimxrt/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ SHARED_SRC_C += \
231231
shared/runtime/pyexec.c \
232232
shared/runtime/softtimer.c \
233233
shared/runtime/stdout_helpers.c \
234+
shared/runtime/tinyusb_helpers.c \
234235
shared/runtime/sys_stdio_mphal.c \
235236
shared/timeutils/timeutils.c \
236237

ports/mimxrt/mimxrt_flash.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ STATIC mimxrt_flash_obj_t mimxrt_flash_obj = {
4646
.base = { &mimxrt_flash_type }
4747
};
4848

49+
extern bool tud_msc_ejected;
50+
4951
STATIC mp_obj_t mimxrt_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
5052
// Check args.
5153
mp_arg_check_num(n_args, n_kw, 0, 0, false);
@@ -133,6 +135,12 @@ STATIC mp_obj_t mimxrt_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t a
133135
status = flash_erase_sector(self->flash_base + offset);
134136
return MP_OBJ_NEW_SMALL_INT(status != kStatus_Success);
135137
}
138+
case MP_BLOCKDEV_IOCTL_STATUS:
139+
#if MICROPY_HW_USB_MSC
140+
return MP_OBJ_NEW_SMALL_INT(!tud_msc_ejected);
141+
#else
142+
return MP_OBJ_NEW_SMALL_INT(false);
143+
#endif
136144
default:
137145
return mp_const_none;
138146
}

ports/mimxrt/mpconfigport.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,13 @@ uint32_t trng_random_u32(void);
156156

157157
// by default do not enable MSC support
158158
#ifndef MICROPY_HW_USB_MSC
159-
#define MICROPY_HW_USB_MSC (0)
159+
#define MICROPY_HW_USB_MSC (1)
160160
#endif
161161

162162
#if MICROPY_HW_USB_MSC
163163
#define MICROPY_FATFS_USE_LABEL (1)
164164
#define MICROPY_FATFS_MULTI_PARTITION (1)
165+
#define MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS (1)
165166
#endif
166167
// Hooks to add builtins
167168

ports/mimxrt/msc_disk.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
#define BLOCK_COUNT (MICROPY_HW_FLASH_STORAGE_BYTES / BLOCK_SIZE)
3535
#define FLASH_BASE_ADDR (MICROPY_HW_FLASH_STORAGE_BASE)
3636

37-
bool ejected = false;
37+
bool tud_msc_ejected = true;
38+
extern void tud_msc_remount(void);
3839

3940
// Invoked when received SCSI_CMD_INQUIRY
4041
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
@@ -46,12 +47,13 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16
4647
strncpy((char *)vendor_id, vid, 8);
4748
strncpy((char *)product_id, pid, 16);
4849
strncpy((char *)product_rev, rev, 4);
50+
tud_msc_ejected = false;
4951
}
5052

5153
// Invoked when received Test Unit Ready command.
5254
// return true allowing host to read/write this LUN e.g SD card inserted
5355
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
54-
if (ejected) {
56+
if (tud_msc_ejected) {
5557
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
5658
return false;
5759
}
@@ -63,6 +65,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) {
6365
void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) {
6466
*block_size = BLOCK_SIZE;
6567
*block_count = BLOCK_COUNT;
68+
tud_msc_ejected = false;
6669
}
6770

6871
// Invoked when received Start Stop Unit command
@@ -72,10 +75,13 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
7275
if (load_eject) {
7376
if (start) {
7477
// load disk storage
75-
ejected = false;
78+
tud_msc_ejected = false;
7679
} else {
7780
// unload disk storage
78-
ejected = true;
81+
tud_msc_ejected = true;
82+
#if MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS
83+
tud_msc_remount();
84+
#endif
7985
}
8086
}
8187
return true;

shared/tinyusb/mp_cdc_common.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,31 @@ tud_cdc_line_state_cb
5858
}
5959

6060
#endif
61+
62+
#if MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS
63+
#include "tusb.h"
64+
#include "extmod/vfs.h"
65+
#include "extmod/vfs_fat.h"
66+
static mp_sched_node_t mp_remount_sched_node;
67+
68+
STATIC void tud_msc_remount_task(mp_sched_node_t *node) {
69+
mp_vfs_mount_t *vfs = NULL;
70+
for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
71+
if (vfs->len == 1) {
72+
const char *path_str = "/";
73+
mp_obj_t path = mp_obj_new_str(path_str, strlen(path_str));
74+
nlr_buf_t nlr;
75+
if (nlr_push(&nlr) == 0) {
76+
mp_vfs_umount(vfs->obj);
77+
mp_vfs_mount_and_chdir_protected(vfs->obj, path);
78+
nlr_pop();
79+
}
80+
break;
81+
}
82+
}
83+
}
84+
85+
void tud_msc_remount(void) {
86+
mp_sched_schedule_node(&mp_remount_sched_node, tud_msc_remount_task);
87+
}
88+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy