首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

S3C2440端口操作函数(2)

S3C2440端口操作函数(2)

5. __raw_readl和__raw_writel
Linux对I/O的操作都定义在asm/io.h中,相应的在arm平台下,就在asm-arm/io.h中。
#define __raw_readl(a)  (__chk_io_ptr(a), *(volatile unsigned int__force   *)(a))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int__force   *)(a) = (v))
在include\linux\compiler.h中:
#ifdef __CHECKER__
……
extern void __chk_io_ptr(void __iomem *);
#else
……
# define __chk_io_ptr(x) (void)0
……
#endif
__raw_readl(a)展开是:((void)0, *(volatile unsigned int _force*)(a))。在定义了__CHECKER__的时候先调用__chk_io_ptr检查该地址,否则__chk_io_ptr什么也不做,*(volatileunsigned int _force*)(a)就是返回地址为a处的值。(void)xx的做法有时候是有用的,例如编译器打开了检查未使用的参数的时候需要将没有用到的参数这么弄一下才能编译通过。
CPU对I/O的物理地址的编程方式有两种:一种是I/O映射,一种是内存映射。__raw_readl和__raw_writel等是原始的操作I/O的方法,由此派生出来的操作方法有:inb、outb、_memcpy_fromio、readb、writeb、ioread8、iowrite8等。
6.local_irq_save和local_irq_restore
关中断和开中断,在asm-arm/system.h中定义。
#definelocal_irq_save(x)     \
({       \
__asm____volatile__(     \
"mrs %0, cpsr   @local_irq_save\n" \
"cpsidi"      \
: "=r" (x) : : "memory","cc");    \
})
#definelocal_irq_save(x)     \
({       \
   unsigned longtemp;    \
   (void) (&temp==&x);    \
__asm____volatile__(     \
"mrs %0, cpsr   @local_irq_save\n" \
" orr %1, %0,#128\n"     \
" msr cpsr_c,%1"     \
: "=r" (x), "=r"(temp)     \
:       \
: "memory","cc");     \
})
继承事业,薪火相传
返回列表