openWRT 驱动开发举例

来源:互联网 发布:涂色 app 源码 编辑:程序博客网 时间:2024/04/24 09:55

http://wiki.t-firefly.com/index.php/FireWRT/Remote_Login



目录

 [隐藏] 
  • 1 FireWRT GPIO
    • 1.1 用户空间控制GPIO
    • 1.2 GPIO实例应用:控制电源灯
    • 1.3 GPIO实例应用:电源控制
  • 2 FireWRT I2C
    • 2.1 FireWRT添加I2C支持
    • 2.2 FireWRT添加I2C传感器
  • 3 FireWRT UART
    • 3.1 添加UART设备
    • 3.2 添加UART的clk
    • 3.3 修改pinctrl配置

FireWRT GPIO

用户空间控制GPIO

控制GPIO的目录位于FireLink的/sys/class/gpio

Sys-0.png

  • export
       告知系统需要导出GPIO的引脚编号。
  • unexport
       通知系统取消GPIO导出。
  • gpiochipX
      表示是一个gpiochip,用来管理和控制一组gpio端口的控制器目录,保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数ngpio 。
  • gpioN
       N代表了gpio的引脚号,在gpioN目录下由如下属性文件:

Sys-1.png

  • direction
        表示gpio端口的方向,读取结果是in或out。 
  • value
       表示gpio引脚的电平,其中0表示低电平,1表示高电平,如果gpio被配置为输出,这个值是可写的,注意任何非零的值都将输出高电平。

GPIO实例应用:控制电源灯

dts里对gpio-leds的注册,compatible要与led的驱动gpio-leds.c里compatible对应,label是设备的名字。

Leddts.png

设备注册成功,在FireWRT文件系统下就会有 /sys/class/leds/firewrt:green:wan。

Ledpower.png

控制电源灯(1:熄灭,0:点亮)

Ledcontrol.png

GPIO实例应用:电源控制

FireLink电源按键引脚电路图:

Gpio-2.png

POWER_CON接GPIO#24,POWER_DEC接GPIO#23。 当GPIO#24输出高电平时,8050处于导通状态,电源接通,key不管处于断开还是连接状态,FireLink都会处于上电状态。 当GPIO#24输出低电平时,8050处于截止状态,key正常工作。

  • 应用

断开FireLink开关时,卸载所有usb挂载设备,FireLink自动断电。

  1. 设置POWER_CON为高电平,检测POWER_DEC状态。
  2. 当POWER_DEC状态发生变化时,卸载USB挂载设备,设置POWER_CON为低电平,FireLink断电。
  • 演示步骤

1.控制POWER_CON(GPIO#24)输出高电平,弹起电源键FireLink依然运行。 Gpio-3.png

FireWRT I2C

FireWRT添加I2C支持

  • 打开FIREWRT.dts并添加以下两段代码:
        $vim FIREWRT.dts

1.指定i2c驱动

I2c-dts0.png

2.GPIO复用为i2c接口

I2c-dts1.png

  • i2c配置

配置方法:

       $make menuconfig

Makemenuconfig.png

Mt7621-i2c.png

  • 编译固件
       make V=99 -j4
  • 刷新固件

将新编译的固件烧写到FireWRT上,进入串口发现: Lsi2c.png

FireWRT添加I2C传感器

  • 传感器

温湿度传感器ChipCap2,复用i2c从设备连接示意图

Chipcap2-0.png

采集四字节温湿度时序图

Chipcap2-1.png

温湿度计算公式

Chipcap2-2.png

  • 采集温湿度实例代码
       /*************************************************************************               > File Name: chipcap2.c               > Author:daixj                > Mail:fl.service@t-firefly.com       ************************************************************************/       #include <stdio.h>         #include <fcntl.h>         #include <stdlib.h>         #include <unistd.h>         #include <sys/ioctl.h>         #include <string.h>       #include <unistd.h>       #define I2C_RETRIES0x0701/* number of times a device address shouldbe polled when not acknowledging */       #define I2C_TIMEOUT0x0702/* set timeout in units of 10 ms */       /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses        * are NOT supported! (due to code brokenness)        */       #define I2C_SLAVE0x0703/* Use this slave address */       #define I2C_SLAVE_FORCE0x0706/* Use this slave address, even if it is already in use by a driver! */       #define I2C_TENBIT0x0704/* 0 for 7 bit addrs, != 0 for 10 bit */       #define I2C_FUNCS0x0705/* Get the adapter functionality mask */       #define I2C_RDWR0x0707/* Combined R/W transfer (one STOP only) */       #define I2C_PEC0x0708/* != 0 to use PEC with SMBus */       #define I2C_SMBUS0x0720/* SMBus transfer */       int main(int argc, char** argv)       {               int file;               int i2c_bus_number = 0;                char filename[20];               int addr = 0x28; /* The I2C DEVICE address for GE ChipCap2*/               unsigned char buf[10];               int i;               snprintf(filename, 19, "/dev/i2c-%d", i2c_bus_number);               file = open(filename, O_RDWR);               if (file < 0) {                       exit(1);               }               if (ioctl(file, I2C_SLAVE, addr) < 0) {                       exit(1);                }                if (write(file,buf,1) != 1) {                        printf("Failed to write to the i2c bus.\n");                 }                 // Wake the sensor from sleep and trigger a measurement (may take up to 100 mili sec)                 usleep(100 * 1000);                 if (read(file, buf, 4) != 4) {                         printf("ERROR HANDLING: i2c transaction failed\n");                 } else {// debug                #ifdef DEBUG                         printf("buf[0]: 0x%x\n", buf[0]);                         printf("buf[1]: 0x%x\n", buf[1]);                         printf("buf[2]: 0x%x\n", buf[2]);                         printf("buf[3]: 0x%x\n", buf[3]);                #endif                }                unsigned short value_umi;                float humidity;                value_umi = buf[0];                value_umi = (value_umi & 0x3F) << 8;                value_umi = value_umi | buf[1];                humidity = value_umi;                humidity = humidity / 163.84;                unsigned short value_temp;                float temperature;                value_temp = buf[2];                value_temp = value_temp << 8;                value_temp = value_temp | buf[3];                value_temp = value_temp & 0xFFFC;                temperature = value_temp;                temperature = ((temperature / 65536) * 165) - 40;                // Prints the temperature and humidity, comma separated, with 2 decimal precision                printf("temperature:%0.2f,humidity:%0.2f\n", temperature, humidity);                 return 0;       }
  • 测试

Chipcap2-3.png

FireWRT UART

MT7621内置3组UART,UART1我们用作console,UART2由于其TX信号被其它功能占用,所以我们如果开发外接UART设备,可以使用UART3。

添加UART设备

在mt7621.dtsi中添加如下代码,UART3使用的中断号为28,设置波特率为9600.

Chipcap3-1.jpg

添加UART的clk

在linux/arch/mips/ralink/mt7621.c "void __init ralink_clk_init(void)"中添加如下代码:

Chipcap3-2.jpg

修改pinctrl配置

在mt7621.dtsi中关于pinctrl的描述中添加

Chipcap3-3.jpg

完成以上操作后,UART3生成的对应tty设备节点为/dev/ttyS1.


0 0