Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FileManager.cpp
- Committer:
- nsrwsurasak
- Date:
- 2016-09-15
- Revision:
- 36:09e662a69c50
- Parent:
- 35:b91169442c4a
- Child:
- 38:e2799f75940f
File content as of revision 36:09e662a69c50:
/**
******************************************************************************
* @file FileManager.cpp
* @author Narut T
* @version V1
* @date 19/05/2016
* @brief File Manager for managing file system in SD Card
******************************************************************************/
#include "main.h"
char m_StrGpsInterval[XMLTEXT_SIZE]; // GPS Interval
char m_StrDataInterval[XMLTEXT_SIZE]; // Data Interval
uint32_t m_GpsInterval;
uint32_t m_DataInterval;
Variable_Data_TypeDef m_varList[MAX_VAR]; // Variable List
unsigned int m_amountVarList = 0; // Amount of variable list
bool m_SdCardHasDisconnected = false; // flag to indicate sd card has disconnected
char m_varListFileName[MAX_FILE_NAME_SIZE]; // Variable File Name
bool m_sdCardIsPresent; // Flag to indicate sd card is present
uint32_t m_TxID; // Transmit ID
uint32_t m_RxID; // Receive ID
#if UART_FILE_ACCESS
char m_bufFileName[MAX_FILE_NAME_SIZE]; // buffer for storing File Name
#endif
/** Connect pin for SD Card LED */
#ifdef LED_SDCARD
DigitalOut ledStatus(LED_SDCARD);
#else
DigitalOut ledStatus(NC);
#endif
#if CAPTURE_TIME
Timer t;
#endif
/* ############### Static function prototype ################## */
static void FILEMANAGER_RemoveSpaces(char* s , int size);
static void FILEMANAGER_GetXmlText(char *str, char *ret);
static void FILEMANAGER_GenerateFileNameWithTime(time_t timestamp, char * file_name);
static void FILEMANAGER_SetLedStatus(bool on);
#if UART_FILE_ACCESS
static void FILEMANAGER_AddPrefixFilename(char* in, char* out);
#endif
/**
* @brief Utility function to Remove space charector from given char array
* @note
* @param char array to process remove spaces
* @param size of char array
* @retval space removed char array
*/
static void FILEMANAGER_RemoveSpaces(char* s , int size)
{
char* cpy = s; // an alias to iterate through s without moving s
char* temp = s;
for (int i = 0 ; i < size ; i++) {
if (*cpy != ' ')
*temp++ = *cpy;
cpy++;
}
*temp = 0;
return;
}
/**
* @brief Utility function to get XML tag
* @note Only First tag will be returned
* @param char array to get XML Text
* @param char array to be populate XML text
* @retval XML text
*/
static void FILEMANAGER_GetXmlText(char *str, char *ret)
{
int size = strlen(str);
int i;
bool begin_text = false;
char * ret_addr = ret;
/* initialized our return value */
memset (ret,' ',XMLTEXT_SIZE);
/* Loop to check XML tag symbols */
for(i = 0; i < size ; i++) {
if (*str == '>') {
/* Found begining of the tag */
begin_text = true;
} else if (begin_text && *str == '<') {
/* Reach the end of text message */
begin_text = false;
break;
} else if (begin_text && *str != ' ') {
/* Populate the return value */
*ret = *str;
ret++;
}
/* Move to next char */
str++;
}
/* Remove space from return value */
FILEMANAGER_RemoveSpaces(ret_addr, XMLTEXT_SIZE);
}
/**
* @brief Utility function to get File Name with Date
* @note Format file will be YYYY-MM-DD.filename
* @param timestamp - time structure to get Date
* @param file_name - char array to file name
* @retval renamed file name
*/
static void FILEMANAGER_GenerateFileNameWithTime(time_t timestamp, char * file_name)
{
char str[RENAME_FILE_BUFFER_SIZE];
struct tm * ptm;
/* Convert timestamp to readable format */
ptm = localtime ( ×tamp );
/* Replacing YYYY to the converted year */
sprintf(str,"%04d", ptm->tm_year + YEAR_4DIGITS_OFFSET);
memcpy(&file_name[TIMESTAMP_YEAR_OFFSET], str, TIMESTAMP_YEAR_SIZE);
/* Replacing MM to converted month */
sprintf(str,"%02d", ptm->tm_mon+1);
memcpy(&file_name[TIMESTAMP_MONTH_OFFSET], str, TIMESTAMP_MONTH_SIZE);
/* Replacing DD to converted date */
sprintf(str,"%02d", ptm->tm_mday);
memcpy(&file_name[TIMESTAMP_DATE_OFFSET], str,TIMESTAMP_DATE_SIZE);
}
/**
* @brief Function to perform read setup file
* @note filename must be defined in FileManager.h, GPS/ Data interval will be stored in dedicated variable
* @param None
* @retval None
*/
void FILEMANAGER_ReadSetupFile()
{
/* Open file in reading mode */
FILE *fp = fopen(SETUP_FILE_NAME, "r");
if (fp == NULL) {
/* In case of error, print the message */
printf("\nError! Unable to open file! %s \n", SETUP_FILE_NAME);
/* Indicate LED Status (OFF)*/
FILEMANAGER_SetLedStatus(false);
} else {
/* Initialized state */
ReadingFileState state = STATE_FINDING;
/* Allocate buffer for reading file */
char buf[READ_FILE_BUFFER_SIZE];
/* Indicate LED Status (ON)*/
FILEMANAGER_SetLedStatus(true);
/* Read line from the file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* Check the TAG */
if (strstr (buf,DATA_TAG))
{
/* Found the DATA TAG */
state = STATE_FOUND_DATA;
}
else if (strstr (buf,GPS_TAG))
{
/* Found GPS TAG */
state = STATE_FOUND_GPS;
}
else if (strstr (buf,UPDATE_INTERVAL_TAG))
{
/* Found Interval TAG */
if (state == STATE_FOUND_GPS)
{
/* Get XML text for GPS Interval */
FILEMANAGER_GetXmlText(buf, m_StrGpsInterval);
m_GpsInterval = atoi(m_StrGpsInterval);
#if DEBUG
printf("\r\n-found GPS interval %s ", m_StrGpsInterval);
#endif
/* Set state to indicate that we are finding */
state = STATE_FINDING;
}
else if(state == STATE_FOUND_DATA)
{
/* Get XML text for Data Interval */
FILEMANAGER_GetXmlText(buf, m_StrDataInterval);
m_DataInterval = atoi(m_StrDataInterval);
#if DEBUG
printf("\r\n-found Data interval %s ", m_StrDataInterval);
#endif
/* Set state to indicate that we are finding */
state = STATE_FINDING;
}
}
else if (strstr (buf,VAR_LIST_FILE_TAG))
{
/* Get XML text for Variable File Name */
char bufFileName[MAX_FILE_NAME_SIZE];
FILEMANAGER_GetXmlText(buf, bufFileName);
/* Get Copy to dedicated variable */
memcpy(m_varListFileName,PREFIX_FILE_NAME,strlen(PREFIX_FILE_NAME));
memcpy(&m_varListFileName[strlen(PREFIX_FILE_NAME)],bufFileName,strlen(bufFileName));
}
else if (strstr (buf,RMS_DEVICE_TAG))
{
/* Get XML text for RMS device TAG */
char bufDevice[XMLTEXT_SIZE];
FILEMANAGER_GetXmlText(buf, bufDevice);
m_TxID = atoi(bufDevice);
}
else if (strstr (buf,RMS_KEY_TAG))
{
/* Get XML text for RMS Key TAG */
char bufKey[XMLTEXT_SIZE];
FILEMANAGER_GetXmlText(buf, bufKey);
m_RxID = atoi(bufKey);
}
}
/* Ensure file is closed */
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
}
}
/**
* @brief Function to log GPS Data
* @note
* @param timestamp - time structure to get Date
* @param lat - char array for lattitude
* @param longti - char array for longtitude
* @retval None
*/
void FILEMANAGER_LogGPSData(time_t timestamp ,char lat[], char longti[])
{
if (!m_sdCardIsPresent)
{
/** Turn off LED */
FILEMANAGER_SetLedStatus(false);
printf("Error! SD Card is not connected \n");
/** Return as nothing to be done */
return;
}
/* Get File name */
char file_name[] = GPS_LOG_FILE_NAME;
/* Generate file name with time stamp */
FILEMANAGER_GenerateFileNameWithTime(timestamp,file_name);
/* Open file with "APPEND" mode */
FILE *fp = fopen(file_name, "a");
if (fp == NULL)
{
/* if it can't open the file then print error message */
printf("Error! Unable to open file %s!\n",file_name);
/* Indicate LED Status (OFF)*/
FILEMANAGER_SetLedStatus(false);
}
else
{
#if CAPTURE_TIME
t.reset();
t.start();
#endif
/* Indicate LED Status (ON)*/
FILEMANAGER_SetLedStatus(true);
#if DEBUG
/* Print some message for information */
printf("\r\n Writing to Gps Log File (%s)....",file_name);
#endif
/* Write the line with lattitude and longtitude */
fprintf(fp, "%d,%s,%s\n",timestamp,lat,longti);
#if DEBUG
printf("Done");
#endif
/* Close file once it done */
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
#if CAPTURE_TIME
t.stop();
printf("\r\nThe GPS Write Log time taken was %d millsecond\n", t.read_ms());
#endif
}
}
/**
* @brief Function to log RMS Data
* @note sequence must be in the same order with variableList
* @param timestamp - time structure to get Date
* @param var - float array to be log in the file
* @param size - size of the float array
* @param p_headerRequired - pointer to flag for log header
* @param msec - time in millisecond
* @retval None
*/
void FILEMANAGER_LogRMSData(time_t timestamp ,float * var, int size, bool * p_headerRequired, uint32_t msec)
{
if (!m_sdCardIsPresent)
{
/** Turn off LED */
FILEMANAGER_SetLedStatus(false);
printf("Error! SD Card is not connected \n");
/** Return as nothing to be done */
return;
}
/* Get File name */
char file_name[] = RTL_LOG_FILE_NAME;
/* Generate File name with timestamp */
FILEMANAGER_GenerateFileNameWithTime(timestamp,file_name);
#if DEBUG
printf("\r\n File name is generated \n");
#endif
#if DEBUG
printf("\r\n Going to Open RMS File For write \n");
#endif
/* Open file with "APPEND" mode */
FILE *fp = fopen(file_name, "a");
if (*p_headerRequired || !FILEMANAGER_IsFileExist(file_name))
{
/* If file is not exist, log the header */
FILEMANAGER_LogRMSHeader(fp, timestamp, file_name);
/* Clear flag once header has been written */
*p_headerRequired = false;
}
if (fp == NULL)
{
/* In case of error, print the error message */
printf("Error! Unable to open file %s!\n",file_name);
/* Indicate LED Status (OFF)*/
FILEMANAGER_SetLedStatus(false);
}
else
{
/* Indicate LED Status (ON)*/
FILEMANAGER_SetLedStatus(true);
#if CAPTURE_TIME
t.reset();
t.start();
#endif
#if DEBUG
/* Print some message for information */
printf("\r\n Writing to Log File (%s)....",file_name);
#endif
/* Write timestamp */
fprintf(fp, "%d,%d",timestamp,msec);
/* Write variable data */
for(int i = 0; i < size; i++)
{
fprintf(fp, ",%g",var[i]);
}
/* Write new line as we done */
fprintf(fp, "\n");
#if DEBUG
printf("Done");
#endif
/* Close the file */
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
#if CAPTURE_TIME
t.stop();
printf("\r\n The RMS Write log time taken was %d milliseconds\n", t.read_ms());
#endif
}
}
/**
* @brief Function to log RMS Header
* @note sequence must be in the same order with variableList
* @param timestamp - time structure to get Date
* @retval None
*/
void FILEMANAGER_LogRMSHeader(FILE *fp, time_t timestamp, char file_name[])
{
#if DEBUG
/* opened file so can write */
printf("\r\n Writing Header to Log File (%s)....",file_name);
#endif
fprintf(fp, "%s,%s",RMS_HEADER_TIME,RMS_HEADER_MSECOND);
for(int i = 0; i < m_amountVarList; i++)
{
fprintf(fp, ",%s",m_varList[i].varName);
}
/* Write new line as done */
fprintf(fp, "\n-,-");
/* Write the unit of variables to the file */
for(int i = 0; i < m_amountVarList; i++)
{
fprintf(fp, ",%s",m_varList[i].varUnit);
}
/* Write new line as done */
fprintf(fp, "\n");
#if DEBUG
printf("Done");
#endif
}
/**
* @brief Function to log Mini RMS System Data
* @note this file is only for debug
* @param gps_interval - gps interval
* @param rms_interval - rms interval
* @param isResetCausedByWdg - flag to indicate system restart by watchdog
* @retval None
*/
void FILEMANAGER_LogSystemData(float gps_interval,float rms_interval, bool isResetCausedByWdg)
{
/* Open the file in append mode */
FILE *fp = fopen(MINIRMS_LOG_FILE_NAME, "a");
if (fp == NULL) {
/* In case of error, print the msg */
printf("Error! Unable to open file!\n");
/* Indicate LED Status (OFF)*/
FILEMANAGER_SetLedStatus(false);
}
else
{
/* Indicate LED Status (ON)*/
FILEMANAGER_SetLedStatus(true);
/* get Timestamp */
time_t seconds = INTERNALRTC_GetEpoch();
/* Write some message, which is TBD */
fprintf(fp, "\nStart Mini-RMS System with At UTC Time %s , Gps Interval = %f second, RMS Interval = %f second, Variable = %d variable(s) ",ctime(&seconds),gps_interval,rms_interval,m_amountVarList);
if (isResetCausedByWdg)
{
fprintf(fp, " **** Restart by Watchdog");
}
fclose(fp); // ensure you close the file after writing
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
}
}
/**
* @brief Utility to delete file
* @note
* @param filename - file name to be deleted
* @retval None
*/
void FILEMANAGER_Deletefile(char filename[])
{
#if UART_FILE_ACCESS
FILEMANAGER_AddPrefixFilename(filename, m_bufFileName);
#endif
printf("Deleting file '%s'...",filename);
#if UART_FILE_ACCESS
FILE *fp = fopen(m_bufFileName, "r"); // try and open file
#else
FILE *fp = fopen(filename, "r"); // try and open file
#endif
if (fp != NULL) { // if it does open...
fclose(fp); // close it
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
#if UART_FILE_ACCESS
remove(m_bufFileName); // and then delete
#else
remove(filename); // and then delete
#endif
printf("Done!\n");
}
// if we can't open it, it doesn't exist and so we can't delete it
}
/**
* @brief Utility to check file available
* @note
* @param filename - file name to be checked
* @retval true - file is exist , false - file is not exist
*/
bool FILEMANAGER_IsFileExist(char filename[])
{
bool exist = false;
FILE *fp = fopen(filename, "r"); // try and open file
if (fp != NULL) { // if it does open...
fclose(fp); // close it
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
exist = true;
}
return exist;
}
/**
* @brief Utility to get GPS Interval
* @note must be called after read the setup file
* @param None
* @retval GPS interval
*/
int FILEMANAGER_GPSInterval()
{
/* Return interval in int */
return ( m_GpsInterval );
}
/**
* @brief Utility to get Data Interval
* @note must be called after read the setup file
* @param None
* @retval Data interval
*/
int FILEMANAGER_DataInterval()
{
/* Return interval in int */
return ( m_DataInterval );
}
/**
* @brief Function to read the variable list file
* @note Recommended to call this function at initilization phase
* @param None
* @retval pointer to variable list
*/
Variable_Data_TypeDef * FILEMANAGER_ReadVarFile()
{
/* Open the file with reading mode */
FILE *fp = fopen(m_varListFileName, "r");
if (fp == NULL)
{
/* if it can't open the file then print error message */
printf("\nError! Unable to open file! %s \n", m_varListFileName);
/* Indicate LED Status (OFF)*/
FILEMANAGER_SetLedStatus(false);
return NULL;
}
else
{
/* Indicate LED Status (ON)*/
FILEMANAGER_SetLedStatus(true);
/* Allocate buffer for reading */
char buf[READ_FILE_BUFFER_SIZE];
int index = 0;
/* Initialize return value */
memset(m_varList, ' ', sizeof(m_varList));
/* Read line from the file */
while (fgets(buf, sizeof(buf), fp) != NULL)
{
/* Check the TAG */
if (strstr (buf,VAR_NAME_TAG))
{
/* Found variable TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varName);
}
else if (strstr (buf,VAR_ADDR_TAG))
{
/* Found variable address TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varAddress);
}
else if (strstr (buf,VAR_TYPE_TAG))
{
/* Found variable type TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varType);
}
else if (strstr (buf,VAR_LSB1_TAG))
{
/* Found variable LSB1 TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varLSB1);
}
else if (strstr (buf,VAR_LSB2_TAG))
{
/* Found variable LSB2 TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varLSB2);
}
else if (strstr (buf,VAR_BITMASK_TAG))
{
/* Found variable BitMask TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varBitMask);
}
else if (strstr (buf,VAR_UNIT_TAG))
{
/* Found variable unit TAG, populate it*/
FILEMANAGER_GetXmlText(buf , m_varList[index].varUnit);
index++;
}
}
/* Close File */
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
/* Populate amount */
m_amountVarList = index;
/* Return variable list */
return m_varList;
}
}
/**
* @brief Function to amount of variable for data logging
* @note Must be called after readVarFile
* @param None
* @retval amount of variable list
*/
int FILEMANAGER_GetAmountVarList()
{
return m_amountVarList;
}
/**
* @brief Function to get variable list
* @note Must be called after readVarFile
* @param None
* @retval pointer to variable list
*/
Variable_Data_TypeDef * FILEMANAGER_GetVarList()
{
return m_varList;
}
/**
* @brief Function to get Receieve ID
* @note Must be called after readSetupFile
* @param None
* @retval Receieve ID
*/
uint32_t FILEMANAGER_GetRxID()
{
return m_RxID;
}
/**
* @brief Function to get Transmit ID
* @note Must be called after readSetupFile
* @param None
* @retval Transmit ID
*/
uint32_t FILEMANAGER_GetTxID()
{
return m_TxID;
}
/**
* @brief Utility to play with LED status
* @note Libary user need to assign proper PinName to LED_SDCARD
* @param on - True for turning LED ON, otherwise LED off
* @retval None
*/
static void FILEMANAGER_SetLedStatus(bool on)
{
/* Check LED Connection */
if (ledStatus.is_connected())
{
/* Set LED regarding to given argment */
if (m_sdCardIsPresent)
{
ledStatus = on;
}
else
{
ledStatus = false;
}
}
#if DEBUG
else
{
printf("\r\nSDCard LED is not connected !!");
}
#endif
}
#if UART_FILE_ACCESS
/**
* @brief Utility to show list of file in SD Card
* @param serial - pointer to serial to be display as output
* @retval None
*/
void FILEMANAGER_listDir(Serial* serial)
{
DIR *d;
struct dirent *p;
d = opendir("/sd");
if (d != NULL) {
while ((p = readdir(d)) != NULL)
{
if (serial != NULL)
{
serial->printf(" - %s\n\r", p->d_name);
}
else
{
printf(" - %s\n\r", p->d_name);
}
}
} else {
printf("Could not open directory!\n");
}
closedir(d);
}
/**
* @brief Utility to display content of specific file
* @param serial - pointer to serial to be display as output
* @param filename - filename to be read
* @retval None
*/
void FILEMANAGER_DisplayFile(Serial* serial, char* filename)
{
FILEMANAGER_AddPrefixFilename(filename, m_bufFileName);
/* Open the file with reading mode */
FILE *fp = fopen(m_bufFileName, "r");
if (fp == NULL)
{
/* if it can't open the file then print error message */
if (serial != NULL)
{
serial->printf("\nError! Unable to open file! %s \n", filename);
}
else
{
printf("\nError! Unable to open file! %s \n", filename);
}
}
else
{
/* Allocate buffer for reading file */
char buf[READ_FILE_BUFFER_SIZE];
/* Read line from the file */
while (fgets(buf, sizeof(buf), fp) != NULL)
{
if (serial != NULL)
{
serial->printf("\n%s", buf);
}
else
{
printf("\n%s", buf);
}
#if WATCHDOG_ENABLE
/** restart Watchdog */
wd.Service();
#endif
}
/* Close File */
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
}
}
/**
* @brief Utility to replace content of specific file
* @param serial - pointer to serial to be display as output
* @param filename - filename to be replace
* @retval None
*/
WritingFileStatus FILEMANAGER_WriteFile(Serial* serial, char* filename, char* input)
{
WritingFileStatus status = FILE_OK;
FILEMANAGER_AddPrefixFilename(filename, m_bufFileName);
FILE *fp = fopen(m_bufFileName, "a");
if (fp == NULL)
{
/* if it can't open the file then print error message */
if (serial != NULL)
{
serial->printf("\nError! Unable to open file! %s \n", filename);
}
else
{
printf("\nError! Unable to open file! %s \n", filename);
}
status = FILE_ERROR;
}
else
{
fprintf(fp, "%s",input);
fclose(fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
free(fp);
#endif
}
return status;
}
static void FILEMANAGER_AddPrefixFilename(char* in, char* out)
{
sprintf(out,"%s%s", PREFIX_FILE_NAME, in);
}
#endif
