From 39403ee20d00b755057a9676f352f86a0c429638 Mon Sep 17 00:00:00 2001 From: gussy Date: Sun, 24 Jan 2010 08:13:48 +0000 Subject: [PATCH] Now using global filesystem mounting on bootup. Changed bootup procedure for how the SD Card is handled. Completed, optimised and added error handling to minGlue.c git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@137 ebee16cc-31ac-478f-84a7-5cbb03baadba --- flight/Libraries/dosfs/README_1st.txt | 7 +- flight/Libraries/dosfs/dosfs.h | 9 ++ flight/Libraries/minIni/minGlue.c | 81 ++++++------ flight/PiOS/Common/pios_sdcard.c | 172 +++++++++++++++----------- flight/PiOS/inc/pios_config.h | 1 + flight/PiOS/inc/pios_sdcard.h | 7 ++ flight/PiOS/pios.c | 23 +++- 7 files changed, 186 insertions(+), 114 deletions(-) diff --git a/flight/Libraries/dosfs/README_1st.txt b/flight/Libraries/dosfs/README_1st.txt index a5289abda..a44df8f80 100644 --- a/flight/Libraries/dosfs/README_1st.txt +++ b/flight/Libraries/dosfs/README_1st.txt @@ -8,15 +8,10 @@ This package has been downloaded from: Version 1.03 from 9/30/06 is used. -dfs_sdcard has been added as access layer between DFS functions (located -in dosemu.c) and MIOS32_SDCARD functions (located in ../mios32/mios32_sdcard.c) +dfs_sdcard has been added as access layer between DFS functions and PIOS_SDCARD functions The original usage examples can be found under unused/main.c -MIOS32 based usage examples can be found under - $MIOS32_PATH/apps/examples/sdcard - - Addendum: TK 2008-12-18: diff --git a/flight/Libraries/dosfs/dosfs.h b/flight/Libraries/dosfs/dosfs.h index 29e92551a..e255f8ae3 100644 --- a/flight/Libraries/dosfs/dosfs.h +++ b/flight/Libraries/dosfs/dosfs.h @@ -366,6 +366,15 @@ void DFS_Seek(PFILEINFO fileinfo, uint32_t offset, uint8_t *scratch); */ uint32_t DFS_UnlinkFile(PVOLINFO volinfo, uint8_t *path, uint8_t *scratch); +/* + Fetch FAT entry for specified cluster number + You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO + Returns a FAT32 BAD_CLUSTER value for any error, otherwise the contents of the desired + FAT entry. + scratchcache should point to a UINT32. This variable caches the physical sector number + last read into the scratch buffer for performance enhancement reasons. +*/ +uint32_t DFS_GetFAT(PVOLINFO volinfo, uint8_t *scratch, uint32_t *scratchcache, uint32_t cluster); /* // TK: added 2009-02-12 diff --git a/flight/Libraries/minIni/minGlue.c b/flight/Libraries/minIni/minGlue.c index b15470f56..c37dd8b9d 100644 --- a/flight/Libraries/minIni/minGlue.c +++ b/flight/Libraries/minIni/minGlue.c @@ -2,28 +2,16 @@ #include "pios.h" #include "minGlue.h" -/* TODO: Use global filesystem mounting */ -/* TODO: Implement error handling properly */ -static uint8_t Sector[SECTOR_SIZE]; -static VOLINFO vi; -static uint32_t pstart, psize; -static uint8_t pactive, ptype; -static uint32_t successcount; +/* Global Variables */ +extern uint8_t Sector[SECTOR_SIZE]; +extern VOLINFO VolInfo; + +/* Local Variables */ +static uint32_t SuccessCount; int dosfs_ini_openread(const char *filename, PFILEINFO file) { - pstart = DFS_GetPtnStart(0, Sector, 0, &pactive, &ptype, &psize); - if (pstart == 0xffffffff) { - /* Cannot find first partition */ - return 0; - } - - if(DFS_GetVolInfo(0, Sector, pstart, &vi) != DFS_OK) { - /* No volume information */ - return 0; - } - - if(DFS_OpenFile(&vi, (uint8_t *)filename, DFS_READ, Sector, file)) { + if(DFS_OpenFile(&VolInfo, (uint8_t *)filename, DFS_READ, Sector, file)) { /* Error opening file */ return 0; } @@ -34,18 +22,8 @@ int dosfs_ini_openread(const char *filename, PFILEINFO file) int dosfs_ini_openwrite(const char *filename, PFILEINFO file) { - pstart = DFS_GetPtnStart(0, Sector, 0, &pactive, &ptype, &psize); - if (pstart == 0xffffffff) { - /* Cannot find first partition */ - return 0; - } - - if(DFS_GetVolInfo(0, Sector, pstart, &vi) != DFS_OK) { - /* No volume information */ - return 0; - } - - if(DFS_OpenFile(&vi, (uint8_t *)filename, DFS_WRITE, Sector, file)) { + /* TODO: Check this works */ + if(DFS_OpenFile(&VolInfo, (uint8_t *)filename, DFS_WRITE, Sector, file)) { /* Error opening file */ return 0; } @@ -65,9 +43,9 @@ int dosfs_ini_close(PFILEINFO file) int dosfs_ini_read(char *buffer, int size, PFILEINFO file) { - DFS_ReadFile(file, Sector, (uint8_t *)buffer, &successcount, size); + DFS_ReadFile(file, Sector, (uint8_t *)buffer, &SuccessCount, size); - if(successcount == size) { + if(SuccessCount == size) { /* No errors */ return 1; } else { @@ -79,7 +57,7 @@ int dosfs_ini_read(char *buffer, int size, PFILEINFO file) int dosfs_ini_write(char *buffer, PFILEINFO file) { /* TODO: Check this works */ - DFS_WriteFile(file, Sector, (uint8_t *)buffer, &successcount, sizeof(buffer)); + DFS_WriteFile(file, Sector, (uint8_t *)buffer, &SuccessCount, sizeof(buffer)); /* No errors */ return 1; @@ -87,7 +65,38 @@ int dosfs_ini_write(char *buffer, PFILEINFO file) int dosfs_ini_rename(const char *source, const char *dest) { - /* TODO: Implement, or just don't, since we aren't planning on using renaming */ + /* TODO: Check this works */ + FILEINFO SourceFile, DestFile; + + /* Disable caching to avoid file inconsistencies while using different sector buffers! */ + DFS_CachingEnabledSet(0); + + if(DFS_OpenFile(&VolInfo, (uint8_t *)source, DFS_READ, Sector, &SourceFile)) { + /* Source file doesn't exist */ + return 1; + } else { + /* Delete destination file if it already exists - ignore errors */ + DFS_UnlinkFile(&VolInfo, (uint8_t *)dest, Sector); + + if(DFS_OpenFile(&VolInfo, (uint8_t *)dest, DFS_WRITE, Sector, &DestFile)) { + /* Failed to create destination file */ + return 1; + } + } + + /* Copy operation */ + uint8_t WriteBuffer[SECTOR_SIZE]; + uint32_t SuccessCountRead; + uint32_t SuccessCountWrite; + do { + if(DFS_ReadFile(&SourceFile, Sector, WriteBuffer, &SuccessCountRead, SECTOR_SIZE)) { + /* DFS_ReadFile failed */ + return 1; + } else if(DFS_WriteFile(&DestFile, Sector, WriteBuffer, &SuccessCountWrite, SuccessCountRead)) { + /* DFS_WriteFile failed */ + return 1; + } + } while(SuccessCountRead > 0); /* No errors */ return 1; @@ -95,6 +104,7 @@ int dosfs_ini_rename(const char *source, const char *dest) int dosfs_ini_remove(const char *filename) { + /* TODO: Check this works */ VOLINFO vi; uint32_t pstart, psize; uint8_t pactive, ptype; @@ -119,6 +129,7 @@ int dosfs_ini_remove(const char *filename) int dosfs_ini_rewind(PFILEINFO file) { + /* TODO: Check this works */ DFS_Seek(file, 0, Sector); /* No errors */ return 1; diff --git a/flight/PiOS/Common/pios_sdcard.c b/flight/PiOS/Common/pios_sdcard.c index 793f3bd15..c6cc2df1b 100644 --- a/flight/PiOS/Common/pios_sdcard.c +++ b/flight/PiOS/Common/pios_sdcard.c @@ -29,6 +29,11 @@ /* Project Includes */ #include "pios.h" +/* Global Variables */ +VOLINFO VolInfo; +uint32_t pstart, psize; +uint8_t pactive, ptype; +uint8_t Sector[SECTOR_SIZE]; /* Local Definitions */ #if !defined(SDCARD_MUTEX_TAKE) @@ -753,87 +758,116 @@ int32_t PIOS_SDCARD_CSDRead(SDCARDCsdTypeDef *csd) /** * Attempts to write a startup log to the SDCard -* return 0 Successful -* return -1 Cannot find first partition -* return -2 No volume information -* return -3 Error opening file +* return 0 No errors +* return -1 Error deleting file +* return -2 Error opening file +* return -3 Error writing file */ int32_t PIOS_SDCARD_StartupLog(void) { - PIOS_SDCARD_Init(); + FILEINFO File; + char Buffer[1024]; + uint32_t Cache; - static uint8_t sdcard_available = 0; + /* Delete the file if it exists */ + if(DFS_UnlinkFile(&VolInfo, (uint8_t *)LOG_FILENAME, Sector)) { + /* Error deleting file */ + return -1; + } + if(DFS_OpenFile(&VolInfo, (uint8_t *)LOG_FILENAME, DFS_WRITE, Sector, &File)) { + /* Error opening file */ + return -2; + } + + sprintf(Buffer, "PiOS Startup Log\r\n\r\nLog file creation completed.\r\n"); + if(DFS_WriteFile(&File, Sector, (uint8_t *)Buffer, &Cache, strlen(Buffer))) { + /* Error writing to file */ + return -3; + } + + sprintf(Buffer, "------------------------------\r\nSD Card Information\r\n------------------------------\r\n"); + if(DFS_WriteFile(&File, Sector, (uint8_t *)Buffer, &Cache, strlen(Buffer))) { + /* Error writing to file */ + return -2; + } + + /* Disabled because it takes ca. 7 seconds with my 2GB card */ + /* sprintf(Buffer, "Total Space: %u MB\r\nFree Space: %u MB\r\n", (uint16_t)((VolInfo.numclusters * (VolInfo.secperclus / 2)) / 1024), (uint16_t)(PIOS_SDCARD_GetFree() / 1048576)); */ + + sprintf(Buffer, "Total Space: %u MB\r\n\r\n", (uint16_t)((VolInfo.numclusters * (VolInfo.secperclus / 2)) / 1024)); + if(DFS_WriteFile(&File, Sector, (uint8_t *)Buffer, &Cache, strlen(Buffer))) { + /* Error writing to file */ + return -2; + } + + /* No errors */ + return 0; +} + + +/** +* Mounts the file system +* param[in] CreateStartupLog 1 = True, 0 = False +* return 0 No errors +* return -1 SDCard not available +* return -2 Cannot find first partition +* return -3 No volume information +* return -4 Error writing startup log file +*/ +int32_t PIOS_SDCARD_MountFS(uint32_t CreateStartupLog) +{ + uint8_t sdcard_available = 0; sdcard_available = PIOS_SDCARD_CheckAvailable(0); - if(sdcard_available) { - /* Connected */ - /* - SDCARDCidTypeDef cid; - PIOS_SDCARD_CIDRead(&cid); + if(!sdcard_available) { + /* Disconnected */ + return -1; + } - SDCARDCsdTypeDef csd; - PIOS_SDCARD_CSDRead(&csd); - */ + /* Connected */ - /* Try to mount file system */ - uint32_t pstart, psize; - uint8_t pactive, ptype; + pstart = DFS_GetPtnStart(0, Sector, 0, &pactive, &ptype, &psize); + if (pstart == 0xffffffff) { + /* Cannot find first partition */ + return -2; + } - static uint8_t Buffer1[SECTOR_SIZE], Buffer2[1024]; + if(DFS_GetVolInfo(0, Sector, pstart, &VolInfo) != DFS_OK) { + /* No volume information */ + return -3; + } - pstart = DFS_GetPtnStart(0, Buffer1, 0, &pactive, &ptype, &psize); - if (pstart == 0xffffffff) { - /* Cannot find first partition */ - return -1; - } - - VOLINFO vi; - if(DFS_GetVolInfo(0, Buffer1, pstart, &vi) != DFS_OK) { - /* No volume information */ - return -2; - } - - FILEINFO fi; - uint32_t cache; - - /* Delete the file if it exists */ - DFS_UnlinkFile(&vi, LOG_FILENAME, Buffer1); - - if(DFS_OpenFile(&vi, LOG_FILENAME, DFS_WRITE, Buffer1, &fi)) { - /* Error opening file */ - return -3; - } - sprintf(Buffer2, "PiOS Startup Log\r\n\r\nLog file creation completed.\r\n"); - DFS_WriteFile(&fi, Buffer1, Buffer2, &cache, strlen(Buffer2)); - - sprintf(Buffer2, "------------------------------\r\nSD Card Information\r\n------------------------------\r\n"); - DFS_WriteFile(&fi, Buffer1, Buffer2, &cache, strlen(Buffer2)); - - sprintf(Buffer2, "Total Space: %d MB\r\n\r\n", ((vi.numclusters * (vi.secperclus / 2)) / 1024)); - DFS_WriteFile(&fi, Buffer1, Buffer2, &cache, strlen(Buffer2)); - - - - uint32_t successcount; - uint8_t buff[80]; - - DFS_OpenFile(&vi, LOG_FILENAME, DFS_READ, Buffer1, &fi); - //result = DFS_ReadFile(file, Sector, (uint8_t *)buffer, &successcount, size); /* file->filelen */ - DFS_ReadFile(&fi, Buffer1, buff, &successcount, 80); - - - - return 0; - } else if(!sdcard_available) { - /* Disconnected - lock up and flash LEDs */ - PIOS_LED_On(LED1); - PIOS_LED_On(LED2); - for(;;) { - PIOS_LED_Toggle(LED2); - PIOS_DELAY_Wait_mS(100); + if(CreateStartupLog == 1) { + if(PIOS_SDCARD_StartupLog()) { + /* Error writing startup log file */ + return -4; } } - return -4; + /* No errors */ + return 0; } + +/** +* Mounts the file system +* return Amount of free bytes +*/ +int32_t PIOS_SDCARD_GetFree(void) +{ + uint32_t VolFreeBytes = 0xffffffff; + uint32_t ScratchCache = 0; + + /* This takes very long, since it scans ALL clusters */ + /* It takes ca. 7 seconds to determine free clusters out of ~47000 (2Gb) */ + + /* Scan all the clusters */ + for(uint32_t i = 2; i < VolInfo.numclusters; ++i) { + if(!DFS_GetFAT(&VolInfo, Sector, &ScratchCache, i)) { + VolFreeBytes += VolInfo.secperclus * SECTOR_SIZE; + } + } + + return VolFreeBytes; +} + diff --git a/flight/PiOS/inc/pios_config.h b/flight/PiOS/inc/pios_config.h index 77c53d745..2154253bd 100644 --- a/flight/PiOS/inc/pios_config.h +++ b/flight/PiOS/inc/pios_config.h @@ -33,6 +33,7 @@ /* Defaults for Logging */ #define LOG_FILENAME "pios.log" +#define STARTUP_LOG_ENABLED 1 /* Defaults for MinIni */ diff --git a/flight/PiOS/inc/pios_sdcard.h b/flight/PiOS/inc/pios_sdcard.h index 7b5d528be..1d9bfefcf 100644 --- a/flight/PiOS/inc/pios_sdcard.h +++ b/flight/PiOS/inc/pios_sdcard.h @@ -80,6 +80,11 @@ typedef struct { uint8_t Reserved2; /* always 1*/ } SDCARDCidTypeDef; +/* Global Variables */ +extern VOLINFO VolInfo; +extern uint32_t pstart, psize; +extern uint8_t pactive, ptype; +extern uint8_t Sector[SECTOR_SIZE]; /* Prototypes */ extern int32_t PIOS_SDCARD_Init(void); @@ -92,5 +97,7 @@ extern int32_t PIOS_SDCARD_SectorWrite(uint32_t sector, uint8_t *buffer); extern int32_t PIOS_SDCARD_CIDRead(SDCARDCidTypeDef *cid); extern int32_t PIOS_SDCARD_CSDRead(SDCARDCsdTypeDef *csd); extern int32_t PIOS_SDCARD_StartupLog(void); +extern int32_t PIOS_SDCARD_MountFS(uint32_t StartupLog); +extern int32_t PIOS_SDCARD_GetFree(void); #endif /* PIOS_SDCARD_H */ diff --git a/flight/PiOS/pios.c b/flight/PiOS/pios.c index bffb4e77f..380bd11ea 100644 --- a/flight/PiOS/pios.c +++ b/flight/PiOS/pios.c @@ -63,9 +63,25 @@ int main() /* Enables the SDCard */ PIOS_SDCARD_Init(); - PIOS_SDCARD_StartupLog(); + /* Wait for SD card for ever */ + for(;;) + { + /* Check if we have an SD Card */ + if(!PIOS_SDCARD_MountFS(STARTUP_LOG_ENABLED)) { + /* Found one without errors */ + break; + } - /* Call LoadSettings which populates System Vars so the rest of the hardware can be configured. */ + /* SD Card not found, flash for 1 second */ + PIOS_LED_On(LED1); + PIOS_LED_On(LED2); + for(uint32_t i = 0; i < 10; i++) { + PIOS_LED_Toggle(LED2); + PIOS_DELAY_Wait_mS(100); + } + } + + /* Call LoadSettings which populates global variables so the rest of the hardware can be configured. */ PIOS_Settings_Load(); Flashy(); @@ -103,8 +119,7 @@ void Flashy(void) while(1) { PIOS_LED_Toggle(LED1); - PIOS_LED_Toggle(LED2); - //for(int i = 0; i < 1000000; i++); + //PIOS_LED_Toggle(LED2); PIOS_DELAY_Wait_mS(250); } }