AM3359 gpio 应用程序调试记录,驱动代码后续给出

本文详细解读了AM335x GPIO应用的实现过程,包括头文件引用、GPIO值设定及控制操作,通过实例展示了如何通过打开特定设备节点来操作GPIO口,并使用ioctl函数进行GPIO值的读写。同时,文章还解决了在编译和模块安装过程中遇到的问题,如路径设置、头文件引用等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
 * am335x_gpio_app1.c
 *
 *  Created on: 2014年4月7日
 *      Author: qhq
 */
#include <linux/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// 头文件放在同一个文件里面就行,另外一个应该是include文件
// 我这次是要操作 GPIO1—21
#include "am335x_gpio.h"
// 我擦,桌面图标的创建方式是什么??
// main 函数里面的 两个参数是不是固定的???
int main(int argc, char **argv)
{
  int fd;
 // unsigned int 是32位??
    unsigned int cmd;
    // 下面这个数字写错了,要操作的是LED1, GPIO1——21,应该是53
    cmd = SET_GPIO_VALUE_BASE + 53;
    // open 这个函数应该也是在 am335x_gpio.c 里面写,实际证明是没有的
    // /dev/leds 这个是什么?? 和什么有联系??
    // 看来是跟 mknod /dev/leds c 231 0
    // 但是上面这句话 怎么和 模块联系起来??
    // 我明白了,这个句子是创建应用程序的 节点,不是直接联系模块
    // 看来是open 函数的问题吧

    // 好像模块里面写的是 /dev/am335x-gpio,所以下面这句话是错误的把
 //fd = open("/dev/leds",0);
    fd = open("/dev/am335x-gpio",0);
 if(fd < 0)
  printf("open leds faild\n");
 // 第二个参数是 cmd , 有四部分组成,看来是需要函数生成cmd ,才行,应该是 _IOC
 // am335x_gpio.h 里面定义的有幻数 MOTOR_MAGIC 'L', 需要把这个幻数添加到 cmd 里面
 //  然后这个函数里面检查幻数
 // 现在问题是,cmd 里面的那几位是对应的 选择GPIO口??

 // ioctl 的最后一个参数是干吗的?? 设置高低电平的

 ioctl(fd ,cmd, 0);
 printf("test ok\n");
 close(fd);
 return 0;
}

// 1.OK, 先编译一下把
// 遇到一下问题
//root@qhq-virtual-machine:/home/qhq/am3359/ti-a8-linux-04.06.00.07/drivers/leds# arm-none-linux-gnueabi- -O am335x_gpio_app am335x_gpio_app.c
//arm-none-linux-gnueabi-:找不到命令

// 2.书上是 make 一下,那我先修改一下makefile文件把

// 3.提示找不到头文件,怎么可能啊
// 解决办法,把PATH 路径设置一下把

// 4. #include <am335x_gpio.h> 和 #include "am335x_gpio.h"

// 5.am335x_gpio_app.c:43:1: 错误: 程序中有游离的‘\277’
// 这句话怎么理解???
// 网上的说法是使用了中文的标点符号

// 6. 目前这个问题消失了,但是出现am335x_gpio_app.c: 在函数‘main’中:
// am335x_gpio_app.c:12:11: 错误: expected expression before ‘int’
// 看来我需要先显示行号,在行号的位置右击--show line number
// 是不是头文件的问题?
// 好像可以了??

//7.root@am335x-evm:/lib/modules/3.2.0-gfb050b4# insmod am335x_gpio.ko
//insmod: error inserting 'am335x_gpio.ko': -1 File exists
// 应该是我之前已经安装过这个模块了rmmod,确实是的

// 8. /am335x_gpio_app.o: line 1: syntax error: word unexpected (expecting ")")怎么会遇到这个问题??
// 判断一是一个括号引起的问题??
// 判断二 我应该用am-none-linux-gnueabi- 编译这个程序把?? 找不到这个命令。我先用arm-linux-gcc 试试
// 暂时不会报错了,哈哈,但是不要高兴的太早啊。

// 9. 暂时还是没有反应,但是LED 灯一个亮,一个不亮,难道是因为这个这两个灯已经用到了???
// 我打算重启一下,看/dev目录里面是否有leds.没有的,目前模块刚安装上去的时候,LED灯会发生变化的

// 10.会不会是 fd 这个参数的数据类型错误??

// 11. 会不会是open 函数出问题了? fd 小于 0?? 不过其他的文件也没有,估计是头文件的问题把
// 原来是 设备的名字搞错了,真蛋疼,哈哈

 

 

 

 

<think>好的,我现在需要帮助用户解答关于LinuxSPI设备树驱动开发的问题。首先,用户明确提到了设备树配置,所以我要确保回答中包含设备树的相关内容。接下来,我需要回忆一下Linux驱动开发的基本流程,尤其是SPI驱动的部分。用户可能已经了解一些驱动开发的基础,但可能需要具体的步骤和示例。我应该分步骤说明,从设备树配置开始,然后到驱动模块的编写,最后是加载和测试。这样结构清晰,用户容易跟随。 设备树部分,需要解释如何添加SPI节点,包括兼容性字符串、寄存器地址、时钟频率等。同时,要提到具体的示例代码,比如spi_icm20608这样的设备节点,这样用户有参考的实例。记得使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$,不过这个问题可能涉及代码较多,数学公式较少,但还是要检查是否有需要的地方。接下来是驱动模块的开发,这里需要提到probe函数、初始化流程,比如分配内存、注册字符设备、创建设备节点等。引用中的probe函数示例可能有用,可以引用[^3]来说明。同时,要提到SPI核心API,如spi_setup、spi_sync等,这些都是关键点。然后,用户可能需要知道如何编译和加载驱动模块,这部分要给出具体的命令,比如insmod或者modprobe,以及如何将模块复制到开发板的系统目录,引用[^1]中的路径示例可能会有帮助。此外,测试部分需要说明如何通过应用程序驱动交互,或者使用sysfs进行简单测试。最后,相关问题的生成需要考虑用户可能的后续疑问,比如设备树语法、调试方法、用户空间交互以及实际项目案例。这些问题能够帮助用户深入学习和解决问题。 需要确保回答中的引用正确,比如设备树配置引用[^2],驱动代码结构引用[^3],路径操作引用[^1]。同时,语言要简洁明了,避免过于技术化的术语,但又要准确无误。检查是否有遗漏的步骤,比如设备树的编译和加载,这在开发过程中很重要,必须提及。 总结一下,回答的结构应该是:设备树配置 ->驱动开发步骤 ->编译加载->测试验证->参考资料和相关问题。确保每个部分都有示例代码或命令,这样用户可以直接应用。同时,注意使用中文,符合用户要求,并且LaTeX格式正确,虽然这个问题可能涉及代码较多,但数学公式可能较少,但如果有的话要正确应用。</think>### Linux SPI设备树驱动开发教程 #### 一、设备树配置 在Linux SPI驱动开发中,**设备树(Device Tree)** 是硬件描述的核心。以下是典型SPI设备节点的配置示例: ```dts &amp;spi1 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&amp;spi1_pins>; cs-gpios = <&amp;gpio 20 GPIO_ACTIVE_LOW>; icm20608: icm20608@0 { compatible = "invensense,icm20608"; // 驱动匹配标识[^3] reg = <0>; // 片选信号编号 spi-max-frequency = <10000000>; // SPI时钟频率 interrupt-parent = <&amp;gpio>; interrupts = <21 IRQ_TYPE_EDGE_RISING>; }; }; ``` - **关键参数**: - `compatible`:与驱动代码中的`of_device_id`匹配 - `spi-max-frequency`:定义通信速率(单位:Hz) - `reg`:指定片选信号编号(对应`cs-gpios`数组索引) 设备树编译后需通过`bootloader`加载到内核[^2]。 --- #### 二、驱动开发步骤 1. **驱动框架定义** ```c static const struct of_device_id spi_ids[] = { { .compatible = "invensense,icm20608" }, // 匹配设备树节点[^3] {} }; static struct spi_driver my_spi_driver = { .probe = spi_probe, .remove = spi_remove, .driver = { .name = "icm20608", .of_match_table = spi_ids, } }; ``` 2. **Probe函数实现** ```c static int spi_probe(struct spi_device *spi) { struct icm20608_dev *dev; // 1. 分配设备内存 dev = devm_kzalloc(&amp;spi->dev, sizeof(*dev), GFP_KERNEL); // 2. 初始化SPI通信参数 spi->mode = SPI_MODE_0; // 时钟相位/极性配置 spi_setup(spi); // 应用参数设置[^3] // 3. 注册字符设备 alloc_chrdev_region(&amp;dev->devno, 0, 1, "icm20608"); cdev_init(&amp;dev->cdev, &amp;fops); cdev_add(&amp;dev->cdev, dev->devno, 1); // 4. 创建设备节点 dev->class = class_create(THIS_MODULE, "icm20608"); device_create(dev->class, NULL, dev->devno, NULL, "icm20608"); // 5. 数据收发示例 u8 tx_buf[2] = {0x75, 0x00}; // 读取WHO_AM_I寄存器 u8 rx_buf[2]; spi_write_then_read(spi, tx_buf, 2, rx_buf, 2); } ``` --- #### 三、驱动编译与加载 1. **Makefile配置** ```makefile obj-m += spi_icm20608.o KDIR := /path/to/kernel/source all: make -C $(KDIR) M=$(PWD) modules ``` 2. **部署到开发板** ```bash # 将驱动模块拷贝到目标系统 sudo cp spi_icm20608.ko /lib/modules/$(uname -r)/kernel/drivers/spi/[^1] # 加载驱动模块 depmod -a modprobe spi_icm20608 ``` --- #### 四、测试与调试 1. **sysfs接口验证** ```bash # 查看SPI设备列表 ls /sys/bus/spi/devices/ # 读取寄存器值(需驱动实现sysfs接口) cat /sys/class/icm20608/icm20608/whoami ``` 2. **逻辑分析仪调试** 建议使用PulseView等工具抓取SCLK/MOSI/MISO波形,验证时序是否符合设备规格。 --- #### 五、参考资料 1. [Linux内核SPI子系统文档](https://www.kernel.org/doc/html/latest/driver-api/spi.html) [^2] 2. `spi.h`头文件中的API定义(包含spi_sync、spi_message等函数) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值