转自: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

.

├── build

├── components

│   │

│   │      ...

│   ├── wolfssl

│   │

│          ...

├── main

│   ...

├── Makefile

├── README.md

├── sdkconfig

└── sdkconfig.old

wolfssl目录下保持源码原来的结构即可,如图:

然后,在wolfssl目录下新建一个component.mk文件,内容如下:

?

1

2

3

4

5

6

7

#

# Component Makefile

#

COMPONENT_ADD_INCLUDEDIRS := ../wolfssl

COMPONENT_PRIV_INCLUDEDIRS := ../freertos/include/freertos

COMPONENT_SRCDIRS := src wolfcrypt/src

为什么是这样我大概解释一下,如果有需要的可以看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

...

/* Uncomment next line if using PIC32MZ Crypto Engine */

/* #define WOLFSSL_MICROCHIP_PIC32MZ */

/* Uncomment next line if using FreeRTOS */

 #define FREERTOS

/* Uncomment next line if using FreeRTOS+ TCP */

/* #define FREERTOS_TCP */

/* Uncomment next line if using FreeRTOS Windows Simulator */

/* #define FREERTOS_WINSIM */

/* Uncomment next line if using RTIP */

/* #define EBSNET */

/* Uncomment next line if using lwip */

 #define WOLFSSL_LWIP

/* Uncomment next line if building wolfSSL for a game console */

/* #define WOLFSSL_GAME_BUILD */

...

二、找到如下地方,添加一些宏定义:

?

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

...

#ifdef FREERTOS

    #include "FreeRTOS.h"

    /* FreeRTOS pvPortRealloc() only in AVR32_UC3 port */

    #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY)

        #define XMALLOC(s, h, type)  pvPortMalloc((s))

        #define XFREE(p, h, type)    vPortFree((p))

        //新增如下一行:

        #define XREALLOC(p, n, h, type) pvPortRealloc((p), (n))

    #endif

    #ifndef NO_WRITEV

        #define NO_WRITEV

    #endif

    #ifndef HAVE_SHA512

        #ifndef NO_SHA512

            #define NO_SHA512

        #endif

    #endif

    #ifndef HAVE_DH

        #ifndef NO_DH

            #define NO_DH

        #endif

    #endif

    #ifndef NO_DSA

        #define NO_DSA

    #endif

    #ifndef NO_HC128

        #define NO_HC128

    #endif

    #ifndef SINGLE_THREADED

        #include "semphr.h"

    #endif

    //新增下面的宏定义:

    #ifndef HAVE_ECC

        #define HAVE_ECC

    #endif

    #define WOLFSSL_DTLS

    #define HAVE_SOCKADDR

    #define DEBUG_WOLFSSL

    #define NO_DEV_RANDOM

    #include "esp_system.h"

#endif

...

另外,由于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

...

void *pvPortMalloc( size_t xWantedSize )

{

    return heap_caps_malloc(xWantedSize, MALLOC_CAP_8BIT);

}

void vPortFree( void *pv )

{

    return heap_caps_free(pv);

}

//添加如下内容:

void *pvPortRealloc( void *pv, size_t size )

{

    return heap_caps_realloc(pv, size,MALLOC_CAP_8BIT);

}

...

然后找到components/freertos/include/freertos/portable.h
在vPortFree的定义后面添加pvPortRealloc的定义:

?

1

2

3

4

5

6

7

...

void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;

void vPortFree( void *pv ) PRIVILEGED_FUNCTION;

//添加如下一行:

void *pvPortRealloc( void *pv, size_t size ) PRIVILEGED_FUNCTION;

void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;

...

最后,由于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

...

#elif defined(NO_DEV_RANDOM)

    //#error "you need to write an os specific wc_GenerateSeed() here"

    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)

    {

        for (int i=0;i<sz;i++)

            output[i] = esp_random()&0xFF;

        return 0;

    }

...

完成这些步骤之后,我们编译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

#

# Main component makefile.

#

# This Makefile can be left empty. By default, it will take the sources in the

# src/ directory, compile them and link them into lib(subdirectory_name).a

# in the build directory. This behaviour is entirely configurable,

# please read the ESP-IDF documents if you need to do this.

#

COMPONENT_PRIV_INCLUDEDIRS := ../../components/freertos/include/freertos ../../components/wolfssl

然后就可以正常使用wolfssl的函数了

ESP32移植wolfssl方法相关推荐

  1. 乐鑫ESP32移植LVGL 7.10

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  2. ffmpeg移植Android方法以及常见问题汇总

    ffmpeg移植Android方法以及常见问题汇总: 1.在ffmpeg官网下载源码包,比如ffmpeg-2.3.在ffmpeg目录下增加Android.mk 和av.mk config.sh三个文件 ...

  3. 燃起来 ESP32移植LVGL最新版本8.2

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  4. arduino tft 方向_ESP32在Arduino环境下玩转 LVGL,ESP32移植LVGL详细教程

    微信关注 "DLGG创客DIY"设为"星标",重磅干货,第一时间送达. ❝ 转载自慕容流年 https://me.csdn.net/qq_41868901 ❞ ...

  5. Arduino ESP32 通过getString方法获取网络时间和气象数据

    Arduino ESP32-通过getString方法获取网络时间和气象数据 国家气象数据API接口:http://www.weather.com.cn/data/sk/101010100.html ...

  6. linux mysql移植_linux 下mysql 移植设置方法

    环境: db01:10.10.10.101 db03:10.10.10.103 需求: 将db01上mysql做完整移植,迁移到db03 详细步骤: 1. 打包db01上/app目录并scp到db03 ...

  7. stm32代码移植的方法

    这里以stm32f103zet6移植到stm32f103c8t6为例: 1.点开魔术棒–>device中修改芯片型号为stm32f103c8t6 2.点击编译 会提示有一大堆错误和警告 点击第一 ...

  8. 基于芯科Host-NCP解决方案的Zigbee 3.0 Gateway技术研究(三)-移植到ESP32平台(1)

    相关系列文章 基于芯科Host-NCP解决方案的Zigbee 3.0 Gateway技术研究(-)-Z3GatewayHost应用搭建 基于芯科Host-NCP解决方案的Zigbee 3.0 Gate ...

  9. memtester4.3.0 方法与 ARM A53 移植

    Overview 前言 详解函数 memtester-4.3.0 版本 方法test_stuck_address 目的(原理) 时间花销 ARM A53移植版本 方法test_random_value ...

最新文章

  1. 物理学家发现粒子是如何自我组装的
  2. VS2008环境下CEGUI 0.7.1及相关工具的编译(转载 + 额外的注意事项)
  3. OpenCV结合socket进行实时视频传输(TCP协议)
  4. [嵌入式][分享][交流]发布一个消息地图的模块
  5. 如何导入任何JBoss BRMS示例项目
  6. 1月25日再次开抢!三星Galaxy S21系列标准版已多次开售即罄
  7. 河南农业大学计算机试题,河南农业大学计算机vb考试必出
  8. 你可能还不知道的关于JavaScript类型的细节?
  9. dp4--codeVs1043 方格取数
  10. AWK学习笔记五:可执行AWK程序
  11. 天然气阶梯是按年还是按月_您搞懂了吗?阶梯电费是按年计算而不是按月计算的...
  12. WordPress站点上传文件插件WordPress File Upload
  13. 盒式滤波器BoxFilter
  14. Hibernate5使用c3p0一些小问题及注意
  15. 清明祭娭毑_原水_新浪博客
  16. matlab批量将mp3文件转wav文件
  17. 全民一起VBA提高篇 第三十二回 Select 简化分枝结构,静态变量坐看沧海桑田
  18. Java面向对象之类和封装
  19. [20190328]PPT中的png图片去底色(透明化)
  20. 百度云盘功能需求分析

热门文章

  1. 一个可以设置中奖概率的抽奖程序[转]
  2. 并查集(disjoint set)的实现及应用
  3. 31.绿豆蛙的归宿(拓扑排序)
  4. SQL Server创建存储过程
  5. iOS经常使用加密方式(MD5,AES,BASE64)与网络数据安全
  6. 标准访问控制列表配置(51cto: 实验 34)
  7. 神经网络的迭代次数和收敛误差与谐振子的位移和时间
  8. 神经网络的输入对迭代次数的影响
  9. 参数整定临界比例度实验_PID控制及参数调节,你真的懂了吗?
  10. 【控制】滑动模式观测器 sliding mode observer