#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define NVS_AP_VER "20110718"
#define READ_NVS_WISNVS 0x0000
#define READ_NVS_UBOOT_VERSION 0x0001
#define WRITE_UBOOT 0x0008
#define READ_NVS_SERIAL 0x0002
#define WRITE_NVS_SERIAL 0x0003
#define READ_NVS_SERIAL2 0x0004
#define WRITE_NVS_SERIAL2 0x0005
//++++add for new sn
#define READ_NVS_PCBA_SERIAL 0x0006
#define WRITE_NVS_PCBA_SERIAL 0x0007
#define WIS_NVS_HEADER_SIZE 7
#define SN_SIZE 23
#define UBOOT_VERSION_SIZE 83
#define RESERVED_SIZE 128
#define DEV_NAME "/dev/block/mmcblk0"
#define NVS_OFFSET_BYTES 0xb19a*512
struct NVS
{
char wisNvs[WIS_NVS_HEADER_SIZE+1]; //a fixed string idefined as WISNVS
char serialNumber[SN_SIZE+1];
char serialNumber2[SN_SIZE+1];
char uboot_version[UBOOT_VERSION_SIZE+1];
//++++add a Serial Number
char PCBA_serialNumber[SN_SIZE+1];
char reserved_0[RESERVED_SIZE];
};
static int nvs_open_dev()
{
int g_dev = open( DEV_NAME, O_RDWR);
if (g_dev != -1)
goto done;
printf("Attemped to open %s fail\r\n",DEV_NAME);
return 0;
done:
return g_dev;
}
unsigned int nvs_get_offset(int g_dev)
{
#if 0
unsigned int g_disk_size = lseek(g_dev, 0, SEEK_END);
g_disk_size = g_disk_size - NVS_OFFSET_BYTES;
#endif
return NVS_OFFSET_BYTES;
}
-
static int nvs_write_NVS(struct NVS *g_nvs, int g_dev)
{
unsigned int nvs_start_offset = nvs_get_offset(g_dev);
//printf("write_NVS sector %d\n", nvs_start_offset/SECTOR_SIZE);
if( -1 ==lseek(g_dev, (off_t)nvs_start_offset, SEEK_SET ) )
{
printf( "lseek 0x%x fail\n", nvs_start_offset );
return 0;
}
int ret = write( g_dev, g_nvs, sizeof(struct NVS) );
return 1;
}
static int nvs_read_NVS(struct NVS *g_nvs, int g_dev)
{
unsigned int nvs_start_offset = nvs_get_offset(g_dev);
//printf("read_NVS sector %d\n", nvs_start_offset/SECTOR_SIZE);
if( -1 ==lseek( g_dev, (off_t)nvs_start_offset, SEEK_SET ) )
{
printf( "lseek 0x%x fail\n", nvs_start_offset );
return 0;
}
int ret = read( g_dev, g_nvs, sizeof(struct NVS) );
if( 0!=strcmp( g_nvs->wisNvs , "WISNVS") )
{
printf( "This is the first time to write NVS. \n");
printf( "Initialize the NVS block.\n");
memset( g_nvs, 0, sizeof(struct NVS) );
strcpy( g_nvs->wisNvs, "WISNVS");
nvs_write_NVS(g_nvs, g_dev);
}
return 1;
}
static void help(void)
{
fprintf(stderr,
"Usage: wisNVS\n"
" Read Mode:\n"
" ->Serial Number : WIS_NVS -rs\n"
" ->Serial Number 2 : WIS_NVS -rs2\n"
" ->u-Boot version : WIS_NVS -ru\n"
" ->PCBA Serial Number : WIS_NVS -rpcba\n"
);
}
int main( int argc, char *argv[])
{
int operation = 0;
//printf( "argc:%d\n", argc);
if( argc >1)
{
if( 0==strcmp( "-rw", argv[1]))
operation = READ_NVS_WISNVS;
else if( 0==strcmp( "-rs", argv[1]))
operation = READ_NVS_SERIAL;
else if( 0==strcmp( "-rs2", argv[1]))
operation = READ_NVS_SERIAL2;
else if( 0==strcmp( "-ru", argv[1]))
operation = READ_NVS_UBOOT_VERSION;
else if( 0==strcmp( "-rpcba", argv[1]))
operation = READ_NVS_PCBA_SERIAL;
else if( 0==strcmp( "-ws", argv[1]))
operation = WRITE_NVS_SERIAL;
else if( 0==strcmp( "-ws2", argv[1]))
operation = WRITE_NVS_SERIAL2;
else if( 0==strcmp( "-wpcba", argv[1]))
operation = WRITE_NVS_PCBA_SERIAL;
else if( 0==strcmp( "-wu", argv[1]))
operation = WRITE_UBOOT;
else if( 0==strcmp( "--help", argv[1]))
{
help();
return -1;
}
else if( 0==strcmp( "-ver", argv[1]) )
{
printf("Wistron NVS AP version:%s \n",NVS_AP_VER);
return -1;
}
else
{
help();
return -1;
}
}
else
{
help();
return -1;
}
struct NVS *g_nvs =(struct NVS*)malloc(sizeof(struct NVS));
struct NVS *g_nvs_tmp =(struct NVS*)malloc(sizeof(struct NVS));
int g_dev = nvs_open_dev();
nvs_read_NVS(g_nvs, g_dev);
switch(operation){
case READ_NVS_WISNVS:
printf("NVS :%s\n",g_nvs->wisNvs);
break;
case READ_NVS_UBOOT_VERSION:
printf("u-boot version :%s\n",g_nvs->uboot_version);
break;
case READ_NVS_SERIAL:
printf("%s\n",g_nvs->serialNumber);
break;
case WRITE_NVS_SERIAL:
if(argc < 3)
printf("Input serial number error\n");
else
{
memset(g_nvs->serialNumber,0,sizeof(g_nvs->serialNumber));
strcpy(g_nvs->serialNumber,argv[2]);
nvs_write_NVS(g_nvs, g_dev);
nvs_read_NVS(g_nvs_tmp, g_dev);
if( 0!=strcmp(g_nvs->serialNumber, g_nvs_tmp->serialNumber) )
{
printf( "Write SN fail. \n");
}
}
break;
case WRITE_UBOOT:
if(argc < 3)
printf("Input serial number error\n");
else
{
memset(g_nvs->uboot_version,0,sizeof(g_nvs->uboot_version));
strcpy(g_nvs->uboot_version,argv[2]);
nvs_write_NVS(g_nvs, g_dev);
nvs_read_NVS(g_nvs_tmp, g_dev);
if( 0!=strcmp(g_nvs->uboot_version, g_nvs_tmp->uboot_version) )
{
printf( "Write SN fail. \n");
}
}
break;
case READ_NVS_SERIAL2:
printf("%s\n",g_nvs->serialNumber2);
break;
case WRITE_NVS_SERIAL2:
if(argc < 3)
printf("Input serial number error\n");
else
{
memset(g_nvs->serialNumber2,0,sizeof(g_nvs->serialNumber2));
strcpy(g_nvs->serialNumber2,argv[2]);
nvs_write_NVS(g_nvs, g_dev);
nvs_read_NVS(g_nvs_tmp, g_dev);
if( 0!=strcmp(g_nvs->serialNumber2, g_nvs_tmp->serialNumber2) )
{
printf( "Write SN fail. \n");
}
}
break;
case READ_NVS_PCBA_SERIAL:
printf("%s\n",g_nvs->PCBA_serialNumber);
break;
case WRITE_NVS_PCBA_SERIAL:
if(argc < 3)
printf("Input PCBA serial number error\n");
else
{
memset(g_nvs->PCBA_serialNumber,0,sizeof(g_nvs->PCBA_serialNumber));
strcpy(g_nvs->PCBA_serialNumber,argv[2]);
nvs_write_NVS(g_nvs, g_dev);
nvs_read_NVS(g_nvs_tmp, g_dev);
if( 0!=strcmp(g_nvs->PCBA_serialNumber, g_nvs_tmp->PCBA_serialNumber) )
{
printf( "Write SN fail. \n");
}
}
break;
}
close(g_dev);
free(g_nvs);
free(g_nvs_tmp);
return 0;
}