openwrt学习指南

路由器的硬件构成

路由器的软件构成

路由器固件开发的一般流程

Openwrt常用命令

1.文件、目录类命令:cd cat rm touch mkdir Is mv grep
2.文本编辑器命令:ⅵ
3.权限类命令:chmod
4.模块命令:rmmod insmod modprobe Ismod
5.进程管理命令:ps top kill killall
6.文件下载上传工具:scp wget tftp
7.系统命令:mount dmesg reboot chpasswd data time du df
8.网络类命令:ifconfig arp route iptables netstat
9.OpenWrt专用命令:sysupgrade opkg

Makefile入门教程-基本方法

目标(target):依赖1 依赖2 依赖3 。。。依赖n(prerequisites)

        命令(command)

Makefile入门教程-特殊宏

 

Makefile四个动作 config、compile、install、clean 

common.mak 是Makefile的缩写

 all:libnvram.so libnvram.a nvram 定义了一个all 产生了libnvram.so、 libnvram.a 、nvram等三个文件 all在这里相当于隐含的compile

#
# This software is licensed under the Public Domain.
#

include $(TOPDIR)/rules.mk

PKG_NAME:=example1
PKG_VERSION:=0.1
PKG_RELEASE:=1
//这些是make menuconfig的配置 是必须的

PKG_MAINTAINER:=John Doe <john.doe@example.com>
PKG_LICENSE:=CC0-1.0
//这一部分可以直接放到src目录中去

include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk

define Package/example1
	SECTION:=utils
	# Select package by default
	#DEFAULT:=y
	CATEGORY:=Utilities
	TITLE:=Some different dummy application.
	URL:=https://www.example.com
endef
//这些是make menuconfig中能看到的信息

define Package/example1/description
	This is some dummy application.
endef
//这些是make menuconfig中能看到的信息(description描述)

//define Build/Configure 编译配置

define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
//编译前

//define Build/Compile 编译
//有几个不是必须的,如果 不写 就是用默认的

define Package/example1/install
	$(CP) ./files/* $(1)/

	$(INSTALL_DIR) $(1)/usr/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/example1 $(1)/usr/bin/
endef
//安装

$(eval $(call BuildPackage,example1))

如何创建package

拿了一个别人的demo - otrx文件

 改第一层Makefile

在进行编译之前 可以先在修改的那个文件夹make一下查看是否报错 

src文件夹中的各项文件也需要修改

openwrt如何逆向解析包-百度

openwrt如何创建开机自启动

 开机启动一共涉及两个文件夹

/etc/init.d

/etc/rc.d

但实际上只会执行/etc/rc.d中的文件

openwrt中opkg应用实例

1 安装app时保留上一次的文件(升级时保留配置文件),通过preinst和 postinst 实现

1)在Makefile中加入preinst和 postinst //记得更新版本号

 

preinst 将 etc文件中的config 考入tmp目录中

postinst 将 tmp文件中的config 再考回到etc目录中 完成覆盖, 从而保证config文件的一致性

2)上传package 

scp myapp_4_mipsel_24kc.ipk root@192.168.1.1:/tmp

3) opkg高版本文件

opkg intall myapp_4_mipsel_24kc.ipk

2 升级后保留配置文件

注意点:一定要用sysupgrade升级 而不能用uboot升级 

1)创建config文件

2)在Makefile中加入 //相当于声明,则升级时会自动保留这个配置文件

define Package/myaoo/conffies

        /etc/config/myapp

        /etc/myapp.conf

endef

3)编译 make package/example/compile V=99

4) 让路由器和电脑虚拟机保持同一频段,然后上传package,上传至tmp目录

scp myapp_2_mipsel_24kc.ipk root@192.168.1.1:/tmp

5)在路由中修改配置,并用uci commit保存 

查看机型:cat /proc/cpuinfo  /  ubus call system board

6)使用sysupgrade 进行升级,查看文件是否保留

上传bin文件 scp openwrt-ramips-mt7620-psg1218b-squashfs-sysupgrade.bin root@192.168.1.1:/tmp

 升级:sysupgrade openwrt-ramips-mt7620-psg1218b-squashfs-sysupgrad //用串口能看到过程

openwrt Cron定时任务

1 每天晚上0点 重启路由

几分?几时?几日?几月?周几?

0        0        *        *        *

 

 

 

 设置定时任务 //测试时要熟练掌握 date 命令

2 每天晚上11:00~早上8:00 关闭LED灯/无线

3 周一~周五 关闭WIFI

 openwrt GPIO框架及其应用

GPIO:General-purpose input/output 输入/输出的接口

应用

1)LED灯 (USB WiFi)

软连接 使用GPIO控制 0 1 变化 会导致 CPU消耗

硬连接 引脚直接连接

2)复位键

3)WPS键

GPIO有几种访问方式

1)sysfs 文件形式

优点)不需要用c、可用Lua、Python

缺点)文件,所以速度慢,一般用于低速IO访问

2)ioctl 系统调用

优点)速度快

缺点)需要用c/c++

3)mmap 内存

用c语言、速度最快、跨平台

GPIO实验 output实验 蜂鸣器

电路连接图

1 进入路由控制台

2 进入 gpio目录 cd /sys/class/gpio

3 使能 42 号引脚 echo "42" > export

4 设置gpio口为推挽输出模式 echo "out" > direction

5 拉高电平:蜂鸣器响 echo "1" > value

 mmap实验

实验之前打开 make menuconfig

打开

 MediaTech(MTK) MT7628 MT7688 Linux 下使用mmap实现用户态 GPIO 驱动

/* forgotfun.org 佐须之男 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#define MMAP_PATH    "/dev/mem"


#define RALINK_GPIO_DIR_IN        0
#define RALINK_GPIO_DIR_OUT        1

#define RALINK_REG_PIOINT        0x690
#define RALINK_REG_PIOEDGE        0x6A0
#define RALINK_REG_PIORENA        0x650
#define RALINK_REG_PIOFENA        0x660
#define RALINK_REG_PIODATA        0x620
#define RALINK_REG_PIODIR        0x600
#define RALINK_REG_PIOSET        0x630
#define RALINK_REG_PIORESET        0x640

#define RALINK_REG_PIO6332INT        0x694
#define RALINK_REG_PIO6332EDGE        0x6A4
#define RALINK_REG_PIO6332RENA        0x654
#define RALINK_REG_PIO6332FENA        0x664
#define RALINK_REG_PIO6332DATA        0x624
#define RALINK_REG_PIO6332DIR        0x604
#define RALINK_REG_PIO6332SET        0x634
#define RALINK_REG_PIO6332RESET        0x644

#define RALINK_REG_PIO9564INT        0x698
#define RALINK_REG_PIO9564EDGE        0x6A8
#define RALINK_REG_PIO9564RENA        0x658
#define RALINK_REG_PIO9564FENA        0x668
#define RALINK_REG_PIO9564DATA        0x628
#define RALINK_REG_PIO9564DIR        0x608
#define RALINK_REG_PIO9564SET        0x638
#define RALINK_REG_PIO9564RESET        0x648


static uint8_t* gpio_mmap_reg = NULL;
static int gpio_mmap_fd = 0;

static int gpio_mmap(void)
{
    if ((gpio_mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
        fprintf(stderr, "unable to open mmap file");
        return -1;
    }

    gpio_mmap_reg = (uint8_t*) mmap(NULL, 1024, PROT_READ | PROT_WRITE,
        MAP_FILE | MAP_SHARED, gpio_mmap_fd, 0x10000000);
    if (gpio_mmap_reg == MAP_FAILED) {
        perror("foo");
        fprintf(stderr, "failed to mmap");
        gpio_mmap_reg = NULL;
        close(gpio_mmap_fd);
        return -1;
    }

    return 0;
}

int mt76x8_gpio_get_pin(int pin)
{
    uint32_t tmp = 0;

    /* MT7621, MT7628 */
    if (pin <= 31) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIODATA);
        tmp = (tmp >> pin) & 1u;
    } else if (pin <= 63) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO6332DATA);
        tmp = (tmp >> (pin-32)) & 1u;
    } else if (pin <= 95) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO9564DATA);
        tmp = (tmp >> (pin-64)) & 1u;
        tmp = (tmp >> (pin-24)) & 1u;
    }
    return tmp;

}

void mt76x8_gpio_set_pin_direction(int pin, int is_output)
{
    uint32_t tmp;

    /* MT7621, MT7628 */
    if (pin <= 31) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIODIR);
        if (is_output)
            tmp |=  (1u << pin);
        else
            tmp &= ~(1u << pin);
        *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIODIR) = tmp;
    } else if (pin <= 63) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO6332DIR);
        if (is_output)
            tmp |=  (1u << (pin-32));
        else
            tmp &= ~(1u << (pin-32));
        *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO6332DIR) = tmp;
    } else if (pin <= 95) {
        tmp = *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO9564DIR);
        if (is_output)
            tmp |=  (1u << (pin-64));
        else
            tmp &= ~(1u << (pin-64));
        *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO9564DIR) = tmp;
    }
}

void mt76x8_gpio_set_pin_value(int pin, int value)
{
    uint32_t tmp;

    /* MT7621, MT7628 */
    if (pin <= 31) {
        tmp = (1u << pin);
        if (value)
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIOSET) = tmp;
        else
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIORESET) = tmp;
    } else if (pin <= 63) {
        tmp = (1u << (pin-32));
        if (value)
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO6332SET) = tmp;
        else
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO6332RESET) = tmp;
    } else if (pin <= 95) {
        tmp = (1u << (pin-64));
        if (value)
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO9564SET) = tmp;
        else
            *(volatile uint32_t *)(gpio_mmap_reg + RALINK_REG_PIO9564RESET) = tmp;
    }
}

int main(int argc, char **argv)
{
    int ret = -1;

    if (gpio_mmap())
        return -1;

    printf("get pin 39 input %d\n", mt76x8_gpio_get_pin(39));
    printf("get pin 40 input %d\n", mt76x8_gpio_get_pin(40));
    printf("get pin 41 input %d\n", mt76x8_gpio_get_pin(41));
    printf("get pin 42 input %d\n", mt76x8_gpio_get_pin(42));

    
    printf("set pin 39 output 1\n");
    mt76x8_gpio_set_pin_direction(39, 1);
    mt76x8_gpio_set_pin_value(39, 1);
    printf("set pin 40 output 0\n");
    mt76x8_gpio_set_pin_direction(40, 1);
    mt76x8_gpio_set_pin_value(40, 0);
    printf("set pin 41 output 1\n");
    mt76x8_gpio_set_pin_direction(41, 1);
    mt76x8_gpio_set_pin_value(41, 1);
    printf("set pin 42 output 0\n");
    mt76x8_gpio_set_pin_direction(42, 1);
    mt76x8_gpio_set_pin_value(42, 0);

    while (1)
    {
        mt76x8_gpio_set_pin_value(42, 0);
        mt76x8_gpio_set_pin_value(42, 1);
    }
    close(gpio_mmap_fd);

    return ret;
}

 OpenWrt 基于GPIO、Hotplug、DTS 的按键实验

DTS是Device Tree Source的缩写,用来描述设备的硬件细节。在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。为了去掉这些垃圾代码,Linux采用DTS这种新的数据结构来描述硬件设备。采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。

.dtsi文件 都属于公共文件 ,能被其他文件依赖的

按键实验

选择GPIO1 偏移量6 则代表 GPIO口为32+6=38

GPIO_ACTIVE_LOW 代表低电平触发

KEY_WPS_BUTTON 定义了一个宏 代表了wps键

你现在要修改一个属于自己DTS ,先找到openwrt文件系统中的DTS源文件

 OpenWrt vlan、switch、bridge、wans、lan、wlan、wifi等相关概念解析

 

 

OpenWrt基于DTS适配RAM、Flash、复位键、波特率、端口布局实验 

openwrt软件移植

先从github上,下拉压缩包至本地,然后解压缩,config(下载以后会出现configure.in 我们需要autoconf,然后就会生成configure)、make。这样就可以查看软件所依赖的各类库(动态、静态)。

在自己的例子目录中新建wificat文件夹,并新建Makefile和src

 回到下载的软件包 make distclean 清空编译的文件

然后复制粘贴到src文件夹下, make menuconfig选择文件夹,编译,上传,运行软件包

openwrt静态库和动态库

动态库:.so文件 运行时才加载,程序小,通常情况release下动态库

静态库:.a 直接编译到程序中,程序大,debug时使用静态库

xx.c->xx.o-LD-xx.so

                -AR-xx.a

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值