最近想用nodemcu+0.96’的oled显示实时时钟和周数,用lua脚本实现的时候发现刷新率极低,用示波器看i2c总线的SCL波形发现只有50kHz,但是官方文档明明说可以支持到1Mbit/s的速率。后来再仔细看一遍i2c相关的说明才发现,云编译为了向前兼容,默认开启I2C_MASTER_OLD_VERSION
宏。代价就是只能使用id=0
的一个i2c总线,而且速度固定为50Hz。
其实nodemcu官方提供了三种固件编译方法
- 云编译
- docker编译
- 本地Linux编译
云编译提供可视化的操作,根据页面提示只需几分钟就可完成编译,缺点就是只能使用官方仓库,而且不能提供更细致的个性化编译,比如上面的i2c宏。本文记录本地编译的步骤和踩的一些坑。
VMware 虚拟机安装
我使用的是VMware 16 pro 官方安装包,以及密钥链接
根据提示安装即可
Linux系统用的是Ubuntu 20.04
下载后打开VMware 创建虚拟机
选择默认设置即可
下面这里选择我们刚刚下好的系统镜像
下面设置登录系统相关信息,全名
应该是局域网中显示的计算机名,用户名
和密码
用于登录系统,牢记自己的密码。
'虚拟机名称’是VMware用于管理虚拟机的名称,可以自定义或者默认,位置
最好选择空间比较大的盘,至少要有20G的可用空间
以下可以根据个人需求修改
检查无误后点击完成,这里先不要点击自定义硬件
,我试过好几遍在这里点了之后闪退。内存和硬盘空间后面都可以设置,这里主要看位置和镜像是不是对的
点击完成
后VNware将进入新创建的虚拟机,完成Linux系统的安装,这个过程可能将花费30分钟时间。
Linux环境设置
- Linux换源
- 安装
git
sudo apt install git
- 安装
pip
sudo apt install python3-pip
- 安装
make
sudo apt install make
- 安装
gcc
sudo apt install gcc
- 卸载
serial
系统默认自带的serial
和仓库使用的pyserial
有冲突,必须卸载再安装
sudo pip3 uninstall serial
sudo pip3 install pyserial
克隆仓库
nodemcu github地址
直接git可能有点慢,也可以不git,去GitHub下载仓库zip包放到虚拟机中。向虚拟机上传文件的方法在文末。
注意:
官方仓库部分源码是引用的第三方库,比如u8g2
和libc
。看到如下图的形式,git clone
和直接下载zip包都下载不了引用的库。如果执行make
时报错,找不到文件,多半是这里的原因。
克隆或下载仓库到对应目录即可,注意文件夹名要与nodemcu保持一直,而不是引用的仓库名
自定义固件
头文件修改
根据需要修改相应文件,注释或取消注释
- 选择模组
@app/include/user_modules.h
注释或取消注释#define
来取消或开启某个模组,例如
...
#define LUA_USE_MODULES_MQTT
// #define LUA_USE_MODULES_COAP
..
- TLS/SSL支持
@app/include/user_config.h
取消以下宏定义注释来开启TLS/SSL功能
#define CLIENT_SSL_ENABLE
- debug调试开关
app/include/user_config.h
取消以下宏定义注释,输出运行性调试信息
#define DEVELOP_VERSION
- LFS
LFS默认为关闭状态,详见参考 - 串口默认波特率
@app/include/user_config.h
默认波特率为115200,可以修改以下宏定义改变波特率
注意,默认情况下固件会使用自动检测波特率算法,在启动时根据收到的几个字符锁定自身波特率(1200-230400)。
#define BIT_RATE_DEFAULT BIT_RATE_115200
- 编译双精度版本(仅Lua 5.3)
@app/include/user_config.h
默认生成支持浮点(单精度)和整数变量的构件。为了提升浮点运算精度,可以选择双精度编译。这也是Lua 5.1的默认构件。缺点就是运行时会花费大量RAM来存储变量。你可以通过取消以下宏定义注释改变:
//#define LUA_NUMBER_64BITS
或者在make时添加参数,覆盖以上宏定义:
make EXTRA_CCFLAGS="-DLUA_NUMBER_64BITS ....
- 编译整数版本(仅Lua 5.1)
@app/include/user_config.h
,默认生成支持浮点(双精度)变量的构件。可以通过取消以下宏定义注释来生成仅整数变量的构件:
//#define LUA_NUMBER_INTEGRAL
或者在make时添加参数,覆盖以上宏定义:
make EXTRA_CCFLAGS="-DLUA_NUMBER_INTEGRAL ....
- 版本名称
创建环境变量USER_PROLOG
export USER_PROLOG=jeekate_built_1942
编译&下载后,开机串口输出版本信息如下
- u8g2模组配置
驱动芯片选择@app/include/u8g2_displays.h
内嵌字体选择@app/include/u8g2_fonts.h
详见参考 - ucg模组配置
驱动和内嵌字体选择@app/include/ucg_config.h
详见参考
编译
cd
进入本地仓库根目录,执行make
命令(要先解锁该目录权限,否则需要使用sudo
)
sudo chmod -R 777 nodemcu-firmware
cd nodemcu-firmware
make
第一次编译会先下载工具链,也是托管在GitHub仓库。如果嫌慢或多次下载失败,可以去仓库页面使用迅雷或其他下载工具下载。放到本地仓库根目录下的cache
文件夹。
虚拟机文件交互
上传到虚拟机
打开虚拟机资源管理器,在Windows端直接把文件拖动到虚拟机资源管理器左侧边栏即可
从虚拟机下载
- 安装
vsftpd
详见参考 - Windows端
桌面右击,新建快捷方式
输入以下代码,用户名、密码、IP分别对应上一步的ftp用户名,密码和虚拟机IP地址。
%windir%\explorer.exe ftp://用户名:密码@IP:21/
注意
- Windows端从远程文件夹复制文件到本地,如果文件名没有改变(比如这里生成的两个文件名始终是
0x00000.bin
和0x10000.bin
)系统默认从本地缓存复制,而不是从远程ftp服务器下载。 - 烧录时,注意
.bin
文件名就对应的文件偏移地址,可以分两次下载。