fsctl - v0.0.0-3 : add test menu

*add*
> [menu]
  | [test] add test menu for various hardcoded tests

*update*
> [fugue]
  | [dirent] support name fragment
  | [dir] enable logger
> [menu]
  | [info] remove debug print
  | [info] display waiting log

*fix*
> [fugue]
  | [dirent] fix FS dump
  | [dirent] fix logger text
This commit is contained in:
Yann MAGNIN 2023-04-21 18:55:54 +02:00
parent 3a09acff4f
commit 9be3189d6c
11 changed files with 233 additions and 20 deletions

View File

@ -21,6 +21,7 @@ set(SOURCES
src/menu/info.c
src/menu/fat.c
src/menu/list.c
src/menu/test.c
#utils
src/utils/fs_table.c

View File

@ -18,6 +18,7 @@ struct fugue_dirent
/* low-level information */
struct {
fugue_fs_t fs;
int lfn_prev_idx;
} _private;
};

View File

@ -65,11 +65,11 @@ struct fugue_fat_dir
struct fugue_fat_dir_name
{
struct {
uint8_t :2;
uint8_t _low0 :1; // must be 0
uint8_t last :1;
uint8_t :1;
uint8_t id :4;
} DIR_Secquence;
uint8_t _low1 :1; // must be 0
uint8_t id :5;
} DIR_Sequence;
uint16_t DIR_Char0;
uint16_t DIR_Char1;
uint16_t DIR_Char2;

View File

@ -12,6 +12,7 @@
struct fugue_file
{
char name[210];
size_t name_len;
int type;
uint32_t size;
};

View File

@ -2,3 +2,4 @@
#include "fsctl/menu/rom.h"
#include "fsctl/menu/info.h"
#include "fsctl/menu/list.h"
#include "fsctl/menu/test.h"

13
include/fsctl/menu/test.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef FSCTL_MENU_TEST_H
#define FSCTL_MENU_TEST_H 1
/* test_menu_init() : init menu */
extern void test_menu_init(void);
/* test_menu_display() : display menu */
extern void test_menu_display(void);
/* test_menu_keyboard() : handle keyboard */
extern void test_menu_keyboard(int key);
#endif /* FSCTL_MENU_TEST_H */

View File

@ -29,6 +29,23 @@ static uint8_t _fugue_dirent_checksum(uintptr_t directory)
return checksum;
}
/* _fugue_dirent_frag_dump() : decode name fragment */
static int _fugue_dirent_frag_dump(fugue_file_t *file, uint8_t *frag, int n)
{
while (--n >= 0)
{
file->name[file->name_len] = frag[0];
if ((frag[0] & 0x80) != 0) {
file->name[file->name_len] = frag[1];
file->name_len += 1;
}
file->name_len += 1;
frag = &frag[2];
}
file->name[file->name_len] = '\0';
return 0;
}
//---
// Public
//---
@ -39,7 +56,7 @@ int fugue_dirent_init(fugue_dirent_t *dirent, fugue_fs_t *fs)
if (fs == NULL || dirent == NULL)
return -1;
memset(dirent, 0x00, sizeof(fugue_dirent_t));
memcpy(&dirent->_private.fs, &fs, sizeof(fugue_fs_t));
memcpy(&dirent->_private.fs, fs, sizeof(fugue_fs_t));
dirent->current_dir_addr = (uintptr_t)fs->_private.root;
dirent->cluster_addr_start = (uintptr_t)fs->_private.root;
dirent->cluster_addr_end = (uintptr_t)fs->_private.root;
@ -86,24 +103,49 @@ int fugue_dirent_name_fetch(
// check directory block validity
//---
if (lfn->DIR_Attr != FUGUE_DIR_ATTR_LFN)
if (lfn->DIR_Attr != FUGUE_DIR_ATTR_LFN) {
fugue_logger_write(log, "[WARN] %p: LFN type error\n", lfn);
return -1;
if (lfn->DIR_Type != 0x00)
}
if (lfn->DIR_Type != 0x00) {
fugue_logger_write(log, "[WARN] %p: LFN attribute error\n", lfn);
return -2;
if (lfn->DIR_FstClus != 0x0000)
}
if (lfn->DIR_FstClus != 0x0000) {
fugue_logger_write(log, "[WARN] %p: cluster info error\n", lfn);
return -3;
//TODO : check Secquence validity
}
if (lfn->DIR_Sequence._low0 != 0 || lfn->DIR_Sequence._low1 != 0) {
fugue_logger_write(log, "[WARN] %p: dirty sequence\n", lfn);
return -4;
}
if (lfn->checksum != _fugue_dirent_checksum(dirent->current_dir_addr)) {
fugue_logger_write(log, "[WARN] checksum error at %p", lfn);
fugue_logger_write(log, "[WARN] %p: checksum error\n", lfn);
return -5;
}
//---
// check sequence validity
//---
if (lfn->DIR_Sequence.last != 0)
{
if (dirent->_private.lfn_prev_idx != 0)
fugue_logger_write(log, "[WARN] %p: multiple LFN entry\n", lfn);
dirent->_private.lfn_prev_idx = lfn->DIR_Sequence.id + 1;
}
if (dirent->_private.lfn_prev_idx != lfn->DIR_Sequence.id + 1) {
fugue_logger_write(log, "[WARN] %p: LFN sequence error\n", lfn);
return -6;
}
dirent->_private.lfn_prev_idx = lfn->DIR_Sequence.id;
//---
// Dump name fragment
//---
//TODO: dump
(void)file;
fugue_logger_write(log, "[ERR] name dump error at %p", lfn);
_fugue_dirent_frag_dump(file, (uint8_t*)&lfn->DIR_Char0, 5);
_fugue_dirent_frag_dump(file, (uint8_t*)&lfn->DIR_Char5, 5);
_fugue_dirent_frag_dump(file, (uint8_t*)&lfn->DIR_Char11,2);
return -1;
}

View File

@ -3,6 +3,7 @@
#include "fsctl/fugue.h"
#include "fsctl/fugue/bits/fat.h"
#include "fsctl/fugue/dirent.h"
#include "fsctl/fugue/logger.h"
#include "fsctl/fugue/utils.h"
#include "fsctl/utils/fs_table.h"
@ -31,6 +32,7 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
{
struct fugue_fat_dir *dir;
fugue_dirent_t dirent_backup;
fugue_logger_t *log;
bool error;
bool vfat;
@ -43,6 +45,7 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
memset(file, 0x00, sizeof(fugue_file_t));
memcpy(&dirent_backup, dirent, sizeof(fugue_dirent_t));
log = dirent->_private.fs._private.logger;
vfat = false;
error = false;
@ -63,7 +66,7 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
{
/* handle free directory */
case 0x00:
//fugue_logger_warn("opendir: wierd empty directory block ")
fugue_logger_write(log, "[WARN] opendir: empty dir block\n");
error = true;
continue;
@ -73,8 +76,13 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
memcpy(file->name, ".", 2);
if (memcmp(dir->DIR_Name, ".. ", 3) == 0)
memcpy(file->name, "..", 3);
if (vfat == true)
//fugue_logger_warn("opendir: wierd directory block ")
if (vfat == true) {
fugue_logger_write(
log,
"[WARN] %p:opendir: wierd dir block layout\n",
dir
);
}
file->type = FUGUE_FILE_TYPE_DIR;
file->size = FAT_LONG(dir->DIR_FileSize);
return 0;
@ -82,7 +90,11 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
/* removed entry */
case 0x05:
case 0xe5:
//fugue_logger_notice("opendir : removed entry");
fugue_logger_write(
log,
"[NOTICE] %p:opendir : removed entry\n",
dir
);
memset(file, 0x00, sizeof(fugue_file_t));
vfat = false;
continue;
@ -114,7 +126,11 @@ int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file)
/* other attribute not handled */
default:
//fugue_logger_warn("opendir : unsupported attribute ")
fugue_logger_write(
log,
"[WARN] %p:opendir : KO attr %02x\n",
dir, dir->DIR_Attr
);
error = true;
break;
}

View File

@ -17,6 +17,7 @@ int main(void)
info_menu_init();
fat_menu_init();
list_menu_init();
test_menu_init();
tab = 0;
while (1)
@ -26,6 +27,7 @@ int main(void)
if (tab == 1) { info_menu_display(); }
if (tab == 2) { fat_menu_display(); }
if (tab == 3) { list_menu_display(); }
if (tab == 4) { test_menu_display(); }
dupdate();
switch (key = getkey().key)
@ -42,11 +44,15 @@ int main(void)
case KEY_F4:
tab = 3;
break;
case KEY_F5:
tab = 4;
break;
default:
if (tab == 0) { rom_menu_keyboard(key); }
if (tab == 1) { info_menu_keyboard(key); }
if (tab == 2) { fat_menu_keyboard(key); }
if (tab == 3) { list_menu_keyboard(key); }
if (tab == 4) { test_menu_keyboard(key); }
}
}

View File

@ -90,11 +90,15 @@ void info_menu_display(void)
dline(391, 1 + y_start, 391, y_start + y_size, C_BLACK);
dline(393, 0, 393, 190, C_BLACK);
}
if (line_nb == 0)
{
dtext(1, 15, C_BLACK, "No logs for now...");
}
dprint(300, 15, C_BLACK, "start=%d", logs_line_start);
dprint(300, 26, C_BLACK, "line_nb=%d", line_nb);
#if 0
dprint(300, 15, C_BLACK, "start=%d", logs_line_start);
dprint(300, 26, C_BLACK, "line_nb=%d", line_nb);
int y = 0;
_printXY(0, ++y, "FS type = %s", fs.props.type);
_printXY(0, ++y, "capacity = %d", fs.props.capacity);

128
src/menu/test.c Normal file
View File

@ -0,0 +1,128 @@
#include "fsctl/menu.h"
#include "fsctl/fugue.h"
#include "fsctl/utils/fs_table.h"
#include "fsctl/utils/display.h"
//---
// Internal
//---
/* internal information */
static int test_selected;
static int __find_ls;
static int __find_lb;
static int __find_fs;
static int __find_fb;
/* test_search() : search Fugue entry using sector */
static void __test_search(
int *info,
uintptr_t start,
uintptr_t end,
size_t block
) {
uintptr_t saved_start;
fugue_fs_t fs;
int counter;
dclear(C_WHITE);
_printXY(0, 0, "search from %p...", start);
dupdate();
counter = 0;
saved_start = start;
while (start < end)
{
if (fugue_fs_mount(&fs, (void *)start) == 0) {
dclear(C_WHITE);
_printXY(0, 0, "search from %p...", saved_start);
_printXY(0, 1, "- found = %d", counter);
dupdate();
*info += 1;
}
start += block;
}
dclear(C_WHITE);
}
/* test_search_sector() : search Fugue entry using sector */
static void test_search_sector(int *info, uintptr_t start, uintptr_t end)
{
__test_search(info, start, end, 512);
}
/* test_search_byte() : search Fugue entry using byte */
static void test_search_byte(int *info, uintptr_t start, uintptr_t end)
{
__test_search(info, start, end, 1);
}
//---
// Public
//---
/* test_menu_init() : init menu */
void test_menu_init(void)
{
test_selected = -1;
__find_ls = 0;
__find_lb = 0;
__find_fs = 0;
__find_fb = 0;
}
/* test_menu_display() : display menu */
void test_menu_display(void)
{
int y;
y = 0;
switch(test_selected)
{
case 1:
test_search_sector(&__find_ls, 0xa1000000, 0xa2000000);
break;
case 2:
test_search_byte(&__find_ls, 0xa1000000, 0xa2000000);
break;
case 3:
test_search_sector(&__find_ls, 0xa0000000, 0xa1000000);
break;
case 4:
test_search_byte(&__find_ls, 0xa0000000, 0xa1000000);
break;
}
test_selected = -1;
_printXY(0, ++y, "[1] last 16Mo entry search (sector)");
_printXY(0, ++y, "[2] last 16Mo entry search (byte)");
_printXY(0, ++y, "[3] first 16Mo entry search (sector)");
_printXY(0, ++y, "[4] first 16Mo entry search (byte)");
_printXY(0, ++y, "");
_printXY(0, ++y, "");
_printXY(0, ++y, "last 16Mo sector found = %d", __find_ls);
_printXY(0, ++y, "last 16Mo byte found = %d", __find_lb);
_printXY(0, ++y, "first 16Mo sector found = %d", __find_fs);
_printXY(0, ++y, "first 16Mo byte found = %d", __find_fb);
}
/* test_menu_keyboard() : handle keyboard */
void test_menu_keyboard(int key)
{
switch (key)
{
case KEY_1:
test_selected = 1;
break;
case KEY_2:
test_selected = 2;
break;
case KEY_3:
test_selected = 3;
break;
case KEY_4:
test_selected = 4;
break;
}
}