📄 nvs.c
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2002 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file nvs.c
*
* $Revision: 1.9 $
*
* Public API to the Non-Volatile Storage (NVS) module.
*
*/
#include <stdio.h>
#include <string.h>
#include "vdvd_types.h"
#include "nvs.h"
#include "osapi.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_NVS DBG_ERROR
#define DBG_ON(x) (DBG_NVS >= x)
/**
* Local constants
* TODO: Make the path for sysparam.dat configurable
*/
#define NVS_DEV_LIMIT 1
#if 1
#define NVS_FILE "sysparam.dat"
#else
#define NVS_FILE "/hd0/sysparam.dat"
#endif
/**
* NVS handle data.
*/
typedef struct tagNVS_HANDLE_DATA
{
BYTE bDevNumber;
FILE *pDataFile;
ULONG ulStorageSize;
PVOID pvBuffer;
OS_SEM_ID critical_section;
} NVS_HANDLE_DATA;
/**
* NVS manager
*/
typedef struct tagNVS_MANAGER
{
USHORT usCount;
NVS_HANDLE_DATA *aNVS[NVS_DEV_LIMIT];
} NVS_MANAGER;
/**
* Local variables
*/
static NVS_MANAGER m_NvsManager = {0, {NULL} };
/**
* NVSOpen -- Create a handle to an NVS device.
*
* @param
* bDevNum -- device number to use for the NVS handle
* ulSize -- size of nvs buffer for this device handle
*
* @retval
* NVS_HANDLE, a handle to an NVS device, if successful
* NULL on failure
*
* @remark
* For this implementation, HD is the only available storage device,
* so bDevNum is ignored.
*/
NVS_HANDLE NVSOpen(BYTE bDevNum, ULONG ulSize)
{
NVS_HANDLE_DATA *pNvs = NULL;
NVS_HANDLE hNVS = NULL;
/* Check if we have reached the device limit */
if (m_NvsManager.usCount == NVS_DEV_LIMIT)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: device limit reached!\n"));
goto errout;
}
/* Allocate NVS handle */
pNvs = (NVS_HANDLE_DATA *)OS_MemAlloc(sizeof(NVS_HANDLE_DATA) );
if (pNvs == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure allocating handle!\n"));
goto errout;
}
/* Create buffer for this handle */
pNvs->pvBuffer = (PVOID)OS_MemAlloc(ulSize);
if (pNvs->pvBuffer == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure creating buffer!\n"));
goto errout;
}
/* Set the device number and storage size */
pNvs->bDevNumber = bDevNum;
pNvs->ulStorageSize = ulSize;
/* Create critical section semaphore */
pNvs->critical_section = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
if (pNvs->critical_section == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: Could not create semaphore\n"));
goto errout;
}
/* Open the storage file in read/write mode */
pNvs->pDataFile = fopen(NVS_FILE, "r+");
if (pNvs->pDataFile == NULL)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("NVSOpen: Creating NVS file\n"));
/* create file */
pNvs->pDataFile = fopen(NVS_FILE, "w");
if (pNvs->pDataFile == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure creating file!\n"));
goto errout;
}
/* reopen file in read/write mode */
pNvs->pDataFile = freopen(NVS_FILE, "r+", pNvs->pDataFile);
if (pNvs->pDataFile == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure re-opening file in rw mode!\n"));
goto errout;
}
}
/* Add this NVS handle to the NVS manager */
m_NvsManager.aNVS[m_NvsManager.usCount] = pNvs;
m_NvsManager.usCount++;
/* Set the NVS handle to return */
hNVS = (NVS_HANDLE)pNvs;
pNvs = NULL;
DBGPRINT(DBG_ON(DBG_TRACE), ("NVSOpen: NVS handle successfully created\n"));
return (hNVS);
errout:
if (pNvs != NULL)
{
if (pNvs->pDataFile != NULL)
{
/* close the file */
fclose(pNvs->pDataFile);
}
/* delete critical section sem */
if (pNvs->critical_section != 0)
{
OS_SemDelete(pNvs->critical_section);
pNvs->critical_section = 0;
}
/* free buffer */
if (pNvs->pvBuffer != NULL)
{
/* free NVS handle data */
OS_MemFree(pNvs->pvBuffer);
pNvs->pvBuffer = NULL;
}
/* free NVS handle data */
OS_MemFree(pNvs);
pNvs = NULL;
}
return (NULL);
}
/**
* NVSClose -- Delete the handle to an NVS device
*
* @param
* tNVS -- handle to an NVS device
*
* @retval
* NVS_ERR value
*/
NVS_ERR NVSClose(NVS_HANDLE tNVS)
{
if (tNVS != NULL)
{
NVS_HANDLE_DATA *pNvs = (NVS_HANDLE_DATA *)tNVS;
USHORT i;
/* close the file */
if (pNvs->pDataFile != NULL)
{
fclose(pNvs->pDataFile);
}
/* delete critical section sem */
if (pNvs->critical_section != 0)
{
OS_SemDelete(pNvs->critical_section);
pNvs->critical_section = 0;
}
/* free buffer */
if (pNvs->pvBuffer != NULL)
{
/* free NVS handle data */
OS_MemFree(pNvs->pvBuffer);
pNvs->pvBuffer = NULL;
}
/* remove this NVS handle from NVS manager */
for (i = 0; i < m_NvsManager.usCount; i++)
{
if (m_NvsManager.aNVS[i] == pNvs)
{
m_NvsManager.aNVS[i] = NULL;
m_NvsManager.usCount--;
break;
}
}
/* free NVS handle data */
OS_MemFree(pNvs);
pNvs = NULL;
/* point handle to NULL */
tNVS = NULL;
DBGPRINT(DBG_ON(DBG_TRACE), ("NVSClose: NVS handle deleted\n"));
return (NVS_SUCCESS);
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSClose: NVS handle is NULL!\n"));
return (NVS_FAILURE);
}
}
/**
* NVSLoad -- Load buffer with data stored in NVS device
*
* @param
* tNVS -- handle to an NVS device to load from
* pvBuffer -- buffer to load data into
* ulBufSize -- size of buffer pointed to by pvBuffer
*
* @retval
* NVS_ERR value
*
* @remark
* ulBufSize must be the same size that was specified when the NVS
* device was open. If sizes are different, then NVS_INVALID_BUFFER_SIZE
* will be returned.
*/
NVS_ERR NVSLoad(NVS_HANDLE tNVS, PVOID pvBuffer, ULONG ulBufSize)
{
NVS_HANDLE_DATA *pNvs = (NVS_HANDLE_DATA *)tNVS;
/* Check for Null pointers */
if ( (pNvs == NULL) || (pvBuffer == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: NULL pointer!\n"));
return (NVS_NULL_PTR);
}
/* Check for valid buffer size */
if (pNvs->ulStorageSize != ulBufSize)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: Invalid buffer size!\n"));
return (NVS_INVALID_BUFFER_SIZE);
}
/* entering critical section */
OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);
/* Zero the NVS storage buffer before reading file data into it */
memset(pNvs->pvBuffer, 0x00, (size_t)pNvs->ulStorageSize);
/* flush file stream */
if (fflush(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure flushing file stream!\n"));
goto errout;
}
/* Set file position to beginning of file */
if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure setting file position!\n"));
goto errout;
}
/* Read the file and store data in NVS storage buffer */
fread(pNvs->pvBuffer, 1, (size_t)pNvs->ulStorageSize, pNvs->pDataFile);
/* check for error from read */
if (ferror(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure reading file!\n"));
goto errout;
}
/* copy this NVS storage buffer to return buffer */
memcpy(pvBuffer, pNvs->pvBuffer, ulBufSize);
/* leaving critical section */
OS_SemGive(pNvs->critical_section);
return (NVS_SUCCESS);
errout:
OS_SemGive(pNvs->critical_section);
return (NVS_FAILURE);
}
/**
* NVSStore -- Store data from buffer onto NVS device.
*
* @param
* tNVS -- handle to an NVS device to store data to
* pvBuffer -- buffer containing the data to store
* ulBufSize -- size of buffer pointed to by pvBuffer
*
* @retval
* NVS_ERR value
*
* @remark
* ulBufSize must be the same size that was specified when the NVS
* device was open. If sizes are different, then NVS_INVALID_BUFFER_SIZE
* will be returned.
*/
NVS_ERR NVSStore(NVS_HANDLE tNVS, PVOID pvBuffer, ULONG ulBufSize)
{
NVS_HANDLE_DATA *pNvs = (NVS_HANDLE_DATA *)tNVS;
/* Check for Null pointers */
if ( (pNvs == NULL) || (pvBuffer == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: NULL pointer!\n"));
return (NVS_NULL_PTR);
}
/* Check for valid buffer size */
if (pNvs->ulStorageSize != ulBufSize)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: Invalid buffer size!\n"));
return (NVS_INVALID_BUFFER_SIZE);
}
/* entering critical section */
OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);
/* flush file stream */
if (fflush(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure flushing file stream!\n"));
goto errout;
}
/* Set file position to beginning of file */
if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure setting file position!\n"));
goto errout;
}
/* Write the buffer to the NVS file */
fwrite(pvBuffer, 1, (size_t)ulBufSize, pNvs->pDataFile);
/* check for error from write */
if (ferror(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure writing file!\n"));
goto errout;
}
/* leaving critical section */
OS_SemGive(pNvs->critical_section);
return (NVS_SUCCESS);
errout:
OS_SemGive(pNvs->critical_section);
return (NVS_FAILURE);
}
/**
* NVSSet -- Set entire buffer on NVS device to a specified value.
*
* @param
* tNVS -- handle to an NVS device
* bValue -- value to set each byte of NVS buffer to
*
* @retval
* NVS_ERR value
*/
NVS_ERR NVSSet(NVS_HANDLE tNVS, BYTE bValue)
{
NVS_HANDLE_DATA *pNvs = (NVS_HANDLE_DATA *)tNVS;
/* Check for Null pointers */
if (pNvs == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: NULL pointer!\n"));
return (NVS_NULL_PTR);
}
/* entering critical section */
OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);
/* set the NVS storage buffer before writing data into file */
memset(pNvs->pvBuffer, (int)bValue, (size_t)pNvs->ulStorageSize);
/* flush file stream */
if (fflush(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure flushing file stream!\n"));
goto errout;
}
/* Set file position to beginning of file */
if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure setting file position!\n"));
goto errout;
}
/* Write the buffer to the NVS file */
fwrite(pNvs->pvBuffer, 1, (size_t)pNvs->ulStorageSize, pNvs->pDataFile);
/* check for error from write */
if (ferror(pNvs->pDataFile) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure writing file!\n"));
goto errout;
}
/* leaving critical section */
OS_SemGive(pNvs->critical_section);
return (NVS_SUCCESS);
errout:
OS_SemGive(pNvs->critical_section);
return (NVS_FAILURE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -