转自:https://www.jarviswang.me/?p=599
自2015年ESP32发布以后,官方号称很牛逼,关注度也挺高,但实际上呢,我们这些拿到芯片开发的第一批用户来说,也踩了不少坑,文档渣、例子少,生态相比传统大公司比如TI,ST之流还是有很大差距,这次打算移植wolfssl这个库到ESP32上也费了不少劲,过程顺便记录下方便大家参考。
wolfssl是一个轻量级的的SSL库,支持的协议还挺全的,比较适合嵌入式系统,而且使用起来比OpenSSL和mbedTLS简单多了。所以就打算在ESP32上移植这个ssl库。另外,ESP32上自带了OpenSSL和mbedTLS,如果仅仅是实现SSL功能,用这两个库已经足够,但是api用起来没有wolfssl那么简洁好用,所以个人还是更喜欢wolfssl这个库。
好了接下来开始吧,网上完全找不到类似的资料,在wolfssl论坛上有人尝试移植成功过,但是并没有放出方法以及源码,所以此时此刻只能自己尝试移植了。我这里移植用的是乐鑫官方的esp-idf模板库,arduino应该也大同小异。
ESP官方的esp-idf把组件也就是库放在components目录下,每个组件一个文件夹,在组件文件夹目录里会有一个component.mk文件,用于指定每个组件的include目录和源码目录。而整个工程的project.mk会搜索components目录下的每个目录,寻找component.mk来对每个组件进行编译。所以我们要把wolfssl源码放在components目录下。
首先,我们去wolfssl官网下载最新的源代码:
https://wolfssl.com/wolfSSL/download/downloadForm.php
然后,我们在components文件夹下新建wolfssl目录,然后把源码拷贝过来,目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
wolfssl目录下保持源码原来的结构即可,如图:
然后,在wolfssl目录下新建一个component.mk文件,内容如下:
1 2 3 4 5 6 7 |
|
为什么是这样我大概解释一下,如果有需要的可以看wolfssl官方的说明,wolfssl根目录下面看似有很多文件夹,但实际有用的只有这几个:
./wolfssl — 这个文件夹是wolfssl的所有头文件
./src — 这个是wolfssl功能代码
./wolfcrypt/src — 这个是wolfssl的所有加密算法源码实现
由于wolfssl的代码中对头文件的引用都是wolfssl/xxxx.h这种形式的,所以我们头文件包含的目录应该是wolfssl的根目录,所以我们COMPONENT_ADD_INCLUDEDIRS变量要设置为当前目录,才变成我的这种写法,另外由于esp-idf使用的系统是FreeRTOS,所以wolfssl也要结合FreeRTOS来编译,所以FreeRTOS的头文件目录也要加上。
这一步完成了之后,我们需要修改wolfssl/wolfcrypt/settings.h
大致修改如下几处:
一、反注释FREERTOS和WOLFSSL_LWIP宏定义,因为esp-idf使用的是FreeRTOS+lwip方式的系统+协议栈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
二、找到如下地方,添加一些宏定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
另外,由于esp-idf里的freeRTOS没有pvPortRealloc这个定义,但这个功能是已经实现的只是没封装,所以现在要自己去封装这个函数:
找到components/freertos/port.c,在vPortFree函数后面添加如下函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
然后找到components/freertos/include/freertos/portable.h
在vPortFree的定义后面添加pvPortRealloc的定义:
1 2 3 4 5 6 7 |
|
最后,由于wolfssl要正常工作还需要一个随机数发生器,默认使用的是/dev/urandom,但是FreeRTOS上面是没有这个io设备的,所以我们在前面有定义过NO_DEV_RANDOM,这时候我们需要自己实现随机数生成的函数,不过好在ESP32自带了硬件随机数发生器,所以写起来也比较简单:
修改wolfcrypt/src/random.c
找到如下位置,在wc_GenerateSeed函数里填上具体实现的代码,下面的代码是我的实现,你也可以自己实现,esp_random()函数一次能获得4个字节随机数,我直接只用最低字节,方便点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
完成这些步骤之后,我们编译esp-idf,这时候wolfssl库应该就能正常编译通过了,会在build/wolfssl目录下生成libwolfssl.a,这时候我们在自己编写app的时候就可以使用wolfssl相关的头文件了。
最后,如果app要引用wolfssl的话,编译到wolfssl的时候可能会报错找不到头文件,这时候就需要在app/main目录下的component.mk文件中添加如下行:
1 2 3 4 5 6 7 8 9 |
|
然后就可以正常使用wolfssl的函数了