内核中与驱动相关的内存操作之十一(IO内存)

2019-07-13 05:56发布

    设备通常会提供一组寄存器用于控制设备、读定设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器.这些寄存器可能位于I/O空间,也可能位于内存空间.当位于I/O空间时,通常被称为I/O端口,位于内存空间时,对应的内存空间被称为I/O内存.在嵌入式LINUX,我们接触最多的就是I/O内存: #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)      向内核申请n个内存地址,这些地址从first开始,name参数为设备的名称.如果分配成功返回值为非NULL,如果返回NULL,则意味着申请I/O内存失败.
  其相反的动作函数为:
int release_resource(struct resource *old)    这对函数一般用来判断I/O内存是否已经被占用了.它一般配合platform_get_resource()函数来使用.platform_get_resource()用来获取平台设备端的I/O内存地址空间,并以其返回值为参数.如下: struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num)      以S3C2440的RTC为例,简单说明: 1. static int __devinit s3c_rtc_probe(struct platform_device *pdev) 2. { 3. ... ...; 4. res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5. if (res == NULL) { 6. dev_err(&pdev->dev, "failed to get memory region resource "); 7. return -ENOENT; 8. } 9. 10. s3c_rtc_mem = request_mem_region(res->start,res->end-res->start+1,pdev->name); 11. ... ...; 12. }     [注:]I/O内存一般只用来判断我们目标操作内存是否被占用,但是这并不是必须的.          在对I/O内存的存取内核提供了专门的API: 1. unsigned readb(address); 2. unsigned readw(address); 3. unsigned readl(address); 4. 5. void writeb(unsigned value, address); 6. void writew(unsigned value, address); 7. void writel(unsigned value, address);        例如S3C2440LCD驱动里面,LCD主控端寄存器的配置: 1. static int __init s3c24xxfb_probe(struct platform_device *pdev,enum s3c_drv_type drv_type) 2. { 3. ... ...; 4. lcdcon1 = readl(info->io + S3C2410_LCDCON1); 5. writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); 6. ... ...; 7. }