Dronebridge-基于ESP32的廉价数字遥测
这篇文章主要是写一下在ESP32这里的实现,因为是IDF下开发的,所以需要下载一下SDK.
代码语言:javascript复制https://github.com/espressif/esp-idf
SDK支持的芯片SDK
下载解压,没毛病
这个是项目里面的main函数
因为实现了断电存储这个功能,所以第一步一定是关于这个已经存储的参数读取。在ESP32,使用非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。
第一个注解直接在代码中就有了显示
NVS 库在其操作中主要使用两个实体:页面和条目。页面是一个逻辑结构,用于存储部分的整体日志。逻辑页面对应 flash 的一个物理扇区,正在使用中的页面具有与之相关联的序列号。序列号赋予了页面顺序,较高的序列号对应较晚创建的页面。页面有以下几种状态:
空或未初始化
页面对应的 flash 扇区为空白状态(所有字节均为 0xff)。此时,页面未存储任何数据且没有关联的序列号。
活跃状态
此时 flash 已完成初始化,页头部写入 flash,页面已具备有效序列号。页面中存在一些空条目,可写入数据。任意时刻,至多有一个页面处于活跃状态。
写满状态
Flash 已写满键值对,状态不再改变。用户无法向写满状态下的页面写入新键值对,但仍可将一些键值对标记为已擦除。
擦除状态
未擦除的键值对将移至其他页面,以便擦除当前页面。这一状态仅为暂时性状态,即 API 调用返回时,页面应脱离这一状态。如果设备突然断电,下次开机时,设备将继续把未擦除的键值对移至其他页面,并继续擦除当前页面。
损坏状态
页头部包含无效数据,无法进一步解析该页面中的数据,因此之前写入该页面的所有条目均无法访问。相应的 flash 扇区并不会被立即擦除,而是与其他处于未初始化状态的扇区一起等待后续使用。这一状态可能对调试有用。
main参数在此
这个是esp_err_t的封装定义
其中NVS 分区不包含任何空页。如果 NVS 分区被截断,则可能会发生这种情况。擦除整个分区并再次调用 nvs_flash_init。
初始化函数
意思是我先看看flash这块初始化的情况,如果没有任何空页就重新擦除
ESP_ERR_NVS_NO_FREE_PAGES :如果 NVS 存储不包含空页(如果 NVS 分区被截断,可能会发生这种情况)
就是这样
函数的定义
我们接下来看这个读取设置的函数
在一开始看见的句柄:
句柄就好像你炒菜使用的锅把,你其实是操作了锅把,但是你对锅有了影响
先出现了open函数,从默认 NVS 分区打开具有给定命名空间的非易失性存储。
参数
代码语言:javascript复制esp_err_tnvs_open
(const char *name,
nvs_open_mode_topen_mode,
nvs_handle_t *out_handle)
第一个参数
第二个
返回值
- 先关
- 后擦
- 在初始化
- 在写入
在代码里面频繁出现这个宏
定义在此。里面使用了一个函数
看不清了?
里面其实最终执行的是这个函数
真的,无底洞
一开始会打印详细的配置信息
下面就是写入配置了
看一个字符串
其他的一样
再看main,在你打开成功的情况下,写入设置,否则就是else了
也就是读取设置
这些函数都是ESP自己实现的:它们包含 malloc() 和 realloc() 实现的业务逻辑。因为堆跟踪 包装原因,我们不希望这些成为公共 api,但是,因此它们没有公开定义。
上面的代码,在末尾的进行扫尾的工作
接着是日志等级的设置
函数的定义
最后是传入一个结构体
这个是WiFi的init函数,先初始化一下底层的协议栈,这些东西没有什么地方教你,就自己研究吧,这里有个有趣的写法就是,每一个函数使用CHECK来包裹,会及时告知编程者函数的执行情况。之后局部的创建一个循环的时间,接着创建一个默认的AP,也就是热点,下面我应该有函数的截图。然后就是WiFi默认的所有参数,在下面也有,之后使用init_config来重新将数据重塑。
将初始化的参数给这个函数来开启WiFi
之后为事件注册一个循环
初始化函数底层协议
创建的事件循环
WIFI的两种模式
一个IP的配置文件,IP, 网络掩码
这个是AP的配置
简单的追一下,就可以知道这个东西的具体意思
反正我也没有啥事情干,就继续追,还可以看见支持的WiFi加密模式
SoftAP的成对密码,群密码将用此导出。密码值从 WIFI _ CYPER _ TYPE _ TK IP 开始有效,之前的枚举值将被视为无效,将使用默认密码套件( TK IP CCMP )。在软 AP 模式下,有效的密码套件是 WIFI _ CYPER _ TYPE _ TK IP 、 Wifi _ CIFIER _ PYPY _ CKIP _ CCKMP 和 WIFi _ CEPIR _ Type _ TC IP _ CCMP
先记住我们这里几个提前写好有意义的东西
这个函数其实你查IDF是没有的
memcpy() 用来复制内存,其原型为:
void * memcpy ( void * dest, const void * src, size_t num );
memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。
memcpy() 并不关心被复制的数据类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据类型进行复制。
wifi的接口模式
下面就开始设置WiFi的模式,很简单
WiFi在不同的国家里面对功率的要求是不一样的,这里是写了这个
就像这样
传入后开启WiFi
memset是计算机中C/C 语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。
看这个代码
把这个写入
后面这个DHCP啥的都设置一下
就是纯互联网了
看在文档的位置
接下来是开启mDNS服务
mdns 即多播dns(Multicast DNS),mDNS主要实现了在没有传统DNS服务器的情况下使局域网内的主机实现相互发现和通信,使用的端口为5353,遵从dns协议,使用现有的DNS信息结构、名语法和资源记录类型。并且没有指定新的操作代码或响应代码。在局域网中,设备和设备之前相互通信需要知道对方的ip地址的,大多数情况,设备的ip不是静态ip地址,而是通过dhcp协议动态分配的ip 地址,如何设备发现呢,就是要mdns大显身手,例如:现在物联网设备和app之间的通信,要么app通过广播,要么通过组播,发一些特定信息,感兴趣设备应答,实现局域网设备的发现,当然mdns 比这强大。
目前为止,2222个字了
看这几个函数
我们的文件系统的初始化,个人认为是web网页
这个是文件系统的结构体
具体的意思
这是防御性的代码,确保文件系统就是可以使用
最后的函数
这个写法和上面一样
ESP32 设备的控制模块实现。FC 和地面之间的双向链路。能处理 MSPv1、MSPv2、LTM 和 MAVLink。MSP & LTM 被解析并逐帧发送到地面。MAVLink 通过(完全透明)。可以与任何协议一起使用。
但是这个任务好复杂。。。
看看这个头是啥?
C99新增inline关键字时,它时唯一的函数说明符(关键字extern和static时存储类别说明符,可应用于数据对象和函数)。C11新增了第二个函数说明符_Noreturn,表明调用完成后函数不返回主调函数。exit()函数时_Noreturn函数的一个示例,一旦调用exit()它不会再返回主调函数。注意,这与void返回类型不同。void类型的函数再执行完毕后返回主调函数,只是它不提供返回值。
_Noreturn的目的是告诉用户和编译器,这个特殊的函数不会把控制返回主调程序,告诉用于以免滥用该函数,通知编译器可优化一些代码。
这个任务里面写了串口和TCP
写入的参数
8位
校验
停止码
硬件流控
看看串口
结构体的配置
串口2
这个是IO配置
具体的使用
定义可以自己改
安装一个串行口的驱动程序
安装 UART 驱动程序并将 UART 设置为默认配置。UART ISR 处理程序将附加到运行此函数的同一 CPU 内核。
就这样
后面还要看看这个串口到底是不是可以使用的。如果不行就把驱动卸载,,抛出错误。
没有小错误就可以使用了
函数在此
TCP看不懂了。。。上面这些应该是初始化的参数
建立一个入口
<0的时候是跑错误
bind我忘了,好像是什么端口也重要
最后是监听的口,反正都没有错就会返回一个正确的IP和Port
。。。写不下去了,函数太长了,我知道也没有人看到这里,我明天考虑要不要把剩下的任务写了、
不过在文章的末尾我还是要骂,金鹏太拉了,凭什么我的行李就得托运,气死我了,为啥深圳航空就可以,我的300米就没了。
临下飞机,我还以为碰上密接了,突然就不让动了,你再看这个图
远一点看,像不像大夫在等着拉人
代码语言:javascript复制https://github.com/orgs/espressif/repositories