Files
TencentOS-tiny/components/connectivity/LoraWAN/system/nvmm.c
supowang edb2879617 first commit for opensource
first commit for opensource
2019-09-16 13:19:50 +08:00

174 lines
4.4 KiB
C

/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2013 Semtech
___ _____ _ ___ _ _____ ___ ___ ___ ___
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
embedded.connectivity.solutions===============
Description: LoRa MAC layer cryptographic functionality implementation
License: Revised BSD License, see LICENSE.TXT file include in the project
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
*/
#include <stdint.h>
#include "utilities.h"
#include "eeprom.h"
#include "nvmm.h"
#define NVMM_MAGIC_NUMBER 0xA23
typedef struct sDataBlockHeader
{
/*
* Checksum
*/
size_t CSum;
/*
* Size of current data block
*/
size_t Num;
} DataBlockHeader_t;
static uint16_t DataBlockAdrCnt = sizeof( DataBlockHeader_t );
static uint32_t ComputeChecksum( uint8_t* data, uint16_t size )
{
uint32_t checksum = NVMM_MAGIC_NUMBER; // Start with a magic number
for( uint16_t i = 0; i < size; i++ )
{
checksum += data[i];
}
return checksum;
}
static uint32_t ComputeChecksumNvm( uint16_t addr, uint16_t size )
{
uint32_t checksum = NVMM_MAGIC_NUMBER; // Start with a magic number
uint8_t data = 0;
for( uint16_t i = 0; i < size; i++ )
{
EepromReadBuffer( addr + i, &data, 1 );
checksum += data;
}
return checksum;
}
/*
* API functions
*/
NvmmStatus_t NvmmDeclare( NvmmDataBlock_t* dataB, size_t num )
{
NvmmStatus_t retval = NVMM_ERROR;
// Increment the internal data block address
dataB->virtualAddr = DataBlockAdrCnt;
if( NvmmVerify( dataB, num ) == NVMM_SUCCESS )
{
retval = NVMM_SUCCESS;
}
// If it is the first time or memory was corrupted
else
{
DataBlockHeader_t dataBHdr;
dataBHdr.CSum = 0;
dataBHdr.Num = num;
EepromWriteBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) );
retval = NVMM_FAIL_CHECKSUM;
}
DataBlockAdrCnt = DataBlockAdrCnt + num + sizeof( DataBlockHeader_t );
return retval;
}
NvmmStatus_t NvmmVerify( NvmmDataBlock_t* dataB, size_t num )
{
DataBlockHeader_t dataBHdr;
// Read the data block header to obtain the size of data block
EepromReadBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) );
// Catch already a mismatch of sizes
if( num != dataBHdr.Num )
{
return NVMM_FAIL_CHECKSUM;
}
if( ComputeChecksumNvm( dataB->virtualAddr, dataBHdr.Num ) == dataBHdr.CSum )
{
return NVMM_SUCCESS;
}
else
{
return NVMM_FAIL_CHECKSUM;
}
}
NvmmStatus_t NvmmWrite( NvmmDataBlock_t* dataB, void* src, size_t num )
{
CRITICAL_SECTION_BEGIN( );
DataBlockHeader_t dataBHdr;
// Read the data block header to obtain the maximum allowed size to write
EepromReadBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( dataBHdr ) );
if( num > dataBHdr.Num )
{
CRITICAL_SECTION_END( );
return NVMM_ERROR_SIZE;
}
dataBHdr.CSum = ComputeChecksum( ( uint8_t* ) src, num );
// Update data block header
EepromWriteBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) );
// Write data block
EepromWriteBuffer( dataB->virtualAddr, ( uint8_t* ) src, num );
CRITICAL_SECTION_END( );
return NVMM_SUCCESS;
}
NvmmStatus_t NvmmRead( NvmmDataBlock_t* dataB, void* dst, size_t num )
{
CRITICAL_SECTION_BEGIN( );
DataBlockHeader_t dataBHdr;
// Read the data block header to obtain the maximum allowed size to write
EepromReadBuffer( (dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t * ) &dataBHdr, sizeof( dataBHdr ) );
if( num > dataBHdr.Num )
{
CRITICAL_SECTION_END( );
return NVMM_ERROR_SIZE;
}
// data block
EepromReadBuffer( dataB->virtualAddr, ( uint8_t* ) dst, num );
CRITICAL_SECTION_END( );
return NVMM_SUCCESS;
}