当前位置: 技术问答>linux和unix
请教嵌入式linux驱动2个问题。
来源: 互联网 发布时间:2016-02-08
本文导语: 1.驱动程序对自定义的全局变量怎么使用互斥进行访问? 2.嵌入式驱动中,如果寄存器的物理地址是0xffff0000,该怎么进行虚拟地址转换,然后又怎么读写相应的寄存器? 谢谢,最好有简单代码。 | ...
1.驱动程序对自定义的全局变量怎么使用互斥进行访问?
2.嵌入式驱动中,如果寄存器的物理地址是0xffff0000,该怎么进行虚拟地址转换,然后又怎么读写相应的寄存器?
谢谢,最好有简单代码。
2.嵌入式驱动中,如果寄存器的物理地址是0xffff0000,该怎么进行虚拟地址转换,然后又怎么读写相应的寄存器?
谢谢,最好有简单代码。
|
1.
Linux下互斥有很多种方法
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);
还有Completions,自旋锁,等等等等,具体参考LDD3第5章
2.
Linux下驱动我接触过一些修改寄存器的操作,都是通过系统定义的结构体进行修改,没有直接通过寄存器地址修改过。。
比如,修改cpm2的寄存器,地址为CPM_MAP_ADDR
volatile iop_cpm2_t *io;
volatile cpm2_map_t* immap = (cpm2_map_t*)CPM_MAP_ADDR;
io = (iop_cpm2_t *)&(immap->im_ioport);
io->iop_pdird &= ~I2C_SDA; /* input */
以上操作就实现了对CPM_MAP_ADDR寄存器的dird这个引脚的修改。
Linux下互斥有很多种方法
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);
还有Completions,自旋锁,等等等等,具体参考LDD3第5章
2.
Linux下驱动我接触过一些修改寄存器的操作,都是通过系统定义的结构体进行修改,没有直接通过寄存器地址修改过。。
比如,修改cpm2的寄存器,地址为CPM_MAP_ADDR
volatile iop_cpm2_t *io;
volatile cpm2_map_t* immap = (cpm2_map_t*)CPM_MAP_ADDR;
io = (iop_cpm2_t *)&(immap->im_ioport);
io->iop_pdird &= ~I2C_SDA; /* input */
以上操作就实现了对CPM_MAP_ADDR寄存器的dird这个引脚的修改。
|
如果用 ioremap 转换,行吗?
-----------------------------------
这个可以,我最近就在自己的学习板上成功的用这个函数操作了硬件寄存器
-----------------------------------
这个可以,我最近就在自己的学习板上成功的用这个函数操作了硬件寄存器
|
关于寄存器物理地址与虚拟地址的转换,在ARM上的函数是:
io_p2v
io_v2p
io_p2v
io_v2p
|
2.嵌入式驱动中,如果寄存器的物理地址是0xffff0000,该怎么进行虚拟地址转换,然后又怎么读写相应的寄存器?
谢谢,最好有简单代码。
---------------------------------
比如我要写aaa积存器,aaa的地址是0xffff0000,大小是4个字节,那么就这样
#include
volatile unsigned long *temp;
temp=(unsigned long *)ioremap(0xffff0000,4);
然后就可以对这个积存器写和读了
写操作
*temp=.....
读操作
...=*temp;
有些硬件可能有点差别的要用readb writeb之类的宏来读写
读写完之后就
iounmap((void *)temp);
谢谢,最好有简单代码。
---------------------------------
比如我要写aaa积存器,aaa的地址是0xffff0000,大小是4个字节,那么就这样
#include
volatile unsigned long *temp;
temp=(unsigned long *)ioremap(0xffff0000,4);
然后就可以对这个积存器写和读了
写操作
*temp=.....
读操作
...=*temp;
有些硬件可能有点差别的要用readb writeb之类的宏来读写
读写完之后就
iounmap((void *)temp);
|
ioremap和read[b|w|l],write[b|w|l]一起用,不然可移植性上不够
|
设备手册上有函数, 不一定用ioremap.