Skip to content

Commit 87ca41c

Browse files
committed
tinyusb/msc_fat_view: Configure root dir sector count
One sector for root dir entry was hardcoded. It could be to small if additional entries were added. In that case firmware update could be impossible if Windows of Linux could not fit new file name in root directory. Now root director sector count is configurable in syscfg.yml by MSC_FAT_VIEW_ROOT_DIR_SECTORS Signed-off-by: Jerzy Kasenberg <[email protected]>
1 parent 1bbc09c commit 87ca41c

File tree

2 files changed

+60
-40
lines changed

2 files changed

+60
-40
lines changed

hw/usb/tinyusb/msc_fat_view/src/msc_fat_view.c

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <modlog/modlog.h>
3535
#include <hal/hal_flash.h>
3636
#include <console/console.h>
37+
#include <stream/stream.h>
3738
#include "coredump_files.h"
3839

3940
#if MYNEWT_VAL(BOOT_LOADER)
@@ -76,7 +77,7 @@
7677
#define SECTOR_BIT_COUNT ((SECTOR_SIZE) * 8)
7778

7879
#define DIR_ENTRY_SIZE 32
79-
#define ROOT_SECTOR_COUNT 1
80+
#define ROOT_SECTOR_COUNT MYNEWT_VAL(MSC_FAT_VIEW_ROOT_DIR_SECTORS)
8081

8182
#define FAT_FIRST_SECTOR 1
8283
#define FAT_ROOT_DIR_FIRST_SECTOR ((FAT_FIRST_SECTOR) + (FAT_SECTOR_COUNT) * (FAT_COUNT))
@@ -787,23 +788,20 @@ msc_fat_view_fat_next_cluster(cluster_t cluster, fat_chain_t **cache)
787788
}
788789

789790
static void
790-
msc_fat_view_write_ucs_2(uint8_t *dst, const char **ascii, int len)
791+
msc_fat_view_write_ucs_2(struct out_stream *ostr, const char *ascii, int field_len)
791792
{
792-
for ( ; len; --len) {
793-
if (*ascii) {
794-
if (**ascii) {
795-
*dst++ = **ascii;
796-
*ascii += 1;
797-
} else {
798-
*dst++ = 0;
799-
*ascii = NULL;
800-
}
801-
*dst++ = 0;
793+
for (; ascii && field_len; --field_len) {
794+
ostream_write_uint8(ostr, *ascii);
795+
ostream_write_uint8(ostr, 0);
796+
if (*ascii == '\0') {
797+
ascii = NULL;
802798
} else {
803-
*dst++ = 0xFF;
804-
*dst++ = 0xFF;
799+
++ascii;
805800
}
806801
}
802+
for (; field_len; --field_len) {
803+
ostream_write_uint16(ostr, 0xFFFF);
804+
}
807805
}
808806

809807
static void
@@ -832,34 +830,46 @@ msc_fat_view_short_name_checksum(const char *short_name)
832830
return check_sum;
833831
}
834832

835-
static fat_dir_entry_t *
836-
msc_fat_view_write_long_name_entry(fat_dir_entry_t *buffer, const char *long_name, const char *short_name)
833+
/*
834+
* Return pointer to character in the string if offset is valid
835+
* If offset is outside of the string return NULL
836+
*/
837+
static const char *
838+
long_name_part(const char *long_name, int long_name_len, int long_name_offset)
839+
{
840+
if (long_name_offset > long_name_len + 1) {
841+
return NULL;
842+
}
843+
return long_name + long_name_offset;
844+
}
845+
846+
void
847+
msc_fat_view_write_long_name_entry(struct out_stream *ostr, const char *name,
848+
const char *short_name)
837849
{
838850
int len;
839851
int n;
840852
int i;
841853
uint8_t checksum;
842-
fat_dir_entry_t *p;
854+
int offset;
843855

844-
len = strlen(long_name);
856+
len = strlen(name);
845857
if (len) {
846858
checksum = msc_fat_view_short_name_checksum(short_name);
847859
n = (len + 12) / 13;
848-
buffer += n;
849-
for (i = 1; i <= n; ++i) {
850-
p = buffer - i;
860+
for (i = n; i > 0; --i) {
861+
offset = (i - 1) * 13;
851862
/* First part of long entry has the highest index and 6th bit set */
852-
p->sequence = i + ((i == n) ? 0x40 : 0);
853-
p->attr1 = 0x0f;
854-
p->reserved2 = 0;
855-
p->reserved3 = 0;
856-
p->checksum = checksum;
857-
msc_fat_view_write_ucs_2((uint8_t *)p->name1, &long_name, 5);
858-
msc_fat_view_write_ucs_2((uint8_t *)p->name2, &long_name, 6);
859-
msc_fat_view_write_ucs_2((uint8_t *)p->name3, &long_name, 2);
863+
ostream_write_uint8(ostr, i + ((i == n) ? 0x40 : 0));
864+
msc_fat_view_write_ucs_2(ostr, long_name_part(name, len, offset), 5);
865+
ostream_write_uint8(ostr, 0x0f); /* attrib */
866+
ostream_write_uint8(ostr, 0); /* reserved2 */
867+
ostream_write_uint8(ostr, checksum);
868+
msc_fat_view_write_ucs_2(ostr, long_name_part(name, len, offset + 5), 6);
869+
ostream_write_uint16(ostr, 0); /* reserved3 */
870+
msc_fat_view_write_ucs_2(ostr, long_name_part(name, len, offset + 11), 2);
860871
}
861872
}
862-
return buffer;
863873
}
864874

865875
static char *
@@ -958,35 +968,41 @@ msc_fat_view_read_root_sector(uint16_t dir_sector, uint8_t buffer[512])
958968
int cluster = 2;
959969
int cluster_count;
960970
uint32_t size;
961-
fat_dir_entry_t *dst = (fat_dir_entry_t *)buffer;
971+
struct mem_out_stream mstr;
972+
struct out_stream *ostr = (struct out_stream *)&mstr;
973+
fat_dir_entry_t fat_dir_entry;
962974
dir_entry_t *entry;
963975
char short_name[11];
964976

977+
memset(buffer, 0, 512);
978+
mem_ostream_init(&mstr, buffer, 512);
979+
mstr.write_ptr -= dir_sector * 512;
980+
965981
TU_LOG1("msc_fat_view_read_root %d\n", dir_sector);
966982
for (i = 0; i < root_dir_entry_count; ++i) {
967983
entry = &root_dir[i];
968984
msc_fat_view_create_short_name(entry, short_name);
969985
if (entry->dir_slots > 1) {
970-
dst = msc_fat_view_write_long_name_entry(dst, entry->file->name, short_name);
986+
msc_fat_view_write_long_name_entry(ostr, entry->file->name, short_name);
971987
}
972-
memcpy(dst->name, short_name, 11);
988+
memcpy(fat_dir_entry.bytes, short_name, 11);
973989
/* Clear out rest of the entry */
974-
memset(dst->bytes + 11, 0, 32 - 11);
975-
dst->attr = root_dir[i].file->attributes;
990+
memset(fat_dir_entry.bytes + 11, 0, 32 - 11);
991+
992+
fat_dir_entry.attr = root_dir[i].file->attributes;
976993
if (i > 0) {
977994
assert(root_dir[i].file->size);
978995
size = root_dir[i].file->size(root_dir[i].file);
979996
if (size) {
980997
cluster_count = cluster_count_from_bytes(size);
981-
dst->cluster_hi = htole16((cluster >> 16));
982-
dst->cluster_lo = htole16((uint16_t)cluster);
983-
dst->size = htole32(size);
998+
fat_dir_entry.cluster_hi = htole16((cluster >> 16));
999+
fat_dir_entry.cluster_lo = htole16((uint16_t)cluster);
1000+
fat_dir_entry.size = htole32(size);
9841001
cluster += cluster_count;
9851002
}
9861003
}
987-
dst++;
1004+
ostream_write(ostr, fat_dir_entry.bytes, 32, false);
9881005
}
989-
memset(dst, 0xE5, buffer + 512 - (uint8_t *)dst);
9901006
}
9911007

9921008
static void

hw/usb/tinyusb/msc_fat_view/syscfg.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ syscfg.defs:
3838
Auto-confirm image when directory is read after reboot.
3939
value: 1
4040

41+
MSC_FAT_VIEW_ROOT_DIR_SECTORS:
42+
description: >
43+
Number of sectors for root directory.
44+
value: 3
4145
MSC_FAT_VIEW_COREDUMP_FILES:
4246
description: >
4347
Adds coredump files (if present) to root directory.

0 commit comments

Comments
 (0)