[1] Review the
platform bus
设备端
设备信息结构体:
struct resource res[] = {
[0] = {
.start = 0xc0053000,
.end = 0xc0053000 + 24 -1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 73,
.end = 73,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device pdev = {
.name = "hello",
.id = -1,
.dev = {
.release = pdev_release,
},
.number_resource = 2,
.resource = res,
};
platform_device_register(&pdev);
platform_device_unregister(&pdev);
驱动端
struct platform_driver pdrv = {
.probe = pdrv_probe,
.remove = pdrv_remove,
.driver = {
.name = "hello",
},
.id_table = pdrv_idtable,
};
platform_driver_register(&pdrv);
platform_driver_unregister(&pdrv);
[2] i2c driver framework
user:
open read write close
Kernel
device driver layer: when the bus driver and the device driver match successfully, the probe function is executed here.
1. Register the character device driver and provide access to the application layer
. 2. Encapsulate data and send data (i2c_read_reg, i2c_write_reg)
3. Complete the hardware ( mma8451q) Initialization
---------------------------------------------- ---------------
core layer (i2c-core.c): it is implemented by the engineer linux kernel, providing bus driver
actuator and the device driver registration and deregistration manner, and a matching the process of.
-------------------------------------------------- -----------
Bus driver layer (controller driver layer): In the linux kernel, the manufacturer has already
programmed the controller driver drivers/i2c/busses| to initialize the controller and send data And receive.
i2c-s3c241.c |
------------------|------------------------- ----------------------
hardware: i2c controller mma8451q
------------ scl --------- ---
| |-------------------| x |
| | | sda | y |
| |--------------- ----| z |
| | | |
------------ ------------
// s3c2410 s3c6410 s5pv210 exynos4412 s5p6818
[3] Implementation of i2c device driver
1. Assigned object
struct i2c_driver { int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); struct device_driver driver; const struct i2c_device_id *id_table; };
struct i2c_driver mma8451q;
2.初始化对象
mma8451q.probe = mma8451q_probe //匹配成功后执行的函数
mma8451q.remove = mma8451q_remove//分离执行的函数
mma8451q.driver.name = "名字" //这个名字不能用于匹配,但是还必须初始化。
// /sys/bus/i2c/drivers/2-001c
mma8451q.id_table = mma8451q_idtable //用于匹配
3.注册
i2c_add_driver(&mma8451q);
4.注销
i2c_del_driver(&mma8451q);
一键注册、注销
module_i2c_driver(mma8451q);
[4] Submission of i2c controller driver name
struct i2c_board_info { char type[I2C_NAME_SIZE]; //Submitted name unsigned short addr; //Slave address };
int i2c_register_board_info(int busnum,
struct i2c_board_info const *info, unsigned len)
功能:向控制器提交名字
参数:
@busnum :总线号(它和控制器的序号一一对应) 2
@info :被提交的信息
@len :提交的i2c_board_info的个数
返回值:成功返回0,失败返回错误码
通用存放设备信息的文件:
arch/arm/plat-s5p6818/fs6818$ vi device.c
716 /*-----------------------------------------
717 * G-Sensor platform device
718 */
719 #include <linux/i2c.h>
720
721 static struct i2c_board_info mma8451q = {
722 .type = "mma8451q",
723 .addr = 0x1c,
724 };
1905 #elif defined(CONFIG_SENSORS_MMA8451) || defined(CONFIG_MXC_MMA8451_MODULE)
1906 printk("plat: add g-sensor mma8451\n");
-1907 // i2c_register_board_info(2, &mma8451_i2c_bdi, 1);
1908 #endif
+1909 i2c_register_board_info(2, &mma8451q, 1);
make uImage 编译内核
cp arch/arm/boot/uImage ~/tftpboot/ 拷贝
重启开发板
[5] The process of packaging and sending i2c data
//https://www.cnblogs.com/aspirs/p/12371237.html
//7-bit 10-bit slave address access problem
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address /
#define I2C_M_RD 0x0001 / read data, from slave to master */
struct i2c_msg {
__u16 addr; //从机地址
__u16 flags; //读写的标志位 0写 I2C_M_RD读
__u16 len; //本次你要写的数据的长度
__u8 *buf; //消息的首地址
};
*/有多少个起始位就有多少个消息,消息的长度是以字节来表示的 /*
写的消息的封装:
char w_buf[] = {reg,data};
struct i2c_msg w_msg = {
.addr = client->addr,
.flags = 0,
.len = 2,
.buf = w_buf,
};
读的消息的封装:
char data;
char r_buf []= {reg};
struct i2c_msg r_msg[] = {
[0] = {
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = r_buf,
},
[1] = {
.addr = client->addr,
.flags = I2C_M_RD,
.len = 1,
.buf = &data,
},
};
消息发送:
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
功能:消息的发送函数
参数:
@adap :总线驱动的对象 client->adapter
@msgs :消息结构体指针
@num :消息的个数
返回值:成功返回发送了的消息的格式,
否者不是发送的消息的个数。
[6] i2c_client structure
When the device driver i2c_driver and the bus driver i2c_adapter match successfully,
an i2c_client structure will be created in the kernel. This structure is
used to save the information after the match is successful.
struct i2c_client { unsigned short addr; //Slave address char name[I2C_NAME_SIZE];//Name struct i2c_adapter *adapter;//The object of the successfully matched bus driver struct i2c_driver *driver; //The object of the successfully matched driver };
[1] Block device For
example, a mobile hard disk:
head: how many disk
surfaces are there, track: how many rings are in a surface,
sector: how many sectors are in a ring, a sector is 512 bytes
磁盘的数据的读取:
磁盘数据的读取不会按照存储顺序来读取,因为磁头它是机械结构,
通过旋转来访问数据,如果按照数据来访问,需要反复的切换这个
物理结构,比较浪费时间。所以磁盘在访问的时候采用电梯优化的算法
来完成。即一次将一个盘面上的数据全部读取到,然后切换物理结构,
在读取下面的数据。将所有的数据读取完之后,进行数据的排序,排序
之后进行操作。