今天开始,抽时间回归一下本行,嵌入式的开发,之前的工作很多时候都用到了这个OpenWRT系统。

OpenWRT是一个高度模块化、高度自动化的嵌入式Linux系统,拥有强大的网络组件和扩展性,常常被用于工控设备、电话、小型机器人、智能家居、路由器以及VOIP设备中。 同时,它还提供了100多个已编译好的软件,而且数量还在不断增加,而OpenWrt SDK 更简化了开发软件的工序。

说的直白一点,还不是因为免费好用。

在openwrt上运行KVM openwrt kpr_wdl

其他的不说,OpenWRT有一个非常有特点的东西,叫做IPK软件包,就像我们windows的安装软件一样,开发出来之后,可以直接安装到目标机器当中,非常的yin性。当然也会受到架构影响,跨了平台可能需要重新编译

在openwrt上运行KVM openwrt kpr_openwrt_02

今天就示范一下如何开发一款这样的IPK软件。

环境准备

首先需要一套完整OpenWRT的开发环境,包括编译主机,整套的OpenWRT源码,以及针对自己的开发板,配置好对应的配置文件,一句话,就是拥有一个能够编译出你自己开发板镜像的编译环境。

这个一般提供给你开发板的说明中,都会包含如何搭建这个开发环境,这里就不做介绍了。

在openwrt上运行KVM openwrt kpr_ipk_03

模块功能

今天我这里要开发的是款能够帮助我们远程控制OpenWRT系统的软件,我们的监控PC(windows系统)能够在不远程登录目标开发板的情况下,控制目标开发板。原理很简单,就是目标开发板主动发起连接到监控PC,能够远程执行监控PC下发的命令,并且能够将结果传输回来。这样就不再需要目标开发板开放防火墙端口了,这在某种情况下还是比较有使用价值的。

在openwrt上运行KVM openwrt kpr_源码_04

代码结构

整体代码放置在一个目录当中,需要上传至编译路径根目录下的package/utils路径下, 我们将模块命令为jwdlh 那么整个代码结构如下

lede_AR9331_zhuotk_source_32bit$ tree package/utils/jwdlh/
package/utils/jwdlh/
├── Makefile		编译IPK的Makefile
└── src
    ├── cbi
    │   └── jwdlh.lua 这个是配置页面
    ├── config
    │   └── jwdlh     这个是配置文件,用来保存参数使用
    ├── controller
    │   └── jwdlh.lua 这个是页面菜单配置
    ├── init.d
    │   └── jwdlh_service	这个是启动脚本原型
    ├── jwdlh.c				源代码
    ├── Makefile			编译源码Makefile
    └── rc.d
        └── S80jwdlh_service -> ../init.d/jwdlh_service 这个是启动脚本

详细来说一下各部分的代码 1.外部的Makefile

include $(TOPDIR)/rules.mk

这里定义了安装包的名字,版本,编译路径
PKG_NAME:=jwdlh
PKG_VERSION:=1.0
PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk
定义了在menuconfig的时候,出现在的位置,以及标题
define Package/jwdlh
SECTION:=base
CATEGORY:=Utilities
TITLE:=beat tiger tonight
endef

定义了简介内容
define Package/jwdlh/description
this is a description
endef

这里是编译准备阶段的操作
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

这里是安装阶段的操作,包括各种拷贝文件
define Package/jwdlh/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/jwdlh $(1)/bin/

$(INSTALL_DIR) $(1)/etc/config
$(CP)  $(PKG_BUILD_DIR)/config/* $(1)/etc/config
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi	
$(CP)  $(PKG_BUILD_DIR)/cbi/* $(1)/usr/lib/lua/luci/model/cbi
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
$(CP)  $(PKG_BUILD_DIR)/controller/* $(1)/usr/lib/lua/luci/controller
$(INSTALL_DIR) $(1)/etc/init.d
$(CP)  $(PKG_BUILD_DIR)/init.d/* $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/rc.d
$(CP)  $(PKG_BUILD_DIR)/rc.d/* $(1)/etc/rc.d
endef

这里是执行编译
$(eval $(call BuildPackage,jwdlh))

2.内部的Makefile

all: jwdlh
jwdlh: jwdlh.o
 $(CC) $(LDFLAGS) jwdlh.o -o jwdlh
helloworld.o: jwdlh.c
 $(CC) $(CFLAGS) -c jwdlh.c
clean:
rm *.o jwdlh

就是一个非常典型的Makefile过程。

3.cbi下的lua

local m, s, o1, o2, t

配置文件选择jwdlh
m = Map("jwdlh", "远程监控配置", "本配置页面用于配置远程监控")
s = m:section(TypedSection, "jwdlh")
s.anonymous = true
s.addremove = false

标签页
s:tab("general",  translate("General Settings")) 

两个参数,分别是rip和rport
s:taboption("general", Value, "rip", "远程主机地址:", "远程主机ip地址")
s:taboption("general", Value, "rport", "端口:", "远程主机监听端口")
return m

4.controller下的lua

module("luci.controller.jwdlh", package.seeall)
function index()
	配置路径在根目录,服务下面
	entry({"admin", "services", "jwdlh"}, cbi("jwdlh"), _("远程监控"), 100)
end

5.配置文件jwdlh

config jwdlh 'jwdlh'
        option rip 	'192.168.101.68'
        option rport '8866'

6.启动脚本原型

#!/bin/sh /etc/rc.common

START=90
STOP=10
USE_PROCD=1
PROG=/bin/jwdlh

校验参数的函数
validate_jwdlh_section() {
        uci_validate_section jwdlh jwdlh "${1}" \
                'rip:string' \
                'rport:string'
}
启动函数
start_service() {
        local rip rport

		读取两个参数到 rip和rport中
        validate_jwdlh_section jwdlh || {
                echo "validation failed"
                return 1
        }
		
		启动可执行服务程序
        procd_open_instance
        procd_set_param command $PROG "$rip" "$rport"
        procd_set_param respawn
        procd_close_instance
}
停止函数
stop_service()
{
        service_stop ${PROG}
}

服务触发函数
service_triggers()
{
        procd_add_reload_trigger "jwdlh"
        procd_add_validation validate_jwdlh_section
}

7.启动脚本 就是启动脚本原型的链接文件。

8.源代码jwdlh.c 原理就是不断去连接一个远程服务器,然后接收消息,再将其执行结果返回回去。代码就不贴了,后续提供下载。

编译及安装

在根目录执行

make menuconfig

进入

在openwrt上运行KVM openwrt kpr_openwrt_05

选择我们的模块

在openwrt上运行KVM openwrt kpr_源码_06

,这里也就知道了为啥模块叫jwdlh

在openwrt上运行KVM openwrt kpr_openwrt_07

然后,保存配置,退出menuconfig,执行

make V=s

最后在下面会生成我们的ipk文件

./bin/packages/mips_24kc/base/jwdlh_1.0_mips_24kc.ipk

然后我们将文件拷贝到开发板 执行安装命令

opkg install 文件名称

在openwrt上运行KVM openwrt kpr_wdl_08

修改重编译及再安装

需要删除之前的历史文件

rm -rf build_dir/target-mips_24kc_musl/jwdlh/

再执行

make V=s

然后卸载旧文件

opkg remove jwdlh

再次重新安装即可更新

整体效果

页面效果

在openwrt上运行KVM openwrt kpr_openwrt_09

进程

在openwrt上运行KVM openwrt kpr_源码_10

windows上位机

真对这个功能,可以开发一个上位机软件,以图形化界面,方面用户操作

在openwrt上运行KVM openwrt kpr_ipk_11

当有用户上线时,会弹出提示,然后输入命令,可以得到返回结果

在openwrt上运行KVM openwrt kpr_源码_12

这个部分需要另写一篇文章来介绍windows系统下MFC类型上位机软件开发。

结尾

内部有一些文件,例如lua的页面,这个需要多做修改,才能大概理解每个语句的意思。 IPK全部代码下载链接IPK源码压缩包 上位机软件代码下载链接上位机源码压缩包

今天看到申请北京的工作居住证的条件和时间,也是越来越严格,时间也越来越长了。外地人在北京的生存,很大一部分会随着孩子的出生,长大,开始发生位置的转变,有的夫妻分离,有的举家回乡,也有的开始长距离通勤。

在openwrt上运行KVM openwrt kpr_openwrt_13

看到一条新闻,是关于银行招聘的,一个人去面试,发现去的全是985,211的本科和研究生,就像之前那些去烟草公司的一样,有人说未来30年,银行都会是一个利好的行业。可是华夏奋起的年代,靠的都是贷款吗?

在openwrt上运行KVM openwrt kpr_源码_14

算了,他们内卷就内卷去吧,反正我还是学习和读书。因为

读书能破万卷!!