Drive learning-daily notes day8

[1] Review
1. Interrupt
request_irq (irqno, interrupt processing function, interrupt trigger mode, name, passed parameters);
free_irq (irqno, passed parameters);

2.内核定时
	struct timer_list mytimer;
	mytimer.expires = jiffies + HZ; (1s)  //# define HZ CONFIG_HZ	
	mytimer.function = timer_function;  //当定时时间到了会执行
	mytimer.data = 0; //一般用于传递下一次的定时的时间
	init_timer(&mytimer);
	add_timer(&mytimer); //启动定时器,并只会执行一次
	mod_timer(&mytimer,下一次定时的时间);再次启动定时器
	del_timer(&mytimer);

3.gpio子系统
	gpio_request(gpio,NULL);
	gpio_direction_input(gpio);
	gpio_driection_output(gpio,value);
	gpio_set_value(gpio,value);
	gpio_get_value(gpio);
	gpio_free(gpio);
	
4.中断底半部
	软中断,tasklet ,工作队列
	
	tasklet:
		struct tasklet_struct tasklet;
		tasklet_init(&tasklet,tasklet底半部处理函数,传递的参数);
		tasklet_schedule(struct tasklet_struct *tasklet)
		
	工作队列:	
		struct work_struct work;
		INIT_WORK(&work, 工作队列的底半部处理函数);
		schedule_work(&work); 
			
作业:	
	1.编写ADC的驱动(使用中断)

[2] How to obtain the soft interrupt number of the controller
find -name irqs.h

	./arch/arm/mach-s5p6818/include/mach/irqs.h
	#include "s5p6818_irq.h"        

	find -name s5p6818_irq.h
	./arch/arm/mach-s5p6818/include/mach/s5p6818_irq.h

	#define IRQ_PHY_ADC   (41 + 32)  //ADC的软中断号

[3] Platform bus driver
platform: It separates the device information from the device driver to realize the general purpose of this device driver.
The device information and device driver complete the matching process through the platform bus. By
matching the device information with the name in the device driver, when the match is successful, the device information terminal will carry the information
to the device driver, and execute the probe function in the device driver, and operate the hardware in the probe function
. Execute the remove function in the driver when the device information is separated from the device driver.

----------------------------------------------------   
				|                |
设备信息端      | platform总线端 |设备驱动端
驱动工程师实现的|内核工程师实现的|驱动工程师实现的
				|                |
----------------------------------------------------

设备信息端 : 
	
	1.分配对象
	struct platform_device {
		const char	* name;
		int		id;
		struct device	dev;
		u32		num_resources;
		struct resource	* resource;
	};
	struct platform_device  pdev;
	2.对象的初始化
		pdev.name  名字,用户匹配
		pdev.id    -1,platform是内核制作出来的,没有真实的硬件存在,填写-1(序号)
		pdev.num_resources 资源的个数
		pdev.resource  描述的资源
		
		struct resource {     //设备信息结构体                                                                              
			resource_size_t start; //起始的资源,需要填写
			resource_size_t end;   //结束的资源,需要填写
			const char *name;      //名字
			unsigned long flags;   //资源的类型,需要填写
			struct resource *parent, *sibling, *child; //内核链表
		};

		#define IORESOURCE_IO	0x00000100  IO口资源
		#define IORESOURCE_MEM	0x00000200  内存资源
		#define IORESOURCE_IRQ	0x00000400  中断资源
		#define IORESOURCE_DMA	0x00000800  DMA资源
		
		pdev.dev.release =  释放资源的函数、如果不写卸载驱动的时候会崩溃
		void	(*release)(struct device *dev);
		
	3.对象的注册
		int platform_device_register(struct platform_device *pdev);
	4.对象注销
		void platform_device_unregister(struct platform_device *pdev)
		
		
		
设备驱动端 :
	1.分配对象
	struct platform_driver {
		int (*probe)(struct platform_device *);
		int (*remove)(struct platform_device *);
		struct device_driver driver;
		const struct platform_device_id *id_table;
	};
	struct platform_driver pdrv;
	
	2.对象的初始化
		pdrv.probe=pdrv_probe //匹配成功执行的函数
		pdrv.remove = pdrv_remove //分离的时候执行的函数
		pdrv.driver.name          //1.用于匹配的名字
		pdrv.id_table             //2.用于匹配的
		//pdrv.driver.of_match_table//3.设备树匹配
		
		
	3.对象的注册
		platform_driver_register(&pdrv);
		
	4.对象注销	
		platform_driver_unregister(&pdrv);

[4] Function
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
to obtain device information on the driver side . Function: get device information on the driver side.
Parameters:
@dev: pointer to the device side object @type
: Resource type
@num: the number of resources of the same kind, each resource starts from 0.
Return value: Return the structure pointer of struct resource * on success,
NULL on failure

int platform_get_irq(struct platform_device *dev, unsigned int num)
Function: Get interrupt resources.
Parameters:
@dev: The pointer of the device side object
@num: The number of interrupt resources, each resource starts from 0.
Return value: the interrupt number is returned on success, the error code is returned on failure

[5] The matching method of id_table
struct platform_device_id { char name[PLATFORM_NAME_SIZE]; //Name used for matching kernel_ulong_t driver_data //Data passed, if you don’t care about 0 };


struct platform_device_id pdrv_idtable[] = {
	{"hello_adc",},
	{"hello_adc0",},	
	{"hello_adc1",},
	{"hello_adc2",},
	{/*结束*/},  //如果不写这个空的花括号,内核在比较名字的时候
};               //有可以会一直循环着比较,如果碰巧匹配上了有可能导致内核崩溃

如果驱动中既有idtable又有名字,匹配的优先级是先匹配idtale如果idtable
没有匹配上然后去匹配名字。

【6】module_platform_driver功能
#define module_platform_driver(pdrv)
module_driver(pdrv, platform_driver_register,platform_driver_unregister)

#define module_driver(__driver, __register, __unregister, …)

static int __init pdrv_init(void)
{
return platform_driver_register(&pdrv);
}
module_init(pdrv_init);
static void __exit pdrv_exit(void)
{
platform_driver_unregister(&pdrv);
}
module_exit(pdrv_exit);

[7] Review of i2c hardware knowledge
1. Several lines
scl: clock line
sda: data line
2. Several kinds of signals
Start signal:
when scl is high, sda jumps from high to low
Stop signal:
at When scl is high, sda changes from low to high.
Response signal:
sda is low
3. Two timings
Write timing:
start +7bit slave address (0 write) +ack+reg(8bit)+ ack+data+ack+stop

	读时序:
		start +7bit从机地址(0写)+ack+reg(8bit)+ack+
		start +7bit从机地址(1读)+ack+从机给主机反馈data+NO ack+stop

4.i2c传输速率
	100K   400K   3.4M

Guess you like

Origin blog.csdn.net/weixin_48430195/article/details/108671837