在某些情况下,需要移植的代码是直接访问寄存器的,当移植到linux时,可利用mmap创建一个适配层,减少开发工作量。
通过操作/dev/mem设备文件,以及mmap函数,将寄存器的地址映射到用户空间,直接在应用层对寄存器进行操作。
mmap的使用示例:
#define REG_AREA_LEN 1024
static int halFileH = -1;
unsigned long gRegBase = 0;
/*!
* HAL layer entry point.
* Mappes regisers to the HOST virtual address space.
*/
int HalInit(void)
{
unsigned long *pVirtBuffAddr = NULL;
halFileH = open("/dev/mem", O_RDWR|O_SYNC);
if (halFileH < 0) {
return 1;
}
(void)fcntl(halFileH, F_SETFD, FD_CLOEXEC);
pVirtBuffAddr = (uint32_t *)mmap(0, REG_AREA_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, halFileH, physicalAddress);
if ((pVirtBuffAddr == NULL) || (pVirtBuffAddr == MAP_FAILED)) {
close(halFileH);
halFileH = -1;
return 2;
}
gRegBase = (unsigned long)pVirtBuffAddr;
return HAL_OK;
}
/*!
* HAL exit point.
* Unmaps registers.
*/
int HalTerminate(void)
{
if (halFileH < 0) {
return 1;
}
munmap((uint32_t *)gRegBase, REG_AREA_LEN);
close(halFileH);
halFileH = -1;
gRegBase = 0;
return HAL_OK;
}
/*!
* Read memory-mapped-IO register.
*
* \param regOffset The offset of the register to read
* \return uint32_t Return the value of the given register
*/
#define HAL_READ_REGISTER(regOffset) \
(*((volatile uint32_t *)(gRegBase + (regOffset))))
/*!
* Write memory-mapped-IO register.
*
* \param regOffset The offset of the register to write
* \param val The value to write
*/
#define HAL_WRITE_REGISTER(regOffset, val) \
(*((volatile uint32_t *)(gRegBase + (regOffset))) = (val))