# Software-Over-the-Air-based-on-Webdav **Repository Path**: hiyanyx/software-over-the-air-based-on-webdav ## Basic Information - **Project Name**: Software-Over-the-Air-based-on-Webdav - **Description**: 软件在线升级SOTA(Software-Over-the-Air),是在操作系统的基础上对应用程序进行升级,是指那些离用户更近的应用程序,UI界面和车载地图、人机交互界面等功能,像娱乐系统更新操作界面或主题。 本项目的目的是: 基于webdav技术,实现SOTA,用于智能驾驶领域的感知与建图软件的升级,不涉及固件升级。 Software-Over-the-Air-based-o - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-09-12 - **Last Updated**: 2023-09-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Software-Over-the-Air-based-on-Webdav #### 介绍 随着汽车行业已进入软件定义汽车的时代,对售后汽车售卖各种各样功能的新商业模式兴起,也要求汽车必须具备OTA功能。这里准确地说,OTA分为两类,一类是固件在线升级FOTA(Firmware-Over-the-Air),是指不改变车辆原有配件的前提下,通过写入新的固件程序,使拥有联网功能的设备进行升级,包括车辆的发动机,电机,变速箱,底盘等控制系统,比如特斯拉曾通过FOTA新增过自动驾驶功能、增加过电池容量和改善过刹车距离等。另一类是软件在线升级SOTA(Software-Over-the-Air),是在操作系统的基础上对应用程序进行升级,是指那些离用户更近的应用程序,UI界面和车载地图、人机交互界面等功能,像娱乐系统更新操作界面或主题。 本项目的目的是: - 基于webdav技术,实现SOTA,用于智能驾驶领域的感知与建图软件的升级,不涉及固件升级。 - **Software-Over-the-Air-based-on-Webdav** 是一个 跨平台的,基于cmake工具的,C++17空项目。 #### 支持的平台 - **Win10** - **MacOSX** (10.12 或更高版本) - **Ubuntu** (18.04 或更高版本) 也许还能支持各个平台的较早版本,但我尚未测试。 #### 支持哪款编译器 **Clang** 是最推荐的编译器,即便是在 **Win10** 平台。 请确保你所下载和安装的 **Clang** 版本,支持 **C++17**。 #### 软件架构 软件架构说明 1、SOTA 服务器使用支持webdav协议的均可。例如,安装被广泛使用的 nextcloud 云盘。 2、该项目为客户端的实现。 3、客户端首先获取SOTA服务器的 update_index.xml文件,然后解析xml文件得到需要下载的文件列表进行下载。 4、xml的格式如下. - ````为必须字段,为版本号 - ````为必须字段。子成员````为必须成员,为需要下载的文件名字,例如需要升级更新的程序文件、执行脚本。 ``` 21 temp.zip 0 20211020 1 zip 0 0 0 0 temp2.zip 0 20211020 1 zip 0 0 0 0 ``` ![struct.png](Docs/pngs/struct.png) #### 必须使用的库 1. neon-0.32.1 #### 使用说明 运行一份 shell 脚本程序: $ ./unix_release.sh 脚本 `unix_release.sh` 将会自动化地帮我们完成程序的 **build** 和本地化部署工作。 你也可以选择运行另一份脚本:`unix_debug.sh`, 正如名字所示,它将生存一份 **DEBUG** 版的程序。 现在,所有的安装工作都已经 **完成**!!! 你可以在目录: **.../appRootDir/build/publish/** 中找到可执行文件:**emptyApp**。 (**注意**,此处的 "appRootDir" 应替换为实际的根目录名字) 在 **终端** 中启动它: $ build/publish/emptyApp 运行我们的程序!!! #### 参与贡献 1. 如何添加 C++ 代码文件(.h/.hpp/.c/.cpp) ##### .c/.cpp 文件 请将所有 C++ 代码文件,放入 `.../appRootDir/src/` 目录(或其递归子目录)下。 - 目录:`main` 放置程序的主文件 `main.cpp` - 目录:`_pch_` 放置一个加速编译效率的文件 `pch.h`(下文会提及) - 目录:`debug` 放置一个推荐的 终端打印函数 **debug::log()**, 用来代替 `std::iostream` - 目录:`classA` 放置一组示范用 class 代码 原则上,你可以在目录 `src` 下创建任意 子目录(递归)或文件。在目前的 cmake 设置中,所以位于目录 `src` (及其递归子目录)下的 **.c/.cpp**, 都会被自动查找到并编译,如文件 `CMakeLists.txt` 中所写. ##### .h/.hpp 文件 与 `.c/.cpp` 文件一致, `.h/.hpp` 文件也请全部放到 `src/` 目录(或其递归子目录)中。一种推荐的做法是:**将同一个模块的代码文件,放在同一个目录下**。 我们已经在 `CMakeLists.txt` 下准备了一个宏函数 `collect_head_dirs`, 它将自动遍历 `src/` 及其所有递归子目录。如果某个目录内含 `.h/.hpp` 文件,这个目录就会被收集到一个 `list` 中。最后,这个 `list` 会被自动添加进 **include路径列表**。 所以,当你在 `src/` 或其递归子目录 下的任何位置添加 `.h/.hpp` 文件时,你不需要对 cmake 配置文件做任何修改。cmake 会自动帮你处理好一切。 比方说,当你在目录 `.../src/a/b/c/` 下,新建一个文件 `koko.h` 时。 那么你就能在 `src/` 目录下的任一代码文件内,inlcude 到它: #include "koko.h" 而不是需要繁琐地写为: #include "a/b/c/koko.h" 当然,这种实现存在一个代价,就是要求你在 `src/` 目录下创建的所有 `.h/.hpp` 文件,都不能重名。 最后,如果你不喜欢这种实现,你可以在 `CMakeLists.txt` 中放弃这个 宏函数 的使用,通过手动添加 include 路径的方式,来精细化地管理 **include路径列表**。具体方法请搜索 cmake: `target_include_directories` 的使用。 ##### 项目构建规则 我们使用 cmake 工具自动编译和构建项目。最终,项目的可执行目录,就是 `.../appRootDir/build/publish/`。 在编译构建完毕后,你可以将这个 `publish` 目录,复制到电脑中的任意位置,都不会影响程序的运行。 目录 `publish/` 下的 `emptyApp/emptyApp.exe` 文件,就是程序的可执行文件。 程序所依赖的一切附加数据,比如 shaders,jsons,pngs,都将在构建过程中,被复制到 `publish/` 目录下。在 Mac/Linux 中,这个复制操作是由 脚本程序 `unix_release.sh, unix_debug.sh` 实现的。在 win10 中,这个复制操作是由 `win.bat` 实现的。整个操作也很简单,就是将 根目录下的 一些文件夹(及其体内的所有文件)复制进 `publish/` 目录下。(在目前的示例中,我已经在根目录放入两个空目录:`jsons/, shaders/`, 以此来示范整个复制效果。当你成功编译构建项目后,你会在 `publish/` 目录下,看到这两个 空目录 ) #### 特技 ##### 如何在代码层实现跨平台 最简单的跨平台方式就是: 让代码检查一组宏,从而得知,自己当前正运行在哪个平台。然后根据这层判断,跳入不同的分支,执行对应的代码。 那么这组宏是从哪里来的呢?一个方式是,在项目编译阶段,由 cmake 工具写入某个 .h文件: 在根目录中,我们会找到一个名为 `sysconfig/` 的目录。它的体内包含一个名为 `SysConfig.h.in` 的文件。这个文件就是提供给 cmake,用来生成平台相关信息 用的。在编译阶段中,cmake 会根据当前平台信息,在目录 `.../publish/sysconfig/` 中,自动创建一个文件 `SysConfig.h`,并且: - 如果当前处于 Mac 系统,这个.h文件中 会生成宏:TPR_OS_MACOSX_ - 如果当前处于 Linux 系统,这个.h文件中 会生成宏:TPR_OS_LINUX_ - 如果当前处于 win 系统,这个.h文件中 会生成宏:TPR_OS_WIN32_ 通过这个机制,你可以在自己的程序代码中,先 `#include "SysConfig.h"`,然后检查是否存在某个宏,来确定自己所处的 操作系统类型。对于那些跨平台的,且依赖平台API 的代码来说,这会是个有用的功能。 ##### pch.h 到底是什么 我们注意到,我在 `src/` 目录下放置了个 `_pch_/pch.h` 文件。并且,它还被写进了 `CMakeLists.txt` 中: target_precompile_headers( emptyApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/_pch_/pch.h ) 这其实是借用了一个 cmake 3.16 以来支持的新功能:**Precompiled headers (PCH) 预编译头文件**。通俗地讲,如果有一组 `.h`文件,使用频率特别高,比如标准库的那些头文件,那你可以把这些头文件写入这个 `pch.h` 文件中。然后,当 cmake 开启相应功能后,将会在编译阶段,预先将这组 **头文件** 编译成一个 **中间件**,然后把这个 **中间件**, 自动添加进你的每一个 `.cpp` 文件中(是的,你什么都不用做)最终的目的就是 加快编译速度。 当然,如果你安装的 cmake 尚未达到 3.16, 这个功能并不会被触发。所以,保险起见,你也可以手动将 `#include "pch.h"` 这句话写到每个 .cpp 文件头部。 **pch** 文件的使用还有其它注意事项,推荐阅读 [**这篇文章**](https://onqtam.com/programming/2019-12-20-pch-unity-cmake-3-16/) 当然,你也有权彻底不用这个功能... ##### Unity Build 在上面推荐的文章中,还介绍了 cmake 3.16 以来的另一个新功能:**Unity Build**。简单说,它也是用来加快编译速度的。 我已经将这部分代码写入 `CMakeLists.txt` 文件中,你将自动获得这个加速功能。 当然,如果你安装的 cmake 尚未达到 3.16, 这个功能也是不会被触发的... ##### debug::log(); 在 main()函数中,我们发现一个奇怪的 打印函数:`debug::log();` 这是我在整个空项目中,**唯一夹带的私货~** 这个函数被定义在 `.../src/debug/` 目录下。通过使用一组类似 **python** 语法的 **格式化参数** 来将信息打印到 命令行终端(console)。这组参数的规则与 第三方库 **fmt** 一致。感兴趣的可以学习 **fmt** 的使用:[fmt](https://fmt.dev/latest/index.html) 通俗地讲,就是用这个 `debug::log();`,来代替标准库中 `std::cout<<"koko"<