07-platform_probe

1、platform_driver 函数中probe函数

struct platform_driver {
	int (*probe)(struct platform_device *);
	int (*remove)(struct platform_device *);
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*resume)(struct platform_device *);
	struct device_driver driver;
	const struct platform_device_id *id_table;
};

probe函数中的唯一的形参”struct platform_device *“,该形参直接对应device.c中的”platform_device“结构体。

以05、06的例子为例
06中的probe函数中的如下函数,platform_device直接指向05中的”led_device“结构体。

int led_driver_probe(struct platform_device *platform_device)

2、platform_device 成员访问

匹配成功后可以直接访问目标结构体中给的成员变量。也可以使用函数进行访问。常用函数进行结构体访问。

struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num)

platform_device:probe函数中的形参
unsigned int type:device中的flag
unsigned int num:同类资源的第几个

3、和前面驱动开发的区别

1)相比于前期的字符设备驱动,在platform架构下主要在probe函数中实现字符设备驱动的设备申请和注册,生成设备节点等操作。
2)平台总线模型将设备代码和驱动代码分离, 将和硬件设备相关的都放到 device.c 文件里面,驱动部分代码都放到 driver.c 文件里面。

4、开发过程的感觉

相比于前期开发,如果外设比较少的情况下,我自己感觉platform架构的开发还是挺麻烦的,不过device.c如果在后面用设备树取代的话,开发起来将会十分方便。

5、demo

1)driver,c
主要关注probe中的字符设备的申请。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/io.h>

struct resource *PH_Config_Reg,*PH_Mul_Reg,*PH_Data_Reg;
void __iomem *gpio_base = NULL;
ssize_t miscread (struct file *file, char __user *buf, size_t size, loff_t *loff)
{
	char *kbuf="welcome to kernel";
	copy_to_user(buf,kbuf,strlen(kbuf));
	printk("enter miscread success \n");	
	return 0;

}
ssize_t miscwrite (struct file *file, const char __user *buf, size_t size, loff_t *loff)
{
	char kbuf[32]={0};
	copy_from_user(kbuf,buf,size);
	if(kbuf[0]==1)
	{
		writel((readl(gpio_base) &~(0x1<<26)),gpio_base); 
	}
	if(kbuf[0]==0)
	{
		writel((readl(gpio_base) |(0x1<<26)),gpio_base); 
	}

	printk("enter miscwrite success \n");	
	printk("%s \n",kbuf);	
	return 0;
}
int miscrelease (struct inode *inode, struct file *file)
{
	printk("enter miscrelease success \n");	
	return 0;

}
int miscopen (struct inode *inode, struct file *file)
{
	printk("enter miscopen success \n");	
	return 0;
}

const struct file_operations mymisc_fops={
	.owner = THIS_MODULE,
	.open = miscopen,
	.read = miscread,
	.write = miscwrite,
	.release = miscrelease
};
struct miscdevice  mymisc={
	.minor = MISC_DYNAMIC_MINOR,
	.name = "mymisc",
	.fops = &mymisc_fops
};


int led_driver_probe(struct platform_device *platform_device)
{
	printk("led_driver_probe run success\n");
	PH_Config_Reg = platform_get_resource(platform_device,IORESOURCE_MEM, 0);
	if(PH_Config_Reg ==NULL){
			printk("led_driver_probe run success\n");
			return -EBUSY;
	}
	printk("platform_get_resource OK\n");
	printk("led_start is %x\n",PH_Config_Reg->start);
	printk("led_end is %x\n",PH_Config_Reg->end);


	int ret;
	ret = misc_register(&mymisc);
	if(ret<0){
		printk("mymisc_register failed \n");
		return -1;
	}
	printk("mymisc_register success \n");	
	printk("hello world! \n");

	gpio_base = ioremap(PH_Config_Reg->start,4);
	if(IS_ERR_OR_NULL(gpio_base)){
		printk("IO PH_Config_Reg remap failed!!\n");
		return -1;
	}
	writel((readl(gpio_base) &~(0x7<<8))|(0x1<<8),gpio_base);

	PH_Mul_Reg = platform_get_resource(platform_device,IORESOURCE_MEM, 1);

	if(PH_Mul_Reg ==NULL){
			printk("led_driver_probe run failed\n");
			return -EBUSY;
	}
	gpio_base = ioremap(PH_Mul_Reg->start,4);
	if(IS_ERR_OR_NULL(gpio_base)){
		printk("IO PH_Mul_Reg remap failed!!\n");
		return -1;
	}
	writel((readl(gpio_base) &~(0x3<<20)),gpio_base);

	PH_Data_Reg = platform_get_resource(platform_device,IORESOURCE_MEM, 2);

	if(PH_Data_Reg ==NULL){
		printk("led_driver_probe run failed\n");
		return -EBUSY;
	}
	gpio_base = ioremap(PH_Data_Reg->start,4);
	if(IS_ERR_OR_NULL(gpio_base)){
		printk("IO PH_Data_Reg remap failed!!\n");
		return -1;
	}
	return 0;
}

int led_driver_remove(struct platform_device *platform_device)
{
	printk("led_driver_remove run success\n");
	return 0;

}


struct platform_driver led_driver = {
	.probe = led_driver_probe,
	.remove = led_driver_remove,
	.driver = {
		.name = "my_led_device",
		.owner = THIS_MODULE 
	}
	//const struct platform_device_id *id_table;
};


static int led_driver_init(void)
{
	int ret =0;
	ret = platform_driver_register(& led_driver);
	if(ret<0)
	{
		printk("platform_driver_register failed\n");
		return -1;
	}

	printk("platform_driver_register ok\n");
	
	printk("led driver init enter success\n");
	return 0;
}

static void led_driver_exit(void)
{
	platform_driver_unregister(& led_driver);
	printk("led_driver_exit\n");
}


module_init(led_driver_init);
module_exit(led_driver_exit);
MODULE_LICENSE("GPL");

2)app参考前面的file_operations中的代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值