2017年7月问题记录与总结——16位nvram读写对齐操作

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值