ESP32嵌入固件读取
虽然我们引入了littlefs,但是在实际使用中用littlefs并不是很方便,因为HTML网页存在了文件系统中,在读取时依旧需要占用一个新的缓存来加载它,这就造成了网页被保存了两次。
更好的做法是利用ESP-idf原生的二进制数据嵌入特性,直接将文件嵌入到固件中。
ESP-IDF提供了 target_add_binary_data()
的CMake函数,这是一个专门用于将任意文件嵌入到固件中的工具。我们在CMakeLists.txt文件中将文件打包成目标文件(.obj),之后生成全局符号标记数据的起始和结束位置,然后在链接阶段将这些数据嵌入到最终的固件二进制文件中。
具体做法是,我们在littlefs文件目录中的CMakeLists.txt文件中插入:
# 嵌入HTML文件
target_add_binary_data(${COMPONENT_LIB} "web/index.html" TEXT)
ESP-IDF工具链遵循固定的命名模式生成对应文件的起始和结束位置:
- 起始符号 :
_binary_<文件名>_start
- 结束符号 :
_binary_<文件名>_end
例如,对于index.html就变成了_binary_index_html_start
和_binary_index_html_end
。
使用
extern const uint8_t index_html_start[] asm("_binary_index_html_start");
extern const uint8_t index_html_end[] asm("_binary_index_html_end");
获取这两个位置。
然后就可以使用算术指针计算该数据块大小:
*size = index_html_end - index_html_start;
我们新定义一个get_embedded_index_html
函数
const uint8_t* get_embedded_index_html(size_t* size)
{if (size) {*size = index_html_end - index_html_start;}return index_html_start;
}
这个函数确保HTML文件已经正确的放进了固件中(因为size存在才不报错,而size存在就说明有这么个文件),并返回指向这个文件的指针。
这样,我们在主程序中就可以直接调用这个get_embedded_index_html
,也就直接获得了固件中的HTML文件数据,省去了再次缓存的麻烦。
HTML文件被存放进了flash当中,后续也可以使用OTA功能实现网页更新升级。