在platformio自动上传esp8266固件

先说结论:

不想每次上传固件的时候手工点按钮,修改这个文件:C:\Users\你的登录名.platformio\platforms\espressif8266\builder\main.py

在319行UPLOADERFLAGS=中间增加2行:

“–before”, “default_reset”,

“–after”, “hard_reset”,

最终实现的效果就是,只要点击PlatformIO:upload 那个小箭头就可以自动上传固件,不再需要手工按按钮。

前言:

最近想研究一下单片机,先是学习51单片机,把江科大自化协的51课程全部看完了。但51简单是简单,就是不太实用,离实际应用有点脱节。然后又看工科男孙老师的视频,他说ESP32是yyds。所以也不用学STM32了,直接就上ESP32。ESP32开发的就没有很好的视频课程了,至少我没有找到。但终于还是对着源代码,把所有的模块基本上都过了一遍,现在就想做一个实际的应用。

第一个项目用ESP8266-01s的原因是它足够简单,只有2个IO口引出,IO0用来输入,IO2用来输出,适合初学者。因为学ESP32的源代码用的是microPython,所以ESP8266这个项目本来也想用的,但是microPython有点上手以后发现,它无法编译固件(或者是我没找到方法,要么方法很麻烦)。这样的话,代码就是用源代码的形式存储在FLASH中的,虽然我本来也是初学者,代码也不值钱。但是总觉得有点不爽。而且microPython的资源也不够丰富。比如想找一个ESP8266的自动配网smartConfig的microPython源码,很不好找。据说是ESP8266本身底层就没有microPython这个库。

所以最终还是要回arduino,用的是arduino 1.8.9,但是这个编辑器用起来很不爽。百度了一番,最终选择了VSCode+PlatformIO,这下写代码终于安逸了。

但是PlatformIO也有点不爽,每次上传固件都要自己手工按键。先关电,再按prog+开关上电,然后松掉prog,再点PlatformIO:upload 那个小箭头。不爽,很不爽。

实现过程:

突然想到之前用arduino的时候,它就可以自动上传不需要我手工按键呀。然后我打开arduino上传了一下,找到命令行:C:\Users\你的登录名\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2/tools/upload.py –chip esp8266 –port COM5 –baud 115200 –before default_reset –after hard_reset write_flash 0x0 C:\Users\你的登录名\AppData\Local\Temp\arduino_build_97171/Blink.ino.bin,其中的关键参数:–before default_reset –after hard_reset

本来想在platformio.ini也写上相应的配置,但是很不幸没找到。所以就只能更改命令行参数了。根据platformio上传提示中的Looking for upload port…,在C:\Users\你的登录名.platformio目录下面查找,找到一个疑似文件:C:\Users\你的登录名.platformio\platforms\espressif8266\builder\main.py,然后在文件中用关键字esp8266查找,找到代码段UPLOADERFLAGS,然后尝试增加关键参数,在platformio上传。

上传一次成功,强迫症舒适,爽了。

END.

改变vmware下manjaro分辨率自适应窗口大小

vmware下manjaro分辨率仅为800×600,窗口非常小无法正常使用。
而且也没法改,改了以后闪一下又复原了。

百度、谷歌了各种方法,已知并尝试无效的有:

1.怀疑组件出错,重新安装open-vm-tools,gtkmm,gtkmm3,linux510-virtualbox-host-modules还有virtualbox-guest-iso/utils
然后启动时候systemctl restart vmtoolsd

然而并没有用。

2.
sudo xrandr -q 查分辨率
sudo cvt 显示器分辨率
xrandr –newmode 新增分辨率模式
sudo xrandr –output 输出使配置生效

也不行。

最终有效的方法为:
编辑vmtoolsd.service文件增加配置,然后每次开机重启服务。
具体步骤:

1.将sudo设置成无密码
sudo tee /etc/sudoers.d/oldfox126 <<< ‘oldfox126 ALL=(ALL) NOPASSWD: ALL’
sudo chmod 440 /etc/sudoers.d/oldfox126

这里oldfox126是登录用户名,改成自己的。

2.编辑:
sudo vi /etc/systemd/system/multi-user.target.wants/vmtoolsd.service

在 [Unit] 节的最后加上这两行:
Requires=graphical.target
After=graphical.target

3.开关机自动任务增加(系统配置》开关与关机》自动启动》添加登录脚本)
sudo systemctl restart vmtoolsd

4.重启电脑manjaro

PVE如何通过OVA方式安装ROS6

OVF 是由分布式管理任务组 (DMTF) 指定的开放标准,用于打包和分发由一个或多个虚拟机 (VM) 组成的虚拟设备。
OVF 包 中包含用于描述虚拟机的元数据和文件元素、以及对于 OVF 包中应用程序的部署和操作至关重要的其他信息。其文件扩展名为 .ovf 。
开放式虚拟设备 (OVA) 是一个 OVF 包,采用单个文件存档形式,其文件扩展名为 .ova

简单的说,.ova文件是vmare导出的虚拟机文件,包含了虚拟机的配置和虚拟磁盘等信息,可以使用vmare导入ova文件,还原虚拟机。

目前网上已经有ROS6 L6版本的ova文件下载,使用PVE也可以导入OVA文件,从而使用L6版本的ROS6。

操作步骤如下:
比如我从网上下载了一个MikroTik-RouterOS-6.42.4.ova文件,首先使用SFTP等方式把该文件上传到PVE,然后通过SSH连接上PVE在控制台界面运行:

tar xvf MikroTik-RouterOS-6.42.4.ova
#解压缩ova包

ls -lh
#列出文件,发现多了几个文件
MikroTik-RouterOS-6.42.3-disk1.vmdk
MikroTik-RouterOS-6.42.3-disk2.vmdk
MikroTik-RouterOS-6.42.3.mf
MikroTik-RouterOS-6.42.3.ovf

qm importovf 107 MikroTik-RouterOS-6.42.3.ovf local –format qcow2
#将ovf配置还原,并新增到ID为107的虚拟机中,107虚拟机必须不存在,会自动新增

vi /etc/pve/nodes/pve/qemu-server/107.conf
#编辑虚拟机配置文件

ide0: local:107/vm-107-disk-0.qcow2
在这行后面增加一段,改成这样:
ide0: local:107/vm-107-disk-0.qcow2,model=VMware%20Virtual%20IDE%20Hard%20Drive,serial=00000000000000000001

******红色的这段必须完全照抄,一个字都不能少,包括前面的逗号******

改好以后保存文件,启动107虚拟机,登录到ros,查看license发现已经是L6级别了。

我试过红色这段改一个字符都不行,估计ROS6是基于硬盘的型号和序列号来计算授权的。而破解ROS6的大神,应该就是使用的vmare来创建的虚拟机环境来进行破解。

DHCP分配不同的网关地址给客户端

基础网络环境是这样:
1.一台ROS负责ADSL拨号上网,IP地址是:192.168.1.1
2.一台LEDE负责爱国上网,IP地址是:192.168.1.2,实际上LEDE还是通过ROS上网的,只是增加了爱国上网的功能(因为ROS功能比较单一,没有这个功能)

需求是:
1.局域网中的默认机器都能通过DHCP自动获取到IP地址,并访问我大中华局域网,网关是ROS;
2.少数几台机器可以自动获取到网关为LEDE,访问一些不存在的网站,比如油管。

为什么不把所有的机器网关都设置成LEDE?
1.因为LEDE转发效率没有ROS高,迅雷下载的时候CPU占用率飙升;
2.既然所有的流量实际上最后都要从ROS出去,对那些不需要爱国上网的客户端来说,直接把ROS作为网关肯定效率最高。

以上

最开始是想在ROS上实现需求,后来发现ROS的DHCP服务器实现不了(或者是我没找到办法)
经过对LEDE自带的dnsmasq研究了一番,实现了需求。

实现过程:
1.在ROS上关闭DHCP服务器,LEDE上开启DHCP,给局域网内的机器分配IP地址;
2.编辑LEDE上/etc/dnsmasq.conf的内容,增加以下这段:

log-dhcp
dhcp-option=option:dns-server,192.168.1.2 #设置默认的DNS服务器为192.168.1.2
dhcp-option=option:router,192.168.1.1 #设置默认的网关为192.168.1.1
dhcp-option=tag:xLEDE,option:router,192.168.1.2 #标记tag为xLEDE的网关为192.168.1.2

dhcp-host=a8:a6:13:5c:af:29,192.168.1.53,TV #假设电视的MAC地址是:a8:a6:13:5c:af:29,它自动获取到的IP地址是192.168.1.53,网关是默认的192.168.1.1
dhcp-host=ac:c3:ee:f7:17:35,set:xLEDE,192.168.1.54,Xiaomi #小米手机MAC地址ac:c3:ee:f7:17:35,获取到的IP地址是192.168.1.54,设置标记为xLEDE,网关是192.168.1.2

完。

使用uci命令行读取uci config小结

UCI是一个用C语言编写的小应用程序,用来集中管理OpenWrt/LEDE的所有配置选项,UCI配置文件位于目录 /etc/config/内。

假设有以下配置文件:/etc/config/v2conf,内容如下:

#这里是注释,实际使用中请删除
#每个config就是一个段落
config v2conf ‘v2name’ #段落类型是v2conf,段落名字是v2name,该段落在uci show中显示为v2conf.v2name
option enabled ‘1’ #在uci show中显示为v2conf.v2name.enabled=’1′
option server ‘s07030093’ #也可以直接读取uci get v2conf.v2name.server,

config subscriptions #这个段落是匿名的,段落类型是subscriptions,无段落名,该匿名段落在uci show中显示为v2conf.@subscriptions[0]
option address ‘http://www.baidu.com/’

config subscriptions #这个段落也是匿名的,该匿名段落在uci show中显示为v2conf.@subscriptions[1]
option address ‘http://www.google.com/’

config servers ‘server1’ #有段落名字就好读取了,uci show v2conf.server1
option name ‘name1′
option success ’62’
option total ‘129’
option uptime ‘2019-04-21 21:04:56’
#uci get v2conf.server1.uptime
#返回2019-04-21 21:04:56

config servers ‘s07030093’
option name ‘name2′
option success ’36’
option total ‘165’
option uptime ‘2019-04-21 21:25:02’

config servers ‘s61355758’
option name ‘name3’
option success ‘7’
option total ’33’
option uptime ‘2019-04-21 20:56:49′

uci命令可以直接在OpenWrt/LEDE的命令行中使用,如在控制台中输入:uci show v2conf
将显示如下内容:
v2conf.v2name=v2conf
v2conf.v2name.enabled=’1′
v2conf.v2name.server=’s07030093′
v2conf.@subscriptions[0]=subscriptions
v2conf.@subscriptions[0].address=’http://www.baidu.com/’
v2conf.@subscriptions[1]=subscriptions
v2conf.@subscriptions[1].address=’http://www.google.com/’
v2conf.server1=servers
v2conf.server1.name=’name1′
v2conf.server1.success=’62’
v2conf.server1.total=’129′
v2conf.server1.uptime=’2019-04-21 21:04:56′
v2conf.s07030093=servers
v2conf.s07030093.name=’name2′
v2conf.s07030093.success=’36’
v2conf.s07030093.total=’165′
v2conf.s07030093.uptime=’2019-04-21 21:25:02′
v2conf.s61355758=servers
v2conf.s61355758.name=’name3′
v2conf.s61355758.success=’7′
v2conf.s61355758.total=’33’
v2conf.s61355758.uptime=’2019-04-21 20:56:49′

常用uci命令:
1.uci show
用法:uci show config #显示config配置文件的所有配置
示例:
uci show v2conf #显示/etc/config/v2conf配置文件的所有配置
uci show v2conf.v2name #只显示v2conf.v2name段落

2.uci get
用法:uci get config.section.option #获取某option具体的值
示例:
uci get v2conf.v2name.enabled #获取enabled的值
uci get v2conf.v2name #如果只get到段落名,获取的是段落类型v2conf

3.uci set
用法:uci set config.section.option=value #设置某option具体的值为value
示例:
uci set v2conf.v2name.enabled=0
然后uci get v2conf.v2name.enabled 发现返回值是0

4.uci delete
4.1用法:uci delete config.section.option #删除某option
示例:
uci delete v2conf.s61355758.uptime
然后uci show v2conf.s61355758返回
v2conf.s61355758=servers
v2conf.s61355758.name=’name3′
v2conf.s61355758.success=’7′
v2conf.s61355758.total=’33’
发现uptime已删除

4.2用法:uci delete config.section #删除某段落section
示例:
uci delete v2conf.s61355758
然后uci show v2conf.s61355758返回
uci: Entry not found
段落不存在

5.uci commit
用法:uci commit config #提交修改。因为之前经过uci set/delete的值实际上都还在缓存内,重启以后就会丢失
示例:
uci commit v2conf

v2设置透明代理的要点

所谓透明代理就是局域网的流量直接通过网关,局域网内的客户端(电脑或者智能终端等)不需要再进行单独的代理设置。在网关上根据域名或者IP地址匹配,到底是走国内还是国外。这个过程对于客户端来说是完全透明的。

要点:
0. 在v2.json上存在配置
“inbounds”: [
{
“protocol”: “dokodemo-door”, #任意门协议,实现透明代理
“port”: 1234, #从1234端口进来的直接转发
“settings”: {
“network”: “tcp,udp”,
“followRedirect”: true
},
“sniffing”: {
“enabled”: false,
“destOverride”: [
“http”,
“tls”
]
}
}
]

1.在v2.json配置文件上,outbounds增加如下段落:
{
“sendThrough”: “0.0.0.0”,
“protocol”: “freedom”,
“settings”: { },
“tag”: “direct”, #针对tag为direct进行处理
“streamSettings”: {
“sockopt”: {“mark”: 255} #做标记,从防火墙上直连
}
}

2.在v2.json配置文件上,增加如下段落routing:
“routing”: {
“domainStrategy”: “IPIfNonMatch”, #当域名没有匹配任何规则时,将域名解析成IP(A 记录或AAAA 记录)再次进行匹配
“rules”: [
{
“type”: “field”,
“outboundTag”: “direct”,
“domain”: [“geosite:cn”] #如果是国内的域名匹配outbound中的direct标记
},
{
“type”: “field”,
“outboundTag”: “direct”,
“ip”:[“geoip:cn”] #如果是国内的IP匹配outbound中的direct标记
},
{
“type”: “field”,
“outboundTag”: “direct”,
“ip”:[“geoip:private”] #如果是私有IP匹配outbound中的direct标记
}
]
}

3.在iptables防火墙增加以下规则:
iptables -t nat -N V2RAY
iptables -t nat -A V2RAY -d x.x.x.x -j RETURN #x.x.x.x是v2服务器的IP,所有到服务器的流量直连
iptables -t nat -A V2RAY -d 0.0.0.0/8 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 10.0.0.0/8 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 127.0.0.0/8 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 169.254.0.0/16 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 172.16.0.0/12 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 192.168.0.0/16 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 224.0.0.0/4 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -d 240.0.0.0/4 -j RETURN #局域网、特殊IP直连
iptables -t nat -A V2RAY -p tcp -j RETURN -m mark –mark 0xff #0xff就是255,所有标记为255的流量直连,这样就跟刚才v2的outbounds标记对应上了
iptables -t nat -A V2RAY -p tcp -j REDIRECT –to-ports 1234 #其他的流量都转发到1234端口,这里的1234是inbounds段落中定义的转发端口
iptables -t nat -A PREROUTING -p tcp -j V2RAY

如何在openWRT/LEDE固件中添加第三方二进制IPK?

所谓的第三方二进制ipk就是没有源码,只有ipk文件。

主要参考文档:
OpenWrt Project: 使用镜像生成工具 (Image Builder)
https://openwrt.org/start?id=zh/docs/guide-user/additional-software/imagebuilder

编译环境及步骤参见:
编译openWRT/LEDE固件 http://xingyuncheng.net/?p=19

有两种办法:
1.从源码编译
1.1 上传
将需要添加的ipk文件上传到~/lede/bin/packages/x86_64/packages/packages/目录;

1.2 创建索引
上传ipk文件以后,需要将所上传的ipk文件进行索引,不然编译程序不认识,没法编译进固件。

#先设置PATH路径,否则创建过程会提示mkhash出错
export PATH=”~/lede/staging_dir/host/bin:$PATH”

cd ~/lede/bin/packages/x86_64/packages/packages/
~/lede/scripts/ipkg-make-index.sh ./ > ./Packages
gzip -9c ./Packages > ./Packages.gz

很不幸,运行的时候出现错误提示:
tar: ./control.tar.gz: Not found in archive
tar: Exiting with failure status due to previous errors

ipk文件其实就是压缩文件打包,只要将.ipk改成.tar.gz后缀,再解压缩就能看到ipk文件内容。
看了一下我要编译的ipk文件结构跟正常的不同,压缩包内显示的不是./control.tar.gz,而是control.tar.gz,所以没办法只好把~/lede/scripts/ipkg-make-index.sh修改了一下,24行内:
tar -xzOf $pkg ./control.tar.gz
改成:
tar -xzOf $pkg control.tar.gz
保存以后重新运行:
~/lede/scripts/ipkg-make-index.sh ./ > ./Packages
成功。

然后再运行
gzip -9c ./Packages > ./Packages.gz

这样~/lede/bin/packages/x86_64/packages/packages/文件夹就多了2个文件
Packages
Packages.gz

1.3 然后按照正常流程编译固件
编译完成以后,在固件的/根目录就会有上传的ipk文件。
但不幸的是,这样上传的ipk文件并不能自动安装,还需要自己手工安装一下。
不完美。

2.
用imagebuilder添加进去(可以自动安装进固件)
imagebuilder是从源码编译的时候,一个可选的中间文件,具体生成办法请百度。

2.1 上传ipk
~/imagebuilder/packages/是原生ipk所在路径,不要将第三方ipk放在同一个目录下。
所以上传到以下位置:~/imagebuilder/packages/packages/

2.2 创建索引文件
export PATH=”~/imagebuilder/staging_dir/host/bin:$PATH”
cd ~/imagebuilder/packages/packages/
~/imagebuilder/scripts/ipkg-make-index.sh ./ > ./Packages
gzip -9c ./Packages > ./Packages.gz

中间ipkg-make-index.sh运行出错也是参照1.2步骤修改的。
创建好的索引位于以下绝对路径:
/home/oldfox126/imagebuilder/packages/packages/Packages.gz
oldfox126是我登录Ubuntu的用户名

2.3 修改软件源
vi ~/imagebuilder/repositories.conf
在这行
# src custom file:///usr/src/openwrt/bin/x86/packages
后面增加一行:
src custom file:///home/oldfox126/imagebuilder/packages/packages
这里的oldfox126要修改成你登录Ubuntu的用户名
保存。

2.4 编译固件包
cd ~/imagebuilder/
make image PACKAGES=”smartdns luci-app-smartdns”

这里的smartdns、luci-app-smartdns,是我刚才上传的2个第三方二进制ipk,只要包名字不需要版本号和日期。如果不清楚包名字叫什么,
cat ~/imagebuilder/packages/packages/Packages
就看到了。

这样增加的ipk,才会自动安装进固件。
完美!

编译openWRT/LEDE固件

最近一个星期反复尝试编译openwrt/LEDE固件,期间失败很多次,只成功了几次,感觉快成玄学了:)
关键是编译速度非常慢,以小时记,1-3小时是起步。
当你睡了一觉起来,发现编译失败,那酸爽,不敢想象……

目前成功编译的代码如下:
sudo apt-get update
sudo apt-get -y install build-essential asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch unzip zlib1g-dev lib32gcc1 libc6-dev-i386 subversion flex uglifyjs git-core gcc-multilib p7zip p7zip-full msmtp libssl-dev texinfo libglib2.0-dev xmlto qemu-utils upx

git clone https://github.com/coolsnowwolf/lede
cd lede
./scripts/feeds update -a
./scripts/feeds install -a

make menuconfig
make download
make -j1 V=s TARGET_DEVICES=x86

再记录一下踩过的坑:
1.首先我使用的是:Ubuntu 14 LTS x64,还没测试过其他的版本,不知道高版本的Ubuntu是不是更容易成功编译;
2.划重点,******内存一定要在4G以上******;
3.划重点,在编译过程中会下载很多文件,基本都要翻墙下载而且网络很不稳定,所以在最后一步:
make -j1 V=s TARGET_DEVICES=x86
之前有一个预先下载的动作:
make download
但就算预先下载了也不能保证下载回来的文件都是正确的,最好在make download以后查一下
lede/dl/目录,按照文件大小排序。如果有文件只有几个字节,那肯定不对,直接删掉该文件,然后重新:make download

LEDE安装SmartDNS

wget -c https://downloads.openwrt.org/releases/18.06.2/packages/x86_64/base/libopenssl_1.0.2q-1_x86_64.ipk
wget -c https://github.com/pymumu/smartdns/releases/download/Release23/luci-app-smartdns.1.2019.04.02-0832.all.ipk
wget -c https://github.com/pymumu/smartdns/releases/download/Release23/smartdns.1.2019.04.02-0832.x86_64.ipk

opkg update
opkg install ./libopenssl_1.0.2q-1_x86_64.ipk
opkg install ./smartdns.1.2019.04.02-0832.x86_64.ipk
opkg install ./luci-app-smartdns.1.2019.04.02-0832.all.ipk