当前位置: 首页 > news >正文

公司网站制作注意事项seo推广软件排行榜前十名

公司网站制作注意事项,seo推广软件排行榜前十名,开淘宝店铺的详细步骤,网页开发工具Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图如下#xff1a; 二、I.MX6U SPI主机驱动分析 主机驱动一般都是由SOC厂商写好的。不作为重点需要掌握的内容。 三、SPI设备驱动编写流程 1、SP…Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长  本章的思维导图如下 二、I.MX6U SPI主机驱动分析 主机驱动一般都是由SOC厂商写好的。不作为重点需要掌握的内容。 三、SPI设备驱动编写流程 1、SPI设备信息描述 1、IO 的 pinctrl 子节点创建与修改 根据所使用的 IO 来创建或修改 pinctrl 子节点检查是否被占用。 2、SPI 设备节点的创建与修改 308 ecspi1 { 309 fsl,spi-num-chipselects 1;/*设置“ fsl,spi-num-chipselects”属性为 1表示只有一个设备。*/ 310 cs-gpios gpio4 9 0;/*设置“ cs-gpios”属性也就是片选信号为 GPIO4_IO09。*/ 311 pinctrl-names default;*设置“ pinctrl-names”属性也就是 SPI 设备所使用的 IO 名字。*/ 312 pinctrl-0 pinctrl_ecspi1;/*设置“ pinctrl-0”属性也就是所使用的 IO 对应的 pinctrl 节点。*/ 313 status okay;/*将 ecspi1 节点的“ status”属性改为“ okay”。*/ 314 315 flash: m25p800 {/*ecspi1 下的 m25p80 设备信息每一个 SPI 设备都采用一个子节点来描述 其设备信息。第 315 行的“ m25p800”后面的“ 0”表示 m25p80 的接到了 ECSPI 的通道 0 上。这个要根据自己的具体硬件来设置。*/ 316 #address-cells 1; 317 #size-cells 1; 318 compatible st,m25p32;/*SPI 设备的 compatible 属性值用于匹配设备驱动。*/ 319 spi-max-frequency 20000000;/*“ spi-max-frequency”属性设置 SPI 控制器的最高频率这个要根据所使用的 SPI 设备来设置比如在这里将 SPI 控制器最高频率设置为 20MHz。*/ 320 reg 0;/* reg 属性设置 m25p80 这个设备所使用的 ECSPI 通道*/ 321 }; 322 }; 上述代码是 I.MX6Q 的一款板子上的一个 SPI 设备节点在这个板子的 ECSPI 接口上接了一个 m25p80这是一个 SPI 接口的设备。 2、SPI设备数据收发处理流程 spi_transfer 结构体此结构体用于描述 SPI 传输信息结构体内容如下 603 struct spi_transfer { 604 /* its ok if tx_buf rx_buf (right?) 605 * for MicroWire, one buffer must be null 606 * buffers must work with dma_*map_single() calls, unless 607 * spi_message.is_dma_mapped reports a pre-existing mapping 608 */ 609 const void *tx_buf;/*tx_buf 保存着要发送的数据。*/ 610 void *rx_buf;/*rx_buf 用于保存接收到的数据。*/ 611 unsigned len;/*len 是要进行传输的数据长度 SPI 是全双工通信因此在一次通信中发送和 接收的字节数都是一样的所以 spi_transfer 中也就没有发送长度和接收长度之分。*/ 612 613 dma_addr_t tx_dma; 614 dma_addr_t rx_dma; 615 struct sg_table tx_sg; 616 struct sg_table rx_sg; 617 618 unsigned cs_change:1; 619 unsigned tx_nbits:3; 620 unsigned rx_nbits:3; 621 #define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */ 622 #define SPI_NBITS_DUAL 0x02 /* 2bits transfer */ 623 #define SPI_NBITS_QUAD 0x04 /* 4bits transfer */ 624 u8 bits_per_word; 625 u16 delay_usecs; 626 u32 speed_hz; 627 628 struct list_head transfer_list; 629 }; spi_message 也是一个结构体: 660 struct spi_message { 661 struct list_head transfers; 662 663 struct spi_device *spi; 664 665 unsigned is_dma_mapped:1; ...... 678 /* completion is reported through a callback */ 679 void (*complete)(void *context); 680 void *context; 681 unsigned frame_length; 682 unsigned actual_length; 683 int status; 684 685 /* for optional use by whatever driver currently owns the 686 * spi_message ... between calls to spi_async and then later 687 * complete(), thats the spi_master controller driver. 688 */ 689 struct list_head queue; 690 void *state; 691 }; spi_message初始化函数为 spi_message_init函数原型如下 void spi_message_init(struct spi_message *m) spi_message 初始化完成以后需要将 spi_transfer 添加到 spi_message 队列中这里要用 到 spi_message_add_tail 函数此函数原型如下 void spi_message_add_tail(struct spi_transfer *t, struct spi_message *m) t 要添加到队列中的 spi_transfer。m spi_transfer 要加入的 spi_message。 spi_message 准备好以后既可以进行数据传输了数据传输分为同步传输和异步传输同步 传输会阻塞的等待 SPI 数据传输完成同步传输函数为 spi_sync函数原型如下 int spi_sync(struct spi_device *spi, struct spi_message *message) spi 要进行数据传输的 spi_device。message要传输的 spi_message。 返回值 无。 异步传输不会阻塞的等到 SPI 数据传输完成异步传输需要设置 spi_message 中的 complete成员变量 complete 是一个回调函数当 SPI 异步传输完成以后此函数就会被调用。 SPI 异步传输函数为 spi_async函数原型如下 int spi_async(struct spi_device *spi, struct spi_message *message) spi 要进行数据传输的 spi_device。message要传输的 spi_message。 返回值 无。         本次测试采用同步传输方式来完成 SPI 数据的传输工作也就是 spi_sync 函数。 SPI 数据传输步骤如下 ①、申请并初始化 spi_transfer设置 spi_transfer 的 tx_buf 成员变量 tx_buf 为要发送的数 据。然后设置 rx_buf 成员变量 rx_buf 保存着接收到的数据。最后设置 len 成员变量也就是 要进行数据通信的长度。 ②、使用 spi_message_init 函数初始化 spi_message。 ③、使用 spi_message_add_tail函数将前面设置好的 spi_transfer添加到 spi_message队列中。 ④、使用 spi_sync 函数完成 SPI 数据同步传输。   四、硬件原理图分析 五、实验程序编写 1、修改设备树 1、添加 ICM20608 所使用的 IO 1 pinctrl_ecspi3: icm20608 { 2 fsl,pins 3 MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0 /* CS */ 4 MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x10b1 /* SCLK */ 5 MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x10b1 /* MISO */ 6 MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x10b1 /* MOSI */ 7 ; 8 }; 2、在 ecspi3 节点追加 icm20608 子节点   1 ecspi3 { 2 fsl,spi-num-chipselects 1;/*当前片选数量为 1*/ 3 cs-gpio gpio1 20 GPIO_ACTIVE_LOW; /* cantt use cs-gpios! *//*用了一个自己定义的“ cs-gpio”属 性*/ 4 pinctrl-names default; 5 pinctrl-0 pinctrl_ecspi3;/*设置 IO 要使用的 pinctrl 子节点*/ 6 status okay;/* imx6ull.dtsi 文件中默认将 ecspi3 节点状态(status)设置为“ disable”这里我们要将 其改为“ okay”。*/ 7 8 spidev: icm206080 {/*icm20608 设备子节点因为 icm20608 连接在 ECSPI3 的第 0 个通道上因此 后面为 0。第 9 行设置节点属性兼容值为“ alientek,icm20608”第 10 行设置 SPI 最大时钟频 率为 8MHz这是 ICM20608 的 SPI 接口所能支持的最大的时钟频率。第 11 行 icm20608 连接 在通道 0 上因此 reg 为 0。*/ 9 compatible alientek,icm20608; 10 spi-max-frequency 8000000; 11 reg 0; 12 }; 13 }; 2、编写ICM20608驱动 1、icm20608 设备结构体创建 需要注意在 probe 函数中设置 private_data 为 probe 函数传递进来的 spi_device 参数。 void *private_data; /* 私有数据 */ 2、icm20608 的 spi_driver 注册与注销 1 /* 传统匹配方式 ID 列表 */ 2 static const struct spi_device_id icm20608_id[] {/*第 2~5 行传统的设备和驱动匹配表。*/ 3 {alientek,icm20608, 0}, 4 {} 5 }; 6 7 /* 设备树匹配列表 */ 8 static const struct of_device_id icm20608_of_match[] {/*第 8~11 行设备树的设备与驱动匹配表这里只有一个匹配项“ alientek,icm20608”。*/ 9 { .compatible alientek,icm20608 }, 10 { /* Sentinel */ } 11 }; 12 13 /* SPI 驱动结构体 */ 14 static struct spi_driver icm20608_driver {/*第 14~23 行 icm20608 的 spi_driver 结构体变量当 icm20608 设备和此驱动匹配成功以后 第 15 行的 icm20608_probe 函数就会执行。同样的当注销此驱动的时候 icm20608_remove 函 数会执行。*/ 15 .probe icm20608_probe, 16 .remove icm20608_remove, 17 .driver { 18 .owner THIS_MODULE, 19 .name icm20608, 20 .of_match_table icm20608_of_match, 21 }, 22 .id_table icm20608_id, 23 }; 24 25 /* 26 * description : 驱动入口函数 27 * param : 无 28 * return : 无 29 */ 30 static int __init icm20608_init(void)/*第 30~33 行 icm20608_init 函数为 icm20608 的驱动入口函数在此函数中使用 spi_register_driver 向 Linux 系统注册上面定义的 icm20608_driver。*/ 31 { 32 return spi_register_driver(icm20608_driver); 33 } 34 35 /* 36 * description : 驱动出口函数 37 * param : 无 38 * return : 无 39 */ 40 static void __exit icm20608_exit(void)/*第 40~43 行 icm20608_exit 函数为 icm20608 的驱动出口函数在此函数中使用 spi_unregister_driver 注销掉前面注册的 icm20608_driver。*/ 41 { 42 spi_unregister_driver(icm20608_driver); 43 } 44 45 module_init(icm20608_init); 46 module_exit(icm20608_exit); 47 MODULE_LICENSE(GPL); 48 MODULE_AUTHOR(zuozhongkai); 3、proberemove 函数 8 static int icm20608_probe(struct spi_device *spi) 9 { 10 int ret 0; 11 12 /* 1、构建设备号 */ 13 if (icm20608dev.major) { 14 icm20608dev.devid MKDEV(icm20608dev.major, 0); 15 register_chrdev_region(icm20608dev.devid, ICM20608_CNT, ICM20608_NAME); 16 } else { 17 alloc_chrdev_region(icm20608dev.devid, 0, ICM20608_CNT, ICM20608_NAME); 18 icm20608dev.major MAJOR(icm20608dev.devid); 19 } 20 21 /* 2、注册设备 */ 22 cdev_init(icm20608dev.cdev, icm20608_ops); 23 cdev_add(icm20608dev.cdev, icm20608dev.devid, ICM20608_CNT); 24 25 /* 3、创建类 */ 26 icm20608dev.class class_create(THIS_MODULE, ICM20608_NAME); 27 if (IS_ERR(icm20608dev.class)) { 28 return PTR_ERR(icm20608dev.class); 29 } 30 31 /* 4、创建设备 */ 32 icm20608dev.device device_create(icm20608dev.class, NULL, icm20608dev.devid, NULL, ICM20608_NAME); 33 if (IS_ERR(icm20608dev.device)) { 34 return PTR_ERR(icm20608dev.device); 35 } 36 37 /* 获取设备树中 cs 片选信号 */ 38 icm20608dev.nd of_find_node_by_path(/soc/aips-bus02000000/ spba-bus02000000/ecspi02010000); 39 if(icm20608dev.nd NULL) { 40 printk(ecspi3 node not find!\r\n); 41 return -EINVAL; 42 } 43 44 /* 2、 获取设备树中的 gpio 属性得到 CS 片选所使用的 GPIO 编号 */ 45 icm20608dev.cs_gpio of_get_named_gpio(icm20608dev.nd, cs-gpio, 0); 46 if(icm20608dev.cs_gpio 0) { 47 printk(cant get cs-gpio); 48 return -EINVAL; 49 } 50 51 /* 3、设置 GPIO1_IO20 为输出并且输出高电平 */ 52 ret gpio_direction_output(icm20608dev.cs_gpio, 1); 53 if(ret 0) { 54 printk(cant set gpio!\r\n); 55 } 56 57 /*初始化 spi_device */ 58 spi-mode SPI_MODE_0; /*MODE0 CPOL0 CPHA0 */ 59 spi_setup(spi); 60 icm20608dev.private_data spi; /* 设置私有数据 */ 61 62 /* 初始化 ICM20608 内部寄存器 */ 63 icm20608_reginit(); 64 return 0; 65 } probe 函数当设备与驱动匹配成功以后此函数就会执行第 13~55 行都是标 准的注册字符设备驱动。其中在第 38~49 行获取设备节点中的“ cs-gpio”属性也就是获取到 设备的片选 IO。 57 /*初始化 spi_device */ 58 spi-mode SPI_MODE_0; /*MODE0 CPOL0 CPHA0 *//*设置 SPI 为模式 0也就是 CPOL0 CPHA0。*/ 59 spi_setup(spi);/*设置好 spi_device 以后需要使用 spi_setup 配置一下。*/ 60 icm20608dev.private_data spi; /* 设置私有数据 *//*设置 icm20608dev 的 private_data 成员变量为 spi_device。*/ 61 62 /* 初始化 ICM20608 内部寄存器 */ 63 icm20608_reginit();/*调用 icm20608_reginit 函数初始化 ICM20608主要是初始化 ICM20608 指定寄 存器。*/ 64 return 0; 65 } 66 67 /* 68 * description : spi 驱动的 remove 函数移除 spi 驱动的时候此函数会执行 69 * param – client : spi 设备 70 * return : 0成功;其他负值,失败 71 *//*icm20608_remove 函数注销驱动的时候此函数就会执行。*/ 72 static int icm20608_remove(struct spi_device *spi) 73 { 74 /* 删除设备 */ 75 cdev_del(icm20608dev.cdev); 76 unregister_chrdev_region(icm20608dev.devid, ICM20608_CNT); 77 78 /* 注销掉类和设备 */ 79 device_destroy(icm20608dev.class, icm20608dev.devid); 80 class_destroy(icm20608dev.class); 81 return 0; 82 } 4、icm20608 寄存器读写与初始化 1 /* 2 * description : 从 icm20608 读取多个寄存器数据 3 * param – dev : icm20608 设备 4 * param – reg : 要读取的寄存器首地址 5 * param – val : 读取到的数据 6 * param – len : 要读取的数据长度 7 * return : 操作结果 8 */ 9 static int icm20608_read_regs(struct icm20608_dev *dev, u8 reg, void *buf, int len) 10 { 11 int ret; 12 unsigned char txdata[len]; 13 struct spi_message m; 14 struct spi_transfer *t; 15 struct spi_device *spi (struct spi_device *)dev-private_data; 16 17 gpio_set_value(dev-cs_gpio, 0); /* 片选拉低选中 ICM20608 */ 18 t kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); 19 20 /* 第 1 次发送要读取的寄存地址 */ 21 txdata[0] reg | 0x80; /* 写数据的时候寄存器地址 bit7 要置 1 */ 22 t-tx_buf txdata; /* 要发送的数据 */ 23 t-len 1; /* 1 个字节 */ 24 spi_message_init(m); /* 初始化 spi_message */ 25 spi_message_add_tail(t, m);/* 将 spi_transfer 添加到 spi_message */ 26 ret spi_sync(spi, m); /* 同步发送 */ 27 28 /* 第 2 次读取数据 */ 29 txdata[0] 0xff; /* 随便一个值此处无意义 */ 30 t-rx_buf buf; /* 读取到的数据 */ 31 t-len len; /* 要读取的数据长度 */ 原子哥在线教学:www.yuanzige.com 论坛:www.openedv.com 1467 I.MX6U 嵌入式 Linux 驱动开发指南 32 spi_message_init(m); /* 初始化 spi_message */ 33 spi_message_add_tail(t, m);/* 将 spi_transfer 添加到 spi_message*/ 34 ret spi_sync(spi, m); /* 同步发送 */ 35 36 kfree(t); /* 释放内存 */ 37 gpio_set_value(dev-cs_gpio, 1); /* 片选拉高释放 ICM20608 */ 38 39 return ret; 40 } 41 42 /* 43 * description : 向 icm20608 多个寄存器写入数据 44 * param – dev : icm20608 设备 45 * param – reg : 要写入的寄存器首地址 46 * param – val : 要写入的数据缓冲区 47 * param – len : 要写入的数据长度 48 * return : 操作结果 49 */ 50 static s32 icm20608_write_regs(struct icm20608_dev *dev, u8 reg, u8 *buf, u8 len) 51 { 52 int ret; 53 54 unsigned char txdata[len]; 55 struct spi_message m; 56 struct spi_transfer *t; 57 struct spi_device *spi (struct spi_device *)dev-private_data; 58 59 t kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); 60 gpio_set_value(dev-cs_gpio, 0); /* 片选拉低 */ 61 62 /* 第 1 次发送要读取的寄存地址 */ 63 txdata[0] reg ~0x80; /* 写数据的时候寄存器地址 bit8 要清零 */ 64 t-tx_buf txdata; /* 要发送的数据 */ 65 t-len 1; /* 1 个字节 */ 66 spi_message_init(m); /* 初始化 spi_message */ 67 spi_message_add_tail(t, m);/* 将 spi_transfer 添加到 spi_message */ 68 ret spi_sync(spi, m); /* 同步发送 */ 69 70 /* 第 2 次发送要写入的数据 */ 71 t-tx_buf buf; /* 要写入的数据 */ 72 t-len len; /* 写入的字节数 */ 73 spi_message_init(m); /* 初始化 spi_message */ 74 spi_message_add_tail(t, m);/* 将 spi_transfer 添加到 spi_message*/ 75 ret spi_sync(spi, m); /* 同步发送 */ 76 77 kfree(t); /* 释放内存 */ 78 gpio_set_value(dev-cs_gpio, 1);/* 片选拉高释放 ICM20608 */ 79 return ret; 80 } 81 82 /* 83 * description : 读取 icm20608 指定寄存器值读取一个寄存器 84 * param – dev : icm20608 设备 85 * param – reg : 要读取的寄存器 86 * return : 读取到的寄存器值 87 */ 88 static unsigned char icm20608_read_onereg(struct icm20608_dev *dev, u8 reg) 89 { 90 u8 data 0; 91 icm20608_read_regs(dev, reg, data, 1); 92 return data; 93 } 94 95 /* 96 * description : 向 icm20608 指定寄存器写入指定的值写一个寄存器 97 * param – dev : icm20608 设备 98 * param – reg : 要写的寄存器 99 * param – data : 要写入的值 100 * return : 无 101 */ 102 103 static void icm20608_write_onereg(struct icm20608_dev *dev, u8 reg, u8 value) 104 { 105 u8 buf value; 106 icm20608_write_regs(dev, reg, buf, 1); 107 } 108 109 /* 110 * description : 读取 ICM20608 的数据读取原始数据包括三轴陀螺仪、 111 * : 三轴加速度计和内部温度。 112 * param - dev : ICM20608 设备 113 * return : 无。 114 */ 115 void icm20608_readdata(struct icm20608_dev *dev) 116 { 117 unsigned char data[14]; 118 icm20608_read_regs(dev, ICM20_ACCEL_XOUT_H, data, 14); 119 120 dev-accel_x_adc (signed short)((data[0] 8) | data[1]); 121 dev-accel_y_adc (signed short)((data[2] 8) | data[3]); 122 dev-accel_z_adc (signed short)((data[4] 8) | data[5]); 123 dev-temp_adc (signed short)((data[6] 8) | data[7]); 124 dev-gyro_x_adc (signed short)((data[8] 8) | data[9]); 125 dev-gyro_y_adc (signed short)((data[10] 8) | data[11]); 126 dev-gyro_z_adc (signed short)((data[12] 8) | data[13]); 127 } 128 /* 129 * ICM20608 内部寄存器初始化函数 130 * param : 无 131 * return : 无 132 */ 133 void icm20608_reginit(void) 134 { 135 u8 value 0; 136 137 icm20608_write_onereg(icm20608dev, ICM20_PWR_MGMT_1, 0x80); 138 mdelay(50); 139 icm20608_write_onereg(icm20608dev, ICM20_PWR_MGMT_1, 0x01); 140 mdelay(50); 141 142 value icm20608_read_onereg(icm20608dev, ICM20_WHO_AM_I); 143 printk(ICM20608 ID %#X\r\n, value); 144 145 icm20608_write_onereg(icm20608dev, ICM20_SMPLRT_DIV, 0x00); 146 icm20608_write_onereg(icm20608dev, ICM20_GYRO_CONFIG, 0x18); 147 icm20608_write_onereg(icm20608dev, ICM20_ACCEL_CONFIG, 0x18); 148 icm20608_write_onereg(icm20608dev, ICM20_CONFIG, 0x04); 149 icm20608_write_onereg(icm20608dev, ICM20_ACCEL_CONFIG2, 0x04); 150 icm20608_write_onereg(icm20608dev, ICM20_PWR_MGMT_2, 0x00); 151 icm20608_write_onereg(icm20608dev, ICM20_LP_MODE_CFG, 0x00); 152 icm20608_write_onereg(icm20608dev, ICM20_FIFO_EN, 0x00); 153 } 5、字符设备驱动框架 重点是第 22~38 行的 icm20608_read 函数当应用程序调用 read 函数读取 icm20608 设备文件的时候此函数就会执行。此函数调用上面编写好的icm20608_readdata 函数读取 icm20608 的原始数据并将其上报给应用程序。 3、编写测试APP 32 int main(int argc, char *argv[]) 33 { 34 int fd; 35 char *filename; 36 signed int databuf[7]; 37 unsigned char data[14]; 38 signed int gyro_x_adc, gyro_y_adc, gyro_z_adc; 39 signed int accel_x_adc, accel_y_adc, accel_z_adc; 40 signed int temp_adc; 41 42 float gyro_x_act, gyro_y_act, gyro_z_act; 43 float accel_x_act, accel_y_act, accel_z_act; 44 float temp_act; 45 46 int ret 0; 47 48 if (argc ! 2) { 49 printf(Error Usage!\r\n); 50 return -1; 51 } 52 53 filename argv[1]; 54 fd open(filename, O_RDWR); 55 if(fd 0) { 原子哥在线教学:www.yuanzige.com 论坛:www.openedv.com 1473 I.MX6U 嵌入式 Linux 驱动开发指南 56 printf(cant open file %s\r\n, filename); 57 return -1; 58 } 59 60 while (1) { 61 ret read(fd, databuf, sizeof(databuf)); 62 if(ret 0) { /* 数据读取成功 */ 63 gyro_x_adc databuf[0]; 64 gyro_y_adc databuf[1]; 65 gyro_z_adc databuf[2]; 66 accel_x_adc databuf[3]; 67 accel_y_adc databuf[4]; 68 accel_z_adc databuf[5]; 69 temp_adc databuf[6]; 70 71 /* 计算实际值 */ 72 gyro_x_act (float)(gyro_x_adc) / 16.4; 73 gyro_y_act (float)(gyro_y_adc) / 16.4; 74 gyro_z_act (float)(gyro_z_adc) / 16.4; 75 accel_x_act (float)(accel_x_adc) / 2048; 76 accel_y_act (float)(accel_y_adc) / 2048; 77 accel_z_act (float)(accel_z_adc) / 2048; 78 temp_act ((float)(temp_adc) - 25 ) / 326.8 25; 79 80 printf(\r\n 原始值:\r\n); 81 printf(gx %d, gy %d, gz %d\r\n, gyro_x_adc, gyro_y_adc, gyro_z_adc); 82 printf(ax %d, ay %d, az %d\r\n, accel_x_adc, accel_y_adc, accel_z_adc); 83 printf(temp %d\r\n, temp_adc); 84 printf(实际值:); 85 printf(act gx %.2f°/S, act gy %.2f°/S, act gz %.2f°/S\r\n, gyro_x_act, gyro_y_act, gyro_z_act); 86 printf(act ax %.2fg, act ay %.2fg, act az %.2fg\r\n, accel_x_act, accel_y_act, accel_z_act); 87 printf(act temp %.2f°C\r\n, temp_act); 88 } 89 usleep(100000); /*100ms */ 90 } 91 close(fd); /* 关闭文件 */ 92 return 0; 93 } 六、运行测试 1、编译驱动程序和测试APP 1、编译驱动程序 1 KERNELDIR : /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imxrel_imx_4.1.15_2.1.0_ga_alientek ...... 4 obj-m : icm20608.o ...... 11 clean: 12 $(MAKE) -C $(KERNELDIR) M$(CURRENT_PATH) clean 第 4 行设置 obj-m 变量的值为“ icm20608.o”。 输入如下命令编译出驱动模块文件 make -j32 编译成功以后就会生成一个名为“ icm20608.ko”的驱动模块文件。 2、编译测试APP 在编译的时候加入如下参数即可-march-armv7-a -mfpu-neon -mfloathard 输入如下命令使能硬件浮点编译 icm20608App.c 这个测试程序arm-linux-gnueabihf-gcc -marcharmv7-a -mfpuneon -mfloat-abihard icm20608App.c -oicm20608App   2、运行测试 输入如下命令加载 icm20608.ko 这个驱动模块。depmod //第一次加载驱动的时候需要运行此命令modprobe icm20608.ko //加载驱动模块         当驱动模块加载成功以后使用 icm20608App 来测试输入如下命令./icm20608App /dev/icm20608         测试 APP 会不断的从 ICM20608 中读取数据然后输出到终端上 七、总结 本节的内容较多可以分成两天进行学习。主要学习了SPI驱动开发及运行测试的相关内容。 本文为参考正点原子开发板配套教程整理而得仅用于学习交流使用不得用于商业用途。
http://www.dnsts.com.cn/news/8696.html

相关文章:

  • 浙江省网站域名备案淘宝上做的网站可以优化吗
  • 东莞企业公司网站建设昆山做网站好的
  • 济南网站建设策划方案做网站销售工资
  • dede 电商网站计算机编程培训班
  • 软件库网站大全网站开发维护计入什么费用
  • 做外贸哪个网站最好能上国外网站的dns
  • 海口市建设局网站wordpress nextgen
  • 网站自助制作网络规划与设计心得体会
  • 退役军人事务部网站建设广水网站定制
  • 本地电脑做网站服务器ASP网站建设招聘
  • 网站生成器怎么做重庆规模最大的建网站公司
  • 贝壳企业网站管理系统公司建立网站步骤
  • 网站建设实践考试试题wordpress如何改成中文字体
  • 天津平台网站建设设计桂林网站建设培训
  • 哪里有免费的ppt模板下载网站交互网站怎么做
  • 网站响应是什么最好玩的传奇网页游戏
  • 上海做推广网站微信小程序
  • 网站建设gzzhixun河北住房和城乡建设厅网站电话是多少
  • 有没有代做课程设计的网站网站怎么做rss
  • 陕西住房建设厅官方网站百度词条官网入口
  • 专做特价手机的网站微信登录网页版登录入口
  • 网站开发用怎么语言网站怎么做一级域名跳转
  • 网站 如何备案网易网站建设
  • 网站建设扁平化2023年新闻热点事件
  • 网站开发工程师是什么内容查法人信息的系统
  • 公司建设网站的作用地方旅游网站建设方案
  • 网站策划书格式及范文1000字免费wordpress本地卡
  • 网站首页设置伪静态世纪购网站开发招聘
  • 家装公司需要什么条件昆明网站优化推广平台
  • 用dw做的网页怎么上传到网站学做网站论坛可信吗