ioremap映射的问题
时间:2010-09-08
来源:互联网
本帖最后由 marcomo1986 于 2010-09-09 08:53 编辑
我写的驱动要对外设I/O资源进行操作,需要对物理地址进行映射,部分程序如下:
void *AC97C_VIR_BASE;
#define AC97C_PHY_BASE 0xfffa0000
#define AC97C_CAMR_VIR AC97C_CAMR+AC97C_VIR_BASE
#define AC97C_CBMR_VIR AC97C_CBMR+AC97C_VIR_BASE
#define AC97C_COTHR_VIR AC97C_COTHR+AC97C_VIR_BASE
AC97C_VIR_BASE = ioremap( AC97C_PHY_BASE, 0x100 );
在程序里
size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
这两句能编译通过,但是其他的涉及虚拟地址映射的部分都编译出错了
比如:
(AT91C_BASE_AC97C->AC97C_COTHR_VIR) = data;
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_RXRDY;
都提示:
error: invalid lvalue in assignment
这是为什么呢?请哪位高手指点小弟一下
我写的驱动要对外设I/O资源进行操作,需要对物理地址进行映射,部分程序如下:
void *AC97C_VIR_BASE;
#define AC97C_PHY_BASE 0xfffa0000
#define AC97C_CAMR_VIR AC97C_CAMR+AC97C_VIR_BASE
#define AC97C_CBMR_VIR AC97C_CBMR+AC97C_VIR_BASE
#define AC97C_COTHR_VIR AC97C_COTHR+AC97C_VIR_BASE
AC97C_VIR_BASE = ioremap( AC97C_PHY_BASE, 0x100 );
在程序里
size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
这两句能编译通过,但是其他的涉及虚拟地址映射的部分都编译出错了
比如:
(AT91C_BASE_AC97C->AC97C_COTHR_VIR) = data;
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_RXRDY;
都提示:
error: invalid lvalue in assignment
这是为什么呢?请哪位高手指点小弟一下
作者: marcomo1986 发布时间: 2010-09-08
咋没回复的呢?小弟有点着急请哪位大哥帮忙看一下
作者: marcomo1986 发布时间: 2010-09-09
代码贴的太少了,大写的看起来都是宏,不知道是不是宏,宏不可以这样用的。
再者若是虚拟地址则应该*(addr)=value。
再者若是虚拟地址则应该*(addr)=value。
作者: EZWORD 发布时间: 2010-09-09
本帖最后由 marcomo1986 于 2010-09-09 09:16 编辑
EZWORD (vs复仇之魂):大写的都是宏,那我改怎么改呢
我贴出了部分程序您看一下
#define AC97C_PHY_BASE 0xfffa0000 //AC97C的物理地址
#define PIO_PHY_BASE 0xffff4000 //PIO的物理地址
#define AIC_PHY_BASE 0xfffff000 //AIC的物理地址
#define PMC_PHY_BASE 0xfffffc00 //PMC的物理地址
void *AC97C_VIR_BASE;
void *PIO_VIR_BASE;
void *AIC_VIR_BASE;
void *PMC_VIR_BASE;
#define PIO_ASR_VIR PIO_ASR+PIO_VIR_BASE
#define PIO_PDR_VIR PIO_PDR+PIO_VIR_BASE
#define AC97C_CAMR_VIR AC97C_CAMR+AC97C_VIR_BASE
#define AC97C_CBMR_VIR AC97C_CBMR+AC97C_VIR_BASE
#define AC97C_COTHR_VIR AC97C_COTHR+AC97C_VIR_BASE
#define AC97C_COMR_VIR AC97C_COMR+AC97C_VIR_BASE
#define AC97C_IER_VIR AC97C_IER+AC97C_VIR_BASE
#define AC97C_PTCR_VIR AC97C_PTCR+AC97C_VIR_BASE
#define AC97C_TPR_VIR AC97C_TPR+AC97C_VIR_BASE
#define AC97C_TCR_VIR AC97C_TCR+AC97C_VIR_BASE
#define AC97C_TNPR_VIR AC97C_TNPR+AC97C_VIR_BASE
#define AC97C_TNCR_VIR AC97C_TNCR+AC97C_VIR_BASE
#define AC97C_RPR_VIR AC97C_RPR+AC97C_VIR_BASE
#define AC97C_RCR_VIR AC97C_RCR+AC97C_VIR_BASE
#define AC97C_RNPR_VIR AC97C_RNPR+AC97C_VIR_BASE
#define AC97C_RNCR_VIR AC97C_RNCR+AC97C_VIR_BASE
#define AC97C_ICA_VIR AC97C_ICA+AC97C_VIR_BASE
#define AC97C_OCA_VIR AC97C_OCA+AC97C_VIR_BASE
#define AC97C_COSR_VIR AC97C_COSR+AC97C_VIR_BASE
#define AC97C_IDR_VIR AC97C_IDR+AC97C_VIR_BASE
#define AC97C_CORHR_VIR AC97C_CORHR+AC97C_VIR_BASE
#define AC97C_CASR_VIR AC97C_CASR+AC97C_VIR_BASE
#define AC97C_SR_VIR AC97C_SR+AC97C_VIR_BASE
#define AC97C_IMR_VIR AC97C_IMR+AC97C_VIR_BASE
#define AC97C_MR_VIR AC97C_MR+AC97C_VIR_BASE
#define AIC_IDCR_VIR AIC_IDCR+AIC_VIR_BASE
#define AIC_SMR_VIR AIC_SMR+AIC_VIR_BASE
#define AIC_SVR_VIR AIC_SVR+AIC_VIR_BASE
#define AIC_ICCR_VIR AIC_ICCR+AIC_VIR_BASE
#define AIC_IECR_VIR AIC_IECR+AIC_VIR_BASE
#define PMC_PCER_VIR PMC_PCER+PMC_VIR_BASE
static unsigned char GetSampleSize(unsigned char channel)
{
unsigned int size=0;
// Check selected channel
if (channel == AC97C_CHANNEL_CODEC) {
return 2;
}
else if (channel == AC97C_CHANNEL_A) {
size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
}
else if (channel == AC97C_CHANNEL_B) {
size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
}
// Compute size in bytes given SIZE field
if ((size & 2) != 0) {
return 2;
}
else {
return 4;
}
}
///////////////////////////////////////////////////////////////////////////////////////
unsigned char AC97C_Transfer(
unsigned char channel,
unsigned char *pBuffer,
unsigned int numSamples,
Ac97Callback callback,
void *pArg)
{
unsigned int size;
unsigned int data;
Ac97Transfer *pTransfer;
// Check that no transfer is pending on the channel
pTransfer = &(ac97c.transfers[channel]);
if (pTransfer->numSamples > 0)
{
trace_LOG(trace_WARNING, "-W- AC97C_Transfer: Channel %d is busy\n\r",channel);
return AC97C_ERROR_BUSY;
}
// Fill transfer information
PTransfer->pBuffer = pBuffer;
pTransfer->numSamples = numSamples;
pTransfer->callback = callback;
pTransfer->pArg = pArg;
// Transmit or receive over codec channel
if (channel == AC97C_CODEC_TRANSFER) {
// Send command
data = *((unsigned int *) pTransfer->pBuffer);
(AT91C_BASE_AC97C->AC97C_COTHR_VIR) = data;
//size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
//size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
// Check if transfer is read or write
if ((data & AT91C_AC97C_READ) != 0) {
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_RXRDY;
}
else {
pTransfer->pBuffer += sizeof(unsigned int);
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_TXRDY;
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_IER_VIR) |= AT91C_AC97C_COEVT;
}
// Transmit over channel A
else if (channel == AC97C_CHANNEL_A_TRANSMIT) {
// Disable PDC
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_TXTDIS;
// Fill PDC buffers
//size = min(pTransfer->numSamples, MAX_PDC_COUNTER);
size = pTransfer->numSamples;
(AT91C_BASE_AC97C->AC97C_TPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_TCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
//size = min(pTransfer->numSamples - size, MAX_PDC_COUNTER);
size = pTransfer->numSamples - size;
if (size > 0) {
(AT91C_BASE_AC97C->AC97C_TNPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_TNCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_CAMR_VIR) |= AT91C_AC97C_PDCEN | AT91C_AC97C_ENDTX;
(AT91C_BASE_AC97C->AC97C_IER_VIR)|= AT91C_AC97C_CAEVT;
// Start transfer
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_TXTEN;
}
// Receive over channel A
else if (channel == AC97C_CHANNEL_A_RECEIVE) {
// Disable PDC
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_RXTDIS;
// Fill PDC buffers
//size = min(pTransfer->numSamples, MAX_PDC_COUNTER);
size = pTransfer->numSamples;
(AT91C_BASE_AC97C->AC97C_RPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_RCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
//size = min(pTransfer->numSamples - size, MAX_PDC_COUNTER);
size = pTransfer->numSamples - size;
if (size > 0) {
(AT91C_BASE_AC97C->AC97C_RNPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_RNCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_CAMR_VIR) |= AT91C_AC97C_PDCEN | AT91C_AC97C_ENDRX;
(AT91C_BASE_AC97C->AC97C_IER_VIR) |= AT91C_AC97C_CAEVT;
// Start transfer
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_RXTEN;
}
return 0;
}
EZWORD (vs复仇之魂):大写的都是宏,那我改怎么改呢
我贴出了部分程序您看一下
#define AC97C_PHY_BASE 0xfffa0000 //AC97C的物理地址
#define PIO_PHY_BASE 0xffff4000 //PIO的物理地址
#define AIC_PHY_BASE 0xfffff000 //AIC的物理地址
#define PMC_PHY_BASE 0xfffffc00 //PMC的物理地址
void *AC97C_VIR_BASE;
void *PIO_VIR_BASE;
void *AIC_VIR_BASE;
void *PMC_VIR_BASE;
#define PIO_ASR_VIR PIO_ASR+PIO_VIR_BASE
#define PIO_PDR_VIR PIO_PDR+PIO_VIR_BASE
#define AC97C_CAMR_VIR AC97C_CAMR+AC97C_VIR_BASE
#define AC97C_CBMR_VIR AC97C_CBMR+AC97C_VIR_BASE
#define AC97C_COTHR_VIR AC97C_COTHR+AC97C_VIR_BASE
#define AC97C_COMR_VIR AC97C_COMR+AC97C_VIR_BASE
#define AC97C_IER_VIR AC97C_IER+AC97C_VIR_BASE
#define AC97C_PTCR_VIR AC97C_PTCR+AC97C_VIR_BASE
#define AC97C_TPR_VIR AC97C_TPR+AC97C_VIR_BASE
#define AC97C_TCR_VIR AC97C_TCR+AC97C_VIR_BASE
#define AC97C_TNPR_VIR AC97C_TNPR+AC97C_VIR_BASE
#define AC97C_TNCR_VIR AC97C_TNCR+AC97C_VIR_BASE
#define AC97C_RPR_VIR AC97C_RPR+AC97C_VIR_BASE
#define AC97C_RCR_VIR AC97C_RCR+AC97C_VIR_BASE
#define AC97C_RNPR_VIR AC97C_RNPR+AC97C_VIR_BASE
#define AC97C_RNCR_VIR AC97C_RNCR+AC97C_VIR_BASE
#define AC97C_ICA_VIR AC97C_ICA+AC97C_VIR_BASE
#define AC97C_OCA_VIR AC97C_OCA+AC97C_VIR_BASE
#define AC97C_COSR_VIR AC97C_COSR+AC97C_VIR_BASE
#define AC97C_IDR_VIR AC97C_IDR+AC97C_VIR_BASE
#define AC97C_CORHR_VIR AC97C_CORHR+AC97C_VIR_BASE
#define AC97C_CASR_VIR AC97C_CASR+AC97C_VIR_BASE
#define AC97C_SR_VIR AC97C_SR+AC97C_VIR_BASE
#define AC97C_IMR_VIR AC97C_IMR+AC97C_VIR_BASE
#define AC97C_MR_VIR AC97C_MR+AC97C_VIR_BASE
#define AIC_IDCR_VIR AIC_IDCR+AIC_VIR_BASE
#define AIC_SMR_VIR AIC_SMR+AIC_VIR_BASE
#define AIC_SVR_VIR AIC_SVR+AIC_VIR_BASE
#define AIC_ICCR_VIR AIC_ICCR+AIC_VIR_BASE
#define AIC_IECR_VIR AIC_IECR+AIC_VIR_BASE
#define PMC_PCER_VIR PMC_PCER+PMC_VIR_BASE
static unsigned char GetSampleSize(unsigned char channel)
{
unsigned int size=0;
// Check selected channel
if (channel == AC97C_CHANNEL_CODEC) {
return 2;
}
else if (channel == AC97C_CHANNEL_A) {
size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
}
else if (channel == AC97C_CHANNEL_B) {
size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
}
// Compute size in bytes given SIZE field
if ((size & 2) != 0) {
return 2;
}
else {
return 4;
}
}
///////////////////////////////////////////////////////////////////////////////////////
unsigned char AC97C_Transfer(
unsigned char channel,
unsigned char *pBuffer,
unsigned int numSamples,
Ac97Callback callback,
void *pArg)
{
unsigned int size;
unsigned int data;
Ac97Transfer *pTransfer;
// Check that no transfer is pending on the channel
pTransfer = &(ac97c.transfers[channel]);
if (pTransfer->numSamples > 0)
{
trace_LOG(trace_WARNING, "-W- AC97C_Transfer: Channel %d is busy\n\r",channel);
return AC97C_ERROR_BUSY;
}
// Fill transfer information
PTransfer->pBuffer = pBuffer;
pTransfer->numSamples = numSamples;
pTransfer->callback = callback;
pTransfer->pArg = pArg;
// Transmit or receive over codec channel
if (channel == AC97C_CODEC_TRANSFER) {
// Send command
data = *((unsigned int *) pTransfer->pBuffer);
(AT91C_BASE_AC97C->AC97C_COTHR_VIR) = data;
//size = ((AT91C_BASE_AC97C->AC97C_CAMR_VIR) & AT91C_AC97C_SIZE) >> 16;
//size = ((AT91C_BASE_AC97C->AC97C_CBMR_VIR) & AT91C_AC97C_SIZE) >> 16;
// Check if transfer is read or write
if ((data & AT91C_AC97C_READ) != 0) {
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_RXRDY;
}
else {
pTransfer->pBuffer += sizeof(unsigned int);
(AT91C_BASE_AC97C->AC97C_COMR_VIR) |= AT91C_AC97C_TXRDY;
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_IER_VIR) |= AT91C_AC97C_COEVT;
}
// Transmit over channel A
else if (channel == AC97C_CHANNEL_A_TRANSMIT) {
// Disable PDC
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_TXTDIS;
// Fill PDC buffers
//size = min(pTransfer->numSamples, MAX_PDC_COUNTER);
size = pTransfer->numSamples;
(AT91C_BASE_AC97C->AC97C_TPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_TCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
//size = min(pTransfer->numSamples - size, MAX_PDC_COUNTER);
size = pTransfer->numSamples - size;
if (size > 0) {
(AT91C_BASE_AC97C->AC97C_TNPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_TNCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_CAMR_VIR) |= AT91C_AC97C_PDCEN | AT91C_AC97C_ENDTX;
(AT91C_BASE_AC97C->AC97C_IER_VIR)|= AT91C_AC97C_CAEVT;
// Start transfer
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_TXTEN;
}
// Receive over channel A
else if (channel == AC97C_CHANNEL_A_RECEIVE) {
// Disable PDC
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_RXTDIS;
// Fill PDC buffers
//size = min(pTransfer->numSamples, MAX_PDC_COUNTER);
size = pTransfer->numSamples;
(AT91C_BASE_AC97C->AC97C_RPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_RCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
//size = min(pTransfer->numSamples - size, MAX_PDC_COUNTER);
size = pTransfer->numSamples - size;
if (size > 0) {
(AT91C_BASE_AC97C->AC97C_RNPR_VIR) = (unsigned int) pTransfer->pBuffer;
(AT91C_BASE_AC97C->AC97C_RNCR_VIR) = size;
pTransfer->pBuffer += size * GetSampleSize(AC97C_CHANNEL_A);
}
// Enable interrupts
(AT91C_BASE_AC97C->AC97C_CAMR_VIR) |= AT91C_AC97C_PDCEN | AT91C_AC97C_ENDRX;
(AT91C_BASE_AC97C->AC97C_IER_VIR) |= AT91C_AC97C_CAEVT;
// Start transfer
(AT91C_BASE_AC97C->AC97C_PTCR_VIR) = AT91C_PDC_RXTEN;
}
return 0;
}
作者: marcomo1986 发布时间: 2010-09-09
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28