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:
parent
3a09acff4f
commit
9be3189d6c
|
@ -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
|
||||
|
|
|
@ -18,6 +18,7 @@ struct fugue_dirent
|
|||
/* low-level information */
|
||||
struct {
|
||||
fugue_fs_t fs;
|
||||
int lfn_prev_idx;
|
||||
} _private;
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
struct fugue_file
|
||||
{
|
||||
char name[210];
|
||||
size_t name_len;
|
||||
int type;
|
||||
uint32_t size;
|
||||
};
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
#include "fsctl/menu/rom.h"
|
||||
#include "fsctl/menu/info.h"
|
||||
#include "fsctl/menu/list.h"
|
||||
#include "fsctl/menu/test.h"
|
||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue