Added command shell to the STM32 FatFs demo.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1890 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2010-04-25 09:31:04 +00:00
parent 7c799d9dfd
commit e53a1a3208
4 changed files with 163 additions and 61 deletions

View File

@ -74,7 +74,7 @@ CSRC = $(PORTSRC) \
$(PLATFORMSRC) \ $(PLATFORMSRC) \
$(BOARDSRC) \ $(BOARDSRC) \
$(FATFSSRC) \ $(FATFSSRC) \
$(CHIBIOS)/os/various/evtimer.c \ $(CHIBIOS)/os/various/shell.c \
$(CHIBIOS)/os/various/syscalls.c \ $(CHIBIOS)/os/various/syscalls.c \
main.c main.c

View File

@ -23,10 +23,15 @@
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "test.h" #include "test.h"
#include "shell.h"
#include "evtimer.h" #include "evtimer.h"
#include "ff.h" #include "ff.h"
/*===========================================================================*/
/* MMC/SPI related. */
/*===========================================================================*/
/** /**
* @brief FS object. * @brief FS object.
*/ */
@ -58,22 +63,6 @@ static bool_t mmc_is_protected(void) {return !palReadPad(IOPORT3, GPIOC_MMCWP);}
/* Generic large buffer.*/ /* Generic large buffer.*/
uint8_t fbuff[1024]; uint8_t fbuff[1024];
/*
* Red LEDs blinker thread, times are in milliseconds.
*/
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
while (TRUE) {
palClearPad(IOPORT3, GPIOC_LED);
chThdSleepMilliseconds(500);
palSetPad(IOPORT3, GPIOC_LED);
chThdSleepMilliseconds(500);
}
return 0;
}
static FRESULT scan_files(char *path) static FRESULT scan_files(char *path)
{ {
FRESULT res; FRESULT res;
@ -107,32 +96,140 @@ static FRESULT scan_files(char *path)
return res; return res;
} }
/* /*===========================================================================*/
* Executed as event handler at 500mS intervals. /* Command line related. */
*/ /*===========================================================================*/
static void TimerHandler(eventid_t id) {
(void)id; #define SHELL_WA_SIZE THD_WA_SIZE(1024)
if (palReadPad(IOPORT1, GPIOA_BUTTON)) { #define TEST_WA_SIZE THD_WA_SIZE(256)
if (fs_ready) {
FRESULT err;
uint32_t clusters;
FATFS *fsp;
err = f_getfree("/", &clusters, &fsp); static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) {
if (err != FR_OK) { size_t n, size;
iprintf("FS: f_getfree() failed\r\n"); char buf[52];
return;
} (void)argv;
iprintf("FS: %lu free clusters, %u sectors per cluster, %lu bytes free\r\n", if (argc > 0) {
clusters, MMC_FS.csize, shellPrintLine(chp, "Usage: mem");
clusters * (uint32_t)MMC_FS.csize * (uint32_t)MMC_SECTOR_SIZE); return;
fbuff[0] = 0;
scan_files((char *)fbuff);
}
else
TestThread(&SD2);
} }
n = chHeapStatus(NULL, &size);
siprintf(buf, "core free memory : %lu bytes", chCoreFree());
shellPrintLine(chp, buf);
siprintf(buf, "heap fragments : %lu", n);
shellPrintLine(chp, buf);
siprintf(buf, "heap free total : %lu bytes", size);
shellPrintLine(chp, buf);
}
static void cmd_threads(BaseChannel *chp, int argc, char *argv[]) {
static const char *states[] = {
"READY",
"CURRENT",
"SUSPENDED",
"WTSEM",
"WTMTX",
"WTCOND",
"SLEEPING",
"WTEXIT",
"WTOREVT",
"WTANDEVT",
"SNDMSG",
"WTMSG",
"FINAL"
};
Thread *tp;
char buf[60];
(void)argv;
if (argc > 0) {
shellPrintLine(chp, "Usage: threads");
return;
}
shellPrintLine(chp, " addr stack prio refs state time");
tp = chRegFirstThread();
do {
siprintf(buf, "%8lx %8lx %4u %4i %9s %u",
(uint32_t)tp, (uint32_t)tp->p_ctx.r13,
(unsigned int)tp->p_prio, tp->p_refs - 1,
states[tp->p_state], (unsigned int)tp->p_time);
shellPrintLine(chp, buf);
tp = chRegNextThread(tp);
} while (tp != NULL);
}
static void cmd_test(BaseChannel *chp, int argc, char *argv[]) {
Thread *tp;
(void)argv;
if (argc > 0) {
shellPrintLine(chp, "Usage: test");
return;
}
tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(),
TestThread, chp);
if (tp == NULL) {
shellPrintLine(chp, "out of memory");
return;
}
chThdWait(tp);
}
static void cmd_tree(BaseChannel *chp, int argc, char *argv[]) {
FRESULT err;
uint32_t clusters;
FATFS *fsp;
(void)argv;
if (argc > 0) {
shellPrintLine(chp, "Usage: tree");
return;
}
if (!fs_ready) {
shellPrintLine(chp, "File System not mounted");
return;
}
err = f_getfree("/", &clusters, &fsp);
if (err != FR_OK) {
shellPrintLine(chp, "FS: f_getfree() failed");
return;
}
siprintf((void *)fbuff,
"FS: %lu free clusters, %lu sectors per cluster, %lu bytes free",
clusters, (uint32_t)MMC_FS.csize,
clusters * (uint32_t)MMC_FS.csize * (uint32_t)MMC_SECTOR_SIZE);
shellPrintLine(chp, (void *)fbuff);
fbuff[0] = 0;
scan_files((char *)fbuff);
}
static const ShellCommand commands[] = {
{"mem", cmd_mem},
{"threads", cmd_threads},
{"test", cmd_test},
{"tree", cmd_tree},
{NULL, NULL}
};
static const ShellConfig shell_cfg1 = {
(BaseChannel *)&SD2,
commands
};
/*
* Red LEDs blinker thread, times are in milliseconds.
*/
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
while (TRUE) {
palTogglePad(IOPORT3, GPIOC_LED);
if (fs_ready)
chThdSleepMilliseconds(200);
else
chThdSleepMilliseconds(500);
}
return 0;
} }
/* /*
@ -142,25 +239,18 @@ static void InsertHandler(eventid_t id) {
FRESULT err; FRESULT err;
(void)id; (void)id;
iprintf("MMC: inserted\r\n");
/* /*
* On insertion MMC initialization and FS mount. * On insertion MMC initialization and FS mount.
*/ */
iprintf("MMC: initialization ");
if (mmcConnect(&MMCD1)) { if (mmcConnect(&MMCD1)) {
iprintf("failed\r\n");
return; return;
} }
iprintf("ok\r\n");
iprintf("FS: mount ");
err = f_mount(0, &MMC_FS); err = f_mount(0, &MMC_FS);
if (err != FR_OK) { if (err != FR_OK) {
iprintf("failed\r\n");
mmcDisconnect(&MMCD1); mmcDisconnect(&MMCD1);
return; return;
} }
fs_ready = TRUE; fs_ready = TRUE;
iprintf("ok\r\n");
} }
/* /*
@ -169,7 +259,6 @@ static void InsertHandler(eventid_t id) {
static void RemoveHandler(eventid_t id) { static void RemoveHandler(eventid_t id) {
(void)id; (void)id;
iprintf("MMC: removed\r\n");
fs_ready = FALSE; fs_ready = FALSE;
} }
@ -179,12 +268,11 @@ static void RemoveHandler(eventid_t id) {
*/ */
int main(int argc, char **argv) { int main(int argc, char **argv) {
static const evhandler_t evhndl[] = { static const evhandler_t evhndl[] = {
TimerHandler,
InsertHandler, InsertHandler,
RemoveHandler RemoveHandler
}; };
static EvTimer evt; Thread *shelltp = NULL;
struct EventListener el0, el1, el2; struct EventListener el0, el1;
(void)argc; (void)argc;
(void)argv; (void)argv;
@ -194,6 +282,11 @@ int main(int argc, char **argv) {
*/ */
sdStart(&SD2, NULL); sdStart(&SD2, NULL);
/*
* Shell manager initialization.
*/
shellInit();
/* /*
* Initializes the MMC driver to work with SPI2. * Initializes the MMC driver to work with SPI2.
*/ */
@ -213,12 +306,16 @@ int main(int argc, char **argv) {
* Normal main() thread activity, in this demo it does nothing except * Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and listen for events. * sleeping in a loop and listen for events.
*/ */
evtInit(&evt, MS2ST(500)); /* Initializes an event timer object. */ chEvtRegister(&MMCD1.mmc_inserted_event, &el0, 0);
evtStart(&evt); /* Starts the event timer. */ chEvtRegister(&MMCD1.mmc_removed_event, &el1, 1);
chEvtRegister(&evt.et_es, &el0, 0); /* Registers on the timer event source. */ while (TRUE) {
chEvtRegister(&MMCD1.mmc_inserted_event, &el1, 1); if (!shelltp)
chEvtRegister(&MMCD1.mmc_removed_event, &el2, 2); shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
while (TRUE) else if (chThdTerminated(shelltp)) {
chThdRelease(shelltp); /* Recovers memory of the previous shell. */
shelltp = NULL; /* Triggers spawning of a new shell. */
}
chEvtDispatch(evhndl, chEvtWaitOne(ALL_EVENTS)); chEvtDispatch(evhndl, chEvtWaitOne(ALL_EVENTS));
}
return 0; return 0;
} }

View File

@ -11,9 +11,11 @@ The demo will on an Olimex STM32-P103 board.
This demo shows how to integrate the FatFs file system and use the SPI and MMC This demo shows how to integrate the FatFs file system and use the SPI and MMC
drivers. drivers.
The demo flashes the board LED using a thread and monitors the MMC slot for The demo flashes the board LED using a thread and monitors the MMC slot for
a card insertion. By pressing the button located on the board while a card is a card insertion. When a card is inserted then the file system is mounted
inserted a directory dump on the serial port is performed, if a card is not and the LED flashes faster.
inserted then the test procedure is activated. A command line shell is spawned on SD2, all the interaction with the demo is
performed using the command shell, type "help" for a list of the available
commands.
** Build Procedure ** ** Build Procedure **

View File

@ -66,9 +66,12 @@
the "const" keyword does that. Note that this macro is not used to place the "const" keyword does that. Note that this macro is not used to place
constants in different address spaces (AVR) because it is assumed that a constants in different address spaces (AVR) because it is assumed that a
pointer to a ROMCONST variable is compatible with a normal pointer. pointer to a ROMCONST variable is compatible with a normal pointer.
- NEW: AT91SAM7 HAL support for the DGBU UART peripheral, as SD3 - NEW: AT91SAM7 HAL support for the DGBU UART peripheral, as SD3.
- OPT: Internal optimization in the serial driver, it now is a bit smaller - OPT: Internal optimization in the serial driver, it now is a bit smaller
and uses less RAM (all architectures). and uses less RAM (all architectures).
- CHANGE: Modified the STM32 FatFs demo, now it spawns a command shell or
the serial port SD2, type "help" for the available commands. More commands
can be easily added.
- Various documentation fixes, added an article covering debugging under - Various documentation fixes, added an article covering debugging under
ChibiOS/RT. ChibiOS/RT.