16位nvram读写地址对齐方法,当以4字节32位方式往nvram的奇地址读写数据的时候,需要注意对齐的问题,因为数据只能16位16位的往里面写,这里采用一个2个字节的数组来作为对齐的中间buff,具体操作见源码。
/********************************************************************************************
* 功能:从nvRam中获取缓存的数据
*
* 参数:
* pBuf 将获取的数据缓存起来的地址空间
* len 获取的数据长度
* offset 数据在nvRam中存放位置的偏移值
*
* 返回值:
* OK 正常获取到读取的nvRam值
* ERROR 参数不合法的时候的返回值
*/
int nv_ram_get(char * pBuf, UINT32 len, UINT32 offset)
{
volatile UINT16 * pMem16;
int i;
int end;
UINT8 word[2];
/* 检查输入的参数值是否合法 */
if((pBuf == NULL) ||(offset > NVRAM_SIZE) ||((offset+len) > NVRAM_SIZE) )
{
return ERROR;
}
/* 获取0长度的数据则直接返回 */
if(len == 0)
{
return OK;
}
/* 设置获取数据的范围(起始值,最终位置) */
end = (UINT32)len;
pMem16 = (UINT16 *)(NVRAM_BASE_ADRS + offset);
nvRamUnlock_Read();
/*读取字节对齐处理*/
if ((UINT32)pMem16 & 0x1)
{
*(UINT16*)word = *(UINT16 *)((UINT32)pMem16 - 1);
pBuf[0] = word[1];
pMem16 = (UINT16 *)((UINT32)pMem16 + 1);
pBuf++;
end--;
}
/* 读取对齐字节余下的字节 */
for( i = 0; i < end/2; i++)
{
*(UINT16 *)&pBuf[i*2] = *pMem16++;
}
/* 读取最后的对齐字节如果对齐结果正好无余 */
if(end & 0x1)
{
*(UINT16*)word = *pMem16;
pBuf[end-1] = word[0];
}
return OK;
}
/****************************************************************************
*
* nvRamSet
* 功能: 将数据写入到nvRam中
*
* 参数:
* pBuf : 要写入nv的缓存数据空间
* len : 要写入的数据的长度
* offset: 写入的数据偏移nvRam起始位置的偏移值
* 返回值:
* OK : 写入成功
* ERROR : 失败
*/
int nv_ram_set(const char * pBuf, UINT32 len, UINT32 offset)
{
volatile UINT16 * pMem16;
int i;
int end;
UINT8 word[2];
/* 参数检查 */
if((pBuf == NULL) ||(offset > NVRAM_SIZE) ||((offset+len) > NVRAM_SIZE) )
{
return ERROR;
}
/* 写入长度为0的话直接返回 */
if(len == 0)
{
return OK;
}
/* 设置指针的值 */
end = (UINT32)len;
pMem16 = (UINT16 *)(NVRAM_BASE_ADRS + offset);
nvRamUnlock_Write();
/*对齐处理*/
if ((UINT32)pMem16 & 0x1)
{
//第一块非对齐数据块的处理
*(UINT16*)word = *(UINT16 *)((UINT32)pMem16 - 1);
word[1] = pBuf[0];
*(UINT16 *)((UINT32)pMem16 - 1) = *(UINT16*)word;
/*调整指针和指向*/
pMem16 = (UINT16 *)((UINT32)pMem16 + 1);
pBuf++;
end--;
}
/* 剩余数据块的写 */
for ( i = 0; i < end/2; i++)
{
*pMem16++ = *(UINT16 *)&pBuf[i*2];
}
/* 如果需要的话写最后一个非对齐的字节 */
if (end & 0x1)
{
*(UINT16 *)word = *pMem16;
word[0] = pBuf[end-1];
*pMem16 = *(UINT16*)word;
}
return OK;
} |
本文介绍了一种针对16位NV-RAM的读写对齐技术,该技术允许以32位的方式高效处理奇数地址上的数据。通过使用额外的字节数组作为缓冲区,确保了数据的正确对齐,并提供了nv_ram_get和nv_ram_set两个关键函数的具体实现。
361

被折叠的 条评论
为什么被折叠?



