[1] Revise el
bus de la plataforma
设备端
设备信息结构体:
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] Usuario del marco del controlador i2c
:
abrir leer escribir cerrar
Capa del controlador del dispositivo del núcleo : cuando el controlador del bus y el controlador del dispositivo coinciden correctamente, la función de sonda se ejecuta aquí.
1. Registre el controlador del dispositivo de caracteres y proporcione acceso a la capa de la aplicación
. 2. Encapsule los datos y envíe los datos (i2c_read_reg, i2c_write_reg)
3. Complete el hardware ( mma8451q) Inicialización
---------------------------------------------- ---------------
capa de núcleo (i2c-core.c): es implementado por el ingeniero kernel de linux, proporcionando el
actuador del controlador de bus y el registro y desregistro del controlador del dispositivo, y una coincidencia el proceso de.
-------------------------------------------------- -----------
Capa de controlador de bus (capa de controlador de controlador): En el kernel de Linux, el fabricante ya ha
programado los controladores de controlador de controlador / i2c / busses | para inicializar el controlador y enviar datos Y recibir.
i2c-s3c241.c |
------------------ | ------------------------- ----------------------
hardware: controlador i2c mma8451q
------------ scl --------- ---
| | ------------------- | x |
| | | sda | y |
| | --------------- ---- | z |
| | | |
------------ ------------
// s3c2410 s3c6410 s5pv210 exynos4412 s5p6818
[3] Implementación del controlador de dispositivo i2c
1. Objeto asignado
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] Envío del nombre del controlador del controlador
i2c struct i2c_board_info { char type [I2C_NAME_SIZE]; // Nombre enviado 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] El proceso de empaquetado y envío de datos
i2c //https://www.cnblogs.com/aspirs/p/12371237.html
// Problema de acceso a la dirección esclava de 10 bits de 7 bits
#define I2C_M_TEN 0x0010 / * esto es una dirección de chip de diez bits /
#define I2C_M_RD 0x0001 / leer datos, de esclavo a maestro * /
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] Estructura i2c_client
Cuando el controlador de dispositivo i2c_driver y el controlador de bus i2c_adapter coinciden con éxito, se
creará una estructura i2c_client en el kernel, que se
utiliza para guardar la información después de que la coincidencia sea exitosa.
struct i2c_client { unsigned short addr; // Slave address char name [I2C_NAME_SIZE]; // Name struct i2c_adapter * adapter; // El objeto del controlador de bus que coincide con éxito struct i2c_driver * driver; // El objeto del controlador que coincide con éxito };
[1] Dispositivo de bloque Por
ejemplo, un disco duro móvil:
cabezal: cuántas
superficies de disco hay, pista: cuántos anillos hay en una superficie,
sector: cuántos sectores hay en un anillo, un sector tiene 512 bytes
磁盘的数据的读取:
磁盘数据的读取不会按照存储顺序来读取,因为磁头它是机械结构,
通过旋转来访问数据,如果按照数据来访问,需要反复的切换这个
物理结构,比较浪费时间。所以磁盘在访问的时候采用电梯优化的算法
来完成。即一次将一个盘面上的数据全部读取到,然后切换物理结构,
在读取下面的数据。将所有的数据读取完之后,进行数据的排序,排序
之后进行操作。