├── .gitmodules ├── Makefile ├── README.md ├── docs ├── config_network_guide.pdf └── readme_image │ ├── alink_advantage.png │ ├── alink_description.png │ ├── alink_development.png │ ├── device_id.png │ ├── download.png │ └── running.png ├── gen_misc.sh ├── main ├── alink_key_trigger.c ├── app_main.c └── component.mk ├── sdkconfig └── tools ├── FLASH_DOWNLOAD_TOOLS_V3.6.2_ID.tar.gz ├── check_log.sh ├── format.sh ├── idf_monitor.py └── setup_toolchain.sh /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "esp-idf"] 2 | path = esp-idf 3 | url = https://github.com/espressif/esp-idf.git 4 | [submodule "components/esp32-alink"] 5 | path = components/esp32-alink 6 | url = https://github.com/espressif/esp32-alink.git 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := alink 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本工程为阿里云 ESP32 ALINK 接口使用示例,你可以通过本示例了解 ALINK 配网、升级及数据传输等 2 | 3 | ## 1 ALINK 概述 4 | ### 1.1 是什么 ALINK 5 | 智能硬件模组、阿里智能云、阿里智能 APP,阿里智能生活事业部为厂商提供一站式设备智能化解决方案。alink 到目前已经过了多次的版本迭代,各版本的区别如下: 6 | 7 | 1. alink v1.0:为阿里提供最基础的版本,支持一键配网,设备热点配网技术,ota 升级等功能 8 | 2. alink v1.1:增强设备身份安全 9 | 3. alink embed:增加支持零配发现模式,默认配网激活模式,手机热点配网模式,但需要占更多的内存空间 10 | 4. alink sds:APP和服务端允许客户定制化,但是需要收取服务收费 11 | 12 | > 注: 13 | 1. 本工程目前支持的版本的 alink embed 和 alink sds,您可以通过 `make menuconfig` 进行版本切换 14 | 2. alink embed 和 alink sds 的版本,目前不支持数据透传 15 | 16 | 17 | 18 | ### 1.2 为什么要使用 ALINK 19 | 阿里智能开发平台的提供强大的智能平台,极大的简化的智能家居开发的高难度和复杂性,主要有以下六个特点:低成本、短时间、大安全、大数据、标准化和定制化等。 20 | 21 | 22 | ### 1.3 怎么使用 ALINK 23 | 我们已经完成 ALINK EMBED SDK 在模组上的适配工作,您在 产品开发时,只需基于模组基础上进行二次开发。 24 | 25 | 26 | ## 2 前置条件 27 | ### 2.1 知识储备 28 | 1. 了解 ALINK 29 | 请详细阅读阿里提供的官方[技术文档](https://open.aliplus.com/docs/open/),了解 ALINK 相关的概念 30 | 2. 熟悉 ESP32 开发 31 | 请详细阅读 [ESP32-DevKitC 入门指南](http://www.espressif.com/sites/default/files/documentation/esp32-devkitc_getting_started_guide_cn.pdf) 及 [ESP-IDF 入门指南](http://www.espressif.com/sites/default/files/documentation/esp-idf_getting_started_guide_cn.pdf) 32 | 33 | ### 2.2 硬件准备 34 | 1. 开发板:二块以上 ESP32-DevKitC 开发板(测试零配网功能至少需要两块开发板) 35 | 2. 路由器:关闭 5G 网络,且可以连接外网(所有的数据交互必需通过阿里云服务器) 36 | 3. 手机:内置有 SIM 卡,可连接 4G 移动网络(测试热点配网功能时,设备需要通过手机热点连接阿里云服务器完成的注册、绑定等过程) 37 | 38 | ## 3 开发板介绍 39 | 40 | 41 | | 接口/模块 | 说明 | 42 | | -------- | :----- | 43 | | ESP-WROOM-32 | ESP-WROOM-32 模组 | 44 | | EN | 复位按键。按下此轻触开关,系统复位 | 45 | | Boot | 下载键,按下此按键,然后再按下EN按键,系统进入下载模式,通过串口对flash进行下载 | 46 | | USB | USB接口,既为开发板提供电源,以作为通信接口连接 PC 与 ESP-WROOM-32 模组 | 47 | | IO | 扩展了 ESP-WROOM-32 的大部分引脚 | 48 | 49 | ## 4 文件结构 50 | 51 | esp32-alink-embed-demo 52 | ├── bin // 存放生成的 bin 文件 53 | ├── build // 存放所有编译生成的文件 54 | ├── components 55 | │ └── esp32-alink_embed // ALINK 适配文件 56 | │   ├── adaptation // ALINK 的底层适配 57 | │   ├── application // ALINK 应用层API的封装 58 | │   │   ├── esp_alink_main.c // 连接ap、恢复出厂设置、事件回调函数 59 | │   │   ├── esp_data_transport.c // ALINK 数据传传输 60 | │   │   ├── esp_info_store.c // FLASH 的读写操作 61 | │   │   └── esp_json_parser.c // JSON 字符串的生成与解析 62 | │   ├── component.mk 63 | │   ├── include 64 | │   │   ├── alink_export.h // ALINK 官方提供的原生应用层 API 65 | │   │   ├── alink_json_parser.h // ALINK 官方提供的原生JSON API 66 | │   │   ├── esp_alink.h // 封装的应用层API使用说明及配置 67 | │   │   ├── esp_alink_log.h // 定义了打印等级 68 | │   │   ├── esp_info_store.h // 信息存储API详解 69 | │   │   └── esp_json_parser.h // JSON API详解 70 | │   ├── Kconfig // make menuconfig 配置文件 71 | │   ├── lib // 库文件 72 | │   └── README.md 73 | ├── device_id // 存放 ALINK SDS 的设备 ID 74 | ├── esp-idf // ESP32 SDK 75 | ├── gen_misc.sh // 编译脚本 76 | ├── main 77 | │ ├── alink_key_trigger.c // 按键触发函数 78 | │ ├── component.mk 79 | │ └── app_main.c // ALINK 非透传示例 80 | ├── Makefile 81 | ├── README.md 82 | ├── sdkconfig // 保存配置选项 83 | └── setup_toolchain.sh // 编译环境的搭建脚本 84 | 85 | ## 5 编译环境的搭建 86 | 87 | 如果您是在 ubuntu x64bit 的平台下开发只需运行脚本 `setup_toolchain.sh`,一键完成开发环境的搭建。若是其他平台请参见:http://esp-idf.readthedocs.io/en/latest/get-started/linux-setup.html 88 | 89 | ```bash 90 | #!/bin/bash 91 | set -e 92 | 93 | # 安装软件 94 | sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial 95 | 96 | # 下载工具链 97 | mkdir -p ~/esp 98 | cd ~/esp 99 | wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz 100 | tar -xzf xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz 101 | 102 | # 配置环境变量 103 | echo 'export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin' >> ~/.profile 104 | source ~/.profile 105 | ``` 106 | 107 | ## 6 配置 108 | ESP32 ALINK 的默认配置已经存储在 sdkconfig, 如果你想要详细了解esp32相关配置与编译详见 esp-idf/README.md 109 | 110 | ### 6.1 ESP-IDF 配置 111 | - 禁用硬件 SHA:Component config->mbedTLS->SHA 112 | - 使能 SO_REUSEADDR:Component config->LWIP->Enable SO_REUSEADDR option 113 | - 配置分区表:Partition Table->Factory app, two OTA definitions 114 | 115 | ### 6.2 ALINK 配置 116 | 使用 `make menuconfig->Component config->Enable alink EMBED function` 配置日志等级,数据传输模式、任务优先级等,推荐使用默认值。 117 | ```Makefile 118 | --- Enable alink_embed function 119 | 120 | Select the version of alink (esp32 alink sds) ---> 121 | 122 | [ ] Remove the buffer space for reporting data 123 | (60) the connection router maximum latency unit is seconds 124 | (6) Configure the priority of all alink tasks 125 | 126 | (4096) Event callback function stack space 127 | (4096) The size of the task of reporting data to Ali 128 | 129 | (3) The number of buffered data received 130 | (3) The number of buffered data send 131 | 132 | (2048) The maximum length of the transmitted data 133 | 134 | (esp32) The name of the chip 135 | (ESP-WROOM-32) The name of the module 136 | 137 | Configure the alink application layer's log (Info) ---> 138 | 139 | Configure the alink sdk's log (Debug) ---> 140 | ``` 141 | 142 | ## 7 编译 143 | 如果您是在 ubuntu x64bit 的平台下开发只需运行脚本 `gen_misc.sh` 即可完成编译及固件烧录,其他平台的参见:http://esp-idf.readthedocs.io/en/latest/get-started/index.html#setup-toolchain 144 | ```bash 145 | ./gen_misc.sh 0 "8Rd98k3Ht0bxblf3TSf9,NrazMjfM9ta87HzqHEHXAaVa0glLb1Ym" 146 | ``` 147 | >>注:第一个参数为串口号,第二个参数为设备ID,embed 版本无需输入设备ID 148 | 149 | ## 8 固件烧录(windows) 150 | 1. 安装[串口驱动](http://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx) 151 | 2. 安装[烧写工具](http://espressif.com/sites/default/files/tools/flash_download_tools_v3.4.8_0.zip) 152 | 3. 烧录相关 bin 文件 153 | - ESP32_Core_board_V2 支持自动下载,按照如下所示,配置串口号、串口波特率等,按 `START` 即可开始下载程序。如果您使用的是 ALINK SDS 版,需向阿里官方购买设备ID, ALINK SDS 的每一个设备都需要一个唯一的设备ID,并将您购买的设备 ID 导成 csv 的格式放入 device_id 文件夹中下载工具将自动device_id.bin,您也可以自行创建一个`device_id.bin`文件,如下格式填入设备ID即可: 154 | 155 | ``` 156 | 8Rd98k3Ht0bxblf3TSf9,NrazMjfM9ta87HzqHEHXAaVa0glLb1Ym 157 | ``` 158 | 159 | 160 | 161 | 162 | ``` 163 | bootloader.bin------------->0x1000 // 启动程序 164 | partitions_two_ota.bin----->0x8000 // 分区表 165 | blank.bin------------------>0x9000 // nvs flash 数据区 166 | blank.bin------------------>0xd000 // ota 升级数据 167 | alink.bin------------------>0x10000 // 主程序 168 | device_id.bin-------------->0x310000 // alink embed 版本无需烧录设备ID 169 | ``` 170 | 171 | 172 | 4. 启动设备 173 | - 按下此轻触 EN 开关,系统复位,出现“ENTER SAMARTCONFIG MODE”信息,即表示 ALINK 程序正常运行,进入配网模式。 174 | 175 | 176 | ## 9 运行与调试 177 | 1. 下载APP: 178 | - ALINK EMBED: [接入阿里智能-厂测包](https://open.aliplus.com/download) 179 | - ALINK SDS: [独立开发者-DemoAPP](https://open.aliplus.com/download) 180 | 2. 登陆淘宝账号 181 | 3. 开启配网模组测试列表: 182 | - 安卓:点击“环境切换”,勾选“开启配网模组测试列表” 183 | - 苹果:点击“AKDebug”->测试选项,勾选“仅显示模组认证入口” 184 | 4. 添加设备:添加设备->“分类查找”中查找对应的类别->模组认证->V3 配网_热点配网(透传模式选择名称带LUA标识的),详见[《ALINK 配网指南》](docs/config_network_guide.pdf) 185 | 5. 按键说明: 186 | - 激活设备:单击 Boot 按键(<1s) 187 | - 重新配网:短按 Boot 按键(1~5s) 188 | - 出厂设置:长按 Boot 按键(>5s) 189 | - 高频压测:GPIO2 与 GND 短接重启 190 | 191 | ## 10 开发流程 192 | ### 10.1 [签约入驻](https://open.aliplus.com/docs/open/open/enter/index.html) 193 | 使用淘宝账号签约入驻阿里平台,并完成账号授权 194 | ### 10.2 [产品注册](https://open.aliplus.com/docs/open/open/register/index.html) 195 | 产品注册是设备上云的必要过程,任何一款产品在上云之前必须完成在平台的注册 196 | ### 10.3 [产品开发](https://open.aliplus.com/docs/open/open/develop/index.html) 197 | > 注:除非您有特殊需求,否则您在开发时只需修改 main 下的代码,无需关心其内部实现细节 198 | 199 | 1. **初始化** 200 | 201 | 202 | 阿里服务器后台导出设备 TRD 表格,调用`alink_init()`传入产品注册的信息,注册事件回调函数 203 | 204 | ```c 205 | #ifdef CONFIG_ALINK_VERSION_SDS 206 | const alink_product_t product_info = { 207 | .name = "alink_product", 208 | /*!< Product version number, ota upgrade need to be modified */ 209 | .version = "1.0.0", 210 | .model = "OPENALINK_LIVING_LIGHT_SDS_TEST", 211 | /*!< The Key-value pair used in the product */ 212 | .key = "1L6ueddLqnRORAQ2sGOL", 213 | .secret = "qfxCLoc1yXEk9aLdx5F74tl1pdxl0W0q7eYOvvuo", 214 | /*!< The Key-value pair used in the sandbox environment */ 215 | .key_sandbox = "", 216 | .secret_sandbox = "", 217 | }; 218 | #else 219 | const alink_product_t product_info = { 220 | .name = "alink_product", 221 | /*!< Product version number, ota upgrade need to be modified */ 222 | .version = "1.0.0", 223 | .model = "ALINKTEST_LIVING_LIGHT_ALINK_TEST", 224 | /*!< The Key-value pair used in the product */ 225 | .key = "5gPFl8G4GyFZ1fPWk20m", 226 | .secret = "ngthgTlZ65bX5LpViKIWNsDPhOf2As9ChnoL9gQb", 227 | /*!< The Key-value pair used in the sandbox environment */ 228 | .key_sandbox = "dpZZEpm9eBfqzK7yVeLq", 229 | .secret_sandbox = "THnfRRsU5vu6g6m9X6uFyAjUWflgZ0iyGjdEneKm", 230 | }; 231 | #endif 232 | 233 | ESP_ERROR_CHECK(alink_init(&product_info, alink_event_handler)); 234 | ``` 235 | 236 | 2. **配网** 237 | - 激活设备:在配网过程中设备需求很服务发送激活指令(具体指令内容由实际产品决定) 238 | - 主动上报:当设备成功连接到阿里云服务器时需要主动上报设备的状态,以保证云端数据与设备端同步,否则将无法配网成功 239 | - 事件回调函数:设备配网过程中的所有动作,都会传入事件回调函数中,您可以根据实际需求事件回调函数相应的做相应处理,如在当设备进入配置配网模式灯慢闪,等待激活时灯快闪等 240 | 241 | ```c 242 | typedef enum { 243 | ALINK_EVENT_CLOUD_CONNECTED = 0,/*!< ESP32 connected from alink cloude */ 244 | ALINK_EVENT_CLOUD_DISCONNECTED, /*!< ESP32 disconnected from alink cloude */ 245 | ALINK_EVENT_GET_DEVICE_DATA, /*!< Alink cloud requests data from the device */ 246 | ALINK_EVENT_SET_DEVICE_DATA, /*!< Alink cloud to send data to the device */ 247 | ALINK_EVENT_POST_CLOUD_DATA, /*!< The device sends data to alink cloud */ 248 | ALINK_EVENT_POST_CLOUD_DATA_FAIL, /*!< The device sends data to alink cloud fialed */ 249 | ALINK_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */ 250 | ALINK_EVENT_STA_DISCONNECTED, /*!< ESP32 station disconnected from AP */ 251 | ALINK_EVENT_CONFIG_NETWORK, /*!< The equipment enters the distribution mode */ 252 | ALINK_EVENT_UPDATE_ROUTER, /*!< Request to configure the router */ 253 | ALINK_EVENT_FACTORY_RESET, /*!< Request to restore factory settings */ 254 | ALINK_EVENT_ACTIVATE_DEVICE, /*!< Request activation device */ 255 | } alink_event_t; 256 | 257 | static alink_err_t alink_event_handler(alink_event_t event) 258 | { 259 | switch (event) { 260 | case ALINK_EVENT_CLOUD_CONNECTED: 261 | ALINK_LOGD("Alink cloud connected!"); 262 | proactive_report_data(); 263 | break; 264 | 265 | ....... 266 | ....... 267 | ....... 268 | 269 | case ALINK_EVENT_ACTIVATE_DEVICE: 270 | ALINK_LOGD("Requests activate device"); 271 | alink_activate_device(); 272 | break; 273 | 274 | default: 275 | break; 276 | } 277 | return ALINK_OK; 278 | } 279 | ``` 280 | > 注: 281 | > 1. 如果您需要传入自己定义的事件,可以通过调用 `alink_event_send()` 发送自定义事件 282 | > 2. 事件回调函数的栈默认大小为 4k, 请避免在事件回调函数使用较大的栈空间,如需修改请使用 `make menuconfig` 283 | 284 | 285 | 3. **修改触发方式** 286 | - 您需要根据实际产品,确定以何种方式触发出厂设置、重新配网、激活等操作,本示例使用的是按键触发方式,如果设备没有按键,您可以通过反复开关电源、通过蓝牙等方式触发,具体修改参见 `alink_key_trigger.c` 287 | 288 | ```c 289 | void alink_key_trigger(void *arg) 290 | { 291 | alink_err_t ret = 0; 292 | alink_key_init(ALINK_RESET_KEY_IO); 293 | for (;;) { 294 | ret = alink_key_scan(portMAX_DELAY); 295 | ALINK_ERROR_CHECK(ret != ALINK_OK, vTaskDelete(NULL), "alink_key_scan ret:%d", ret); 296 | 297 | switch (ret) { 298 | case ALINK_KEY_SHORT_PRESS: 299 | alink_event_send(ALINK_EVENT_ACTIVATE_DEVICE); 300 | break; 301 | 302 | case ALINK_KEY_MEDIUM_PRESS: 303 | alink_event_send(ALINK_EVENT_UPDATE_ROUTER); 304 | break; 305 | 306 | case ALINK_KEY_LONG_PRESS: 307 | alink_event_send(ALINK_EVENT_FACTORY_RESET); 308 | break; 309 | 310 | default: 311 | break; 312 | } 313 | } 314 | 315 | vTaskDelete(NULL); 316 | } 317 | ``` 318 | 319 | 4. **数据通信** 320 | - 数据格式:确认设备通信时的数据格式(透传/非透传),目前 ALINK EMBED 只支持非透传 321 | - 透传:设备端收到的二进制格式的数据。由阿里云端服务器的 lua 脚本完成 json 格式与二进制数据的转换 322 | - 非透传:设备端收到的 JSON 格式的数据,JSON 格式的转换由设备端完成,阿里云端服务器的 lua 脚本是空实现 323 | - 数据长度:默认长度为1KB,数据长度最大支持2k,如需修改请使用 `make menuconfig` 324 | - 数据上报:主动上报是由设备端主动发起 325 | - 数据下发:设备端收的到的数据有设置设备状态和获取设备状态组成 326 | 327 | 5. **底层开发** 328 | 设置 GPIO、UART 等外围设备,参见:http://esp-idf.readthedocs.io/en/latest/api-reference/peripherals/index.html 329 | 330 | ### 6.4 [发布上架](https://open.aliplus.com/docs/open/open/publish/index.html) 331 | 开发调试验证完成后就可以申请发布上架 332 | 333 | ## 11 注意事项 334 | - 请定期更新本项目工程,后期将有持续对本工程进行优化改进 335 | - 模组不支持 5G 网络,请确认已关闭路由器 5G 网络功能 336 | - 测试热点配网时,请确认 4G 网络处于开启状态 337 | - ALINK 受网络环境影响极大,进行测试时,请保证网络环境良好,否则将无法通过高频压测和稳定性测试。 338 | 339 | ## 12 Related links 340 | * ESP32概览 : http://www.espressif.com/en/products/hardware/esp32/overview 341 | * ESP32资料 : http://www.espressif.com/en/products/hardware/esp32/resources 342 | * 烧录工具 : http://espressif.com/en/support/download/other-tools 343 | * 串口驱动 : http://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx 344 | * 阿里智能开放平台:https://open.aliplus.com/docs/open/ 345 | -------------------------------------------------------------------------------- /docs/config_network_guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/config_network_guide.pdf -------------------------------------------------------------------------------- /docs/readme_image/alink_advantage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/alink_advantage.png -------------------------------------------------------------------------------- /docs/readme_image/alink_description.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/alink_description.png -------------------------------------------------------------------------------- /docs/readme_image/alink_development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/alink_development.png -------------------------------------------------------------------------------- /docs/readme_image/device_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/device_id.png -------------------------------------------------------------------------------- /docs/readme_image/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/download.png -------------------------------------------------------------------------------- /docs/readme_image/running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/docs/readme_image/running.png -------------------------------------------------------------------------------- /gen_misc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | export IDF_PATH=$(pwd)/esp-idf 5 | 6 | echo -e "\033[32m----------------------" 7 | echo "SDK_PATH: $IDF_PATH" 8 | echo -e "----------------------\033[00m" 9 | 10 | PROJECT_NAME=alink 11 | 12 | if [ ! -n "$1" ] ;then 13 | echo -e "\033[31m----------------------" 14 | echo "please enter the need to write the serial port number" 15 | echo "eg: ./gen_misc.sh 0" 16 | echo -e "----------------------\033[00m" 17 | exit 0 18 | fi 19 | 20 | alink_submodule=`ls -A components/esp32-alink|wc -w` 21 | if [ "$alink_submodule" -le 1 ];then 22 | git submodule update --init --recursive 23 | fi 24 | 25 | if [ ! -d "bin" ]; then 26 | mkdir bin 27 | fi 28 | 29 | if [ ! -d "serial_log" ]; then 30 | mkdir serial_log 31 | fi 32 | 33 | if [ ! -d "device_id" ]; then 34 | mkdir device_id 35 | fi 36 | 37 | make clean 38 | make -j8 39 | 40 | # copy bin 41 | echo -e "\033[32m----------------------" 42 | echo "the esptool.py copy to bin " 43 | echo "the alink.bin copy to bin " 44 | echo "the bootloader_bin copy to bin" 45 | echo "the partitions_two_ota.bin copy to bin" 46 | echo "the alink.elf copy to bin" 47 | echo -e "----------------------\033[00m" 48 | cp esp-idf/components/esptool_py/esptool/esptool.py bin 49 | cp build/bootloader/bootloader.bin bin 50 | cp build/partitions_two_ota.bin bin 51 | cp build/*.bin bin/ 52 | cp build/*.elf bin 53 | cp build/*.map bin 54 | cp tools/idf_monitor.py bin 55 | 56 | cd bin 57 | 58 | if [ ! -f "blank.bin" ]; then 59 | touch blank.bin 60 | for((i=0;i<4*1024;i++)) 61 | do 62 | echo -e '\0377\c' >> 'blank.bin' 63 | done 64 | fi 65 | 66 | xtensa-esp32-elf-objdump -S $PROJECT_NAME.elf > $PROJECT_NAME.s & 67 | 68 | mac=$(python esptool.py -b 115200 -p /dev/ttyUSB$1 read_mac) 69 | mac_str=${mac##*MAC:} 70 | mac_str=${mac_str//:/-} 71 | log_file_name="../serial_log/"${mac_str:1:17} 72 | 73 | sudo chmod 777 /dev/ttyUSB* 74 | 75 | python esptool.py --chip esp32 --port /dev/ttyUSB$1 erase_flash 76 | 77 | if [ -n "$2" ] ;then 78 | echo -e "\033[32m----------------------" 79 | echo "write device id to flash" 80 | echo $2 > 'device_id.bin' 81 | echo -e "----------------------\033[00m" 82 | 83 | python esptool.py --chip esp32 --port /dev/ttyUSB$1 --baud 1152000 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x10000 $PROJECT_NAME.bin 0x8000 partitions_two_ota.bin 0x310000 device_id.bin 84 | else 85 | python esptool.py --chip esp32 --port /dev/ttyUSB$1 --baud 1152000 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x10000 $PROJECT_NAME.bin 0x8000 partitions_two_ota.bin 86 | fi 87 | 88 | python idf_monitor.py -b 115200 -p /dev/ttyUSB$1 -sf "${log_file_name}__ttyUSB$1.log" $PROJECT_NAME.elf 89 | -------------------------------------------------------------------------------- /main/alink_key_trigger.c: -------------------------------------------------------------------------------- 1 | /* GPIO Example 2 | 3 | This example code is in the Public Domain (or CC0 licensed, at your option.) 4 | 5 | Unless required by applicable law or agreed to in writing, this 6 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 7 | CONDITIONS OF ANY KIND, either express or implied. 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include "freertos/FreeRTOS.h" 13 | #include "freertos/task.h" 14 | #include "freertos/queue.h" 15 | #include "driver/gpio.h" 16 | #include "esp_system.h" 17 | 18 | #include "esp_alink.h" 19 | #include "esp_alink_log.h" 20 | #include "esp_info_store.h" 21 | 22 | typedef enum { 23 | ALINK_KEY_SHORT_PRESS = 1, 24 | ALINK_KEY_MEDIUM_PRESS, 25 | ALINK_KEY_LONG_PRESS, 26 | } alink_key_t; 27 | 28 | #define ESP_INTR_FLAG_DEFAULT 0 29 | #define ALINK_RESET_KEY_IO 0 30 | 31 | static const char *TAG = "alink_factory_reset"; 32 | static xQueueHandle gpio_evt_queue = NULL; 33 | 34 | void IRAM_ATTR gpio_isr_handler(void *arg) 35 | { 36 | uint32_t gpio_num = (uint32_t) arg; 37 | xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); 38 | } 39 | 40 | void alink_key_init(uint32_t key_gpio_pin) 41 | { 42 | gpio_config_t io_conf; 43 | //interrupt of rising edge 44 | io_conf.intr_type = GPIO_INTR_ANYEDGE; 45 | //bit mask of the pins, use GPIO4/5 here 46 | io_conf.pin_bit_mask = 1 << key_gpio_pin; 47 | //set as input mode 48 | io_conf.mode = GPIO_MODE_INPUT; 49 | //enable pull-up mode 50 | io_conf.pull_up_en = 1; 51 | gpio_config(&io_conf); 52 | 53 | //change gpio intrrupt type for one pin 54 | gpio_set_intr_type(key_gpio_pin, GPIO_INTR_ANYEDGE); 55 | 56 | //create a queue to handle gpio event from isr 57 | gpio_evt_queue = xQueueCreate(2, sizeof(uint32_t)); 58 | 59 | //install gpio isr service 60 | gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); 61 | //hook isr handler for specific gpio pin 62 | gpio_isr_handler_add(key_gpio_pin, gpio_isr_handler, (void *) key_gpio_pin); 63 | } 64 | 65 | alink_err_t alink_key_scan(TickType_t ticks_to_wait) 66 | { 67 | uint32_t io_num; 68 | alink_err_t ret; 69 | BaseType_t press_key = pdFALSE; 70 | BaseType_t lift_key = pdFALSE; 71 | 72 | int backup_time = 0; 73 | 74 | for (;;) { 75 | ret = xQueueReceive(gpio_evt_queue, &io_num, ticks_to_wait); 76 | ALINK_ERROR_CHECK(ret != pdTRUE, ALINK_ERR, "xQueueReceive, ret:%d", ret); 77 | 78 | if (gpio_get_level(io_num) == 0) { 79 | press_key = pdTRUE; 80 | backup_time = system_get_time(); 81 | } else if (press_key) { 82 | lift_key = pdTRUE; 83 | backup_time = system_get_time() - backup_time; 84 | } 85 | 86 | if (press_key & lift_key) { 87 | press_key = pdFALSE; 88 | lift_key = pdFALSE; 89 | 90 | if (backup_time > 5000000) { 91 | return ALINK_KEY_LONG_PRESS; 92 | } else if (backup_time > 1000000) { 93 | return ALINK_KEY_MEDIUM_PRESS; 94 | } else { 95 | return ALINK_KEY_SHORT_PRESS; 96 | } 97 | } 98 | } 99 | } 100 | 101 | void alink_key_trigger(void *arg) 102 | { 103 | alink_err_t ret = 0; 104 | alink_key_init(ALINK_RESET_KEY_IO); 105 | 106 | for (;;) { 107 | ret = alink_key_scan(portMAX_DELAY); 108 | ALINK_ERROR_CHECK(ret == ALINK_ERR, vTaskDelete(NULL), "alink_key_scan ret:%d", ret); 109 | 110 | switch (ret) { 111 | case ALINK_KEY_SHORT_PRESS: 112 | alink_event_send(ALINK_EVENT_ACTIVATE_DEVICE); 113 | break; 114 | 115 | case ALINK_KEY_MEDIUM_PRESS: 116 | alink_event_send(ALINK_EVENT_UPDATE_ROUTER); 117 | break; 118 | 119 | case ALINK_KEY_LONG_PRESS: 120 | alink_event_send(ALINK_EVENT_FACTORY_RESET); 121 | break; 122 | 123 | default: 124 | break; 125 | } 126 | } 127 | 128 | vTaskDelete(NULL); 129 | } 130 | 131 | -------------------------------------------------------------------------------- /main/app_main.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2014 -2016 Espressif System 3 | * 4 | * FileName: app_main.c 5 | * 6 | * Description: 7 | * 8 | * Modification history: 9 | * 2016/11/16, v0.0.1 create this file. 10 | *******************************************************************************/ 11 | #include 12 | 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/queue.h" 16 | #include "lwip/sockets.h" 17 | 18 | #include "esp_event_loop.h" 19 | #include "esp_wifi.h" 20 | #include "esp_err.h" 21 | #include "esp_system.h" 22 | #include "esp_spi_flash.h" 23 | 24 | #include "nvs.h" 25 | #include "nvs_flash.h" 26 | 27 | #include "esp_alink.h" 28 | #include "alink_product.h" 29 | #include "cJSON.h" 30 | #include "esp_json_parser.h" 31 | #include "alink_export.h" 32 | 33 | #ifndef ALINK_PASSTHROUGH 34 | static const char *TAG = "sample_json"; 35 | 36 | /*do your job here*/ 37 | typedef struct virtual_dev { 38 | uint8_t errorcode; 39 | uint8_t hue; 40 | uint8_t luminance; 41 | uint8_t power; 42 | uint8_t work_mode; 43 | } dev_info_t; 44 | 45 | static dev_info_t g_light_info = { 46 | .errorcode = 0x00, 47 | .hue = 0x10, 48 | .luminance = 0x50, 49 | .power = 0x01, 50 | .work_mode = 0x02, 51 | }; 52 | /** 53 | * @brief In order to simplify the analysis of json package operations, 54 | * use the package alink_json_parse, you can also use the standard cJson data analysis 55 | */ 56 | static alink_err_t device_data_parse(const char *json_str, const char *key, uint8_t *value) 57 | { 58 | char sub_str[64] = {0}; 59 | char value_tmp[8] = {0}; 60 | 61 | if (esp_json_parse(json_str, key, sub_str) < 0) { 62 | return ALINK_ERR; 63 | } 64 | 65 | if (esp_json_parse(sub_str, "value", value_tmp) < 0) { 66 | return ALINK_ERR; 67 | } 68 | 69 | *value = atoi(value_tmp); 70 | return ALINK_ERR; 71 | } 72 | 73 | static alink_err_t device_data_pack(const char *json_str, const char *key, int value) 74 | { 75 | char sub_str[64] = {0}; 76 | 77 | if (esp_json_pack(sub_str, "value", value) < 0) { 78 | return ALINK_ERR; 79 | } 80 | 81 | if (esp_json_pack(json_str, key, sub_str) < 0) { 82 | return ALINK_ERR; 83 | } 84 | 85 | return ALINK_OK; 86 | } 87 | 88 | /** 89 | * @brief When the service received errno a jump that is complete activation, 90 | * activation of the order need to modify the specific equipment 91 | */ 92 | static alink_err_t alink_activate_device() 93 | { 94 | alink_err_t ret = 0; 95 | const char *activate_data = NULL; 96 | 97 | activate_data = "{\"ErrorCode\": { \"value\": \"1\" }}"; 98 | ret = alink_write(activate_data, strlen(activate_data) + 1, 200); 99 | ALINK_ERROR_CHECK(ret < 0, ALINK_ERR, "alink_write, ret: %d", ret); 100 | 101 | activate_data = "{\"ErrorCode\": { \"value\": \"0\" }}"; 102 | ret = alink_write(activate_data, strlen(activate_data) + 1, 200); 103 | ALINK_ERROR_CHECK(ret < 0, ALINK_ERR, "alink_write, ret: %d", ret); 104 | 105 | return ALINK_OK; 106 | } 107 | 108 | /** 109 | * @brief The alink protocol specifies that the state of the device must be 110 | * proactively attached to the Ali server 111 | */ 112 | static alink_err_t proactive_report_data() 113 | { 114 | alink_err_t ret = 0; 115 | char *up_cmd = (char *)calloc(1, ALINK_DATA_LEN); 116 | 117 | device_data_pack(up_cmd, "Hue", g_light_info.hue); 118 | device_data_pack(up_cmd, "Luminance", g_light_info.luminance); 119 | device_data_pack(up_cmd, "Switch", g_light_info.power); 120 | device_data_pack(up_cmd, "WorkMode", g_light_info.work_mode); 121 | ret = alink_write(up_cmd, strlen(up_cmd) + 1, 500); 122 | free(up_cmd); 123 | 124 | if (ret < 0) { 125 | ALINK_LOGW("alink_write is err"); 126 | } 127 | 128 | return ALINK_OK; 129 | } 130 | 131 | /* 132 | * getDeviceStatus: {"attrSet":[],"uuid":"7DD5CE4ECE654B721BE8F4F912C10B8E"} 133 | * postDeviceData: {"Luminance":{"value":"80"},"Switch":{"value":"1"},"attrSet":["Luminance","Switch","Hue","ErrorCode","WorkMode","onlineState"],"Hue":{"value":"16"},"ErrorCode":{"value":"0"},"uuid":"158EE04889E2B1FE4BF18AFE4BFD0F04","WorkMode":{"value":"2"},"onlineState":{"when":"1495184488","value":"on"} 134 | * {"Switch":{"value":"1"},"attrSet":["Switch"],"uuid":"158EE04889E2B1FE4BF18AFE4BFD0F04"} 135 | * 136 | * @note read_task_test stack space is small, need to follow the specific 137 | * application to increase the size of the stack 138 | */ 139 | static void read_task_test(void *arg) 140 | { 141 | char *down_cmd = (char *)malloc(ALINK_DATA_LEN); 142 | 143 | for (;;) { 144 | if (alink_read(down_cmd, ALINK_DATA_LEN, portMAX_DELAY) < 0) { 145 | ALINK_LOGW("alink_read is err"); 146 | continue; 147 | } 148 | 149 | char method_str[32] = {0}; 150 | if (esp_json_parse(down_cmd, "method", method_str) < 0) { 151 | ALINK_LOGW("alink_json_parse, is err"); 152 | continue; 153 | } 154 | 155 | if (!strcmp(method_str, "getDeviceStatus")) { 156 | proactive_report_data(); 157 | continue; 158 | } else if (!strcmp(method_str, "setDeviceStatus")) { 159 | ALINK_LOGV("setDeviceStatus: %s", down_cmd); 160 | device_data_parse(down_cmd, "ErrorCode", &(g_light_info.errorcode)); 161 | device_data_parse(down_cmd, "Hue", &(g_light_info.hue)); 162 | device_data_parse(down_cmd, "Luminance", &(g_light_info.luminance)); 163 | device_data_parse(down_cmd, "Switch", &(g_light_info.power)); 164 | device_data_parse(down_cmd, "WorkMode", &(g_light_info.work_mode)); 165 | ALINK_LOGI("read: errorcode:%d, hue: %d, luminance: %d, Switch: %d, work_mode: %d", 166 | g_light_info.errorcode, g_light_info.hue, g_light_info.luminance, 167 | g_light_info.power, g_light_info.work_mode); 168 | 169 | /* write data is not necessary */ 170 | if (alink_write(down_cmd, strlen(down_cmd) + 1, 0) < 0) { 171 | ALINK_LOGW("alink_write is err"); 172 | } 173 | } 174 | } 175 | 176 | free(down_cmd); 177 | vTaskDelete(NULL); 178 | } 179 | 180 | static alink_err_t alink_event_handler(alink_event_t event) 181 | { 182 | switch (event) { 183 | case ALINK_EVENT_CLOUD_CONNECTED: 184 | ALINK_LOGD("Alink cloud connected!"); 185 | proactive_report_data(); 186 | break; 187 | 188 | case ALINK_EVENT_CLOUD_DISCONNECTED: 189 | ALINK_LOGD("Alink cloud disconnected!"); 190 | break; 191 | 192 | case ALINK_EVENT_GET_DEVICE_DATA: 193 | ALINK_LOGD("The cloud initiates a query to the device"); 194 | break; 195 | 196 | case ALINK_EVENT_SET_DEVICE_DATA: 197 | ALINK_LOGD("The cloud is set to send instructions"); 198 | break; 199 | 200 | case ALINK_EVENT_POST_CLOUD_DATA: 201 | ALINK_LOGD("The device post data success!"); 202 | break; 203 | 204 | case ALINK_EVENT_WIFI_DISCONNECTED: 205 | ALINK_LOGD("Wifi disconnected"); 206 | break; 207 | 208 | case ALINK_EVENT_CONFIG_NETWORK: 209 | ALINK_LOGD("Enter the network configuration mode"); 210 | break; 211 | 212 | case ALINK_EVENT_UPDATE_ROUTER: 213 | ALINK_LOGD("Requests update router"); 214 | alink_update_router(); 215 | break; 216 | 217 | case ALINK_EVENT_FACTORY_RESET: 218 | ALINK_LOGD("Requests factory reset"); 219 | alink_factory_setting(); 220 | break; 221 | 222 | case ALINK_EVENT_ACTIVATE_DEVICE: 223 | ALINK_LOGD("Requests activate device"); 224 | alink_activate_device(); 225 | break; 226 | 227 | default: 228 | break; 229 | } 230 | 231 | return ALINK_OK; 232 | } 233 | 234 | /** 235 | * @brief This function is only for detecting memory leaks 236 | */ 237 | static void free_heap_task(void *arg) 238 | { 239 | for (;;) { 240 | ALINK_LOGI("free heap size: %d", esp_get_free_heap_size()); 241 | vTaskDelay(5000 / portTICK_RATE_MS); 242 | } 243 | 244 | vTaskDelete(NULL); 245 | } 246 | 247 | /** 248 | * @brief Too much serial print information will not be able to pass high-frequency 249 | * send and receive data test 250 | * 251 | * @Note When GPIO2 is connected to 3V3 and restarts the device, the log level will be modified 252 | */ 253 | void reduce_serial_print() 254 | { 255 | gpio_config_t io_conf = { 256 | .intr_type = GPIO_INTR_ANYEDGE, // interrupt of rising edge 257 | .pin_bit_mask = 1 << GPIO_NUM_2, // bit mask of the pins, use GPIO2 here 258 | .mode = GPIO_MODE_INPUT, // set as input mode 259 | .pull_up_en = GPIO_PULLUP_ENABLE, // enable pull-up mode 260 | }; 261 | 262 | ESP_ERROR_CHECK(gpio_config(&io_conf)); 263 | 264 | if (!gpio_get_level(GPIO_NUM_2)) { 265 | ALINK_LOGI("*********************************"); 266 | ALINK_LOGI("* SET LOGLEVEL INFO *"); 267 | ALINK_LOGI("*********************************"); 268 | alink_set_loglevel(ALINK_LL_INFO); 269 | } 270 | } 271 | 272 | 273 | /****************************************************************************** 274 | * FunctionName : app_main 275 | * Description : entry of user application, init user function here 276 | * Parameters : none 277 | * Returns : none 278 | *******************************************************************************/ 279 | void app_main() 280 | { 281 | esp_chip_info_t chip_info; 282 | esp_chip_info(&chip_info); 283 | 284 | ALINK_LOGI("================= SYSTEM INFO ================"); 285 | ALINK_LOGI("compile time : %s %s", __DATE__, __TIME__); 286 | ALINK_LOGI("free heap : %dB", esp_get_free_heap_size()); 287 | ALINK_LOGI("idf version : %s", esp_get_idf_version()); 288 | ALINK_LOGI("CPU cores : %d", chip_info.cores); 289 | ALINK_LOGI("chip name : %s", ALINK_CHIPID); 290 | ALINK_LOGI("modle name : %s", ALINK_MODULE_NAME); 291 | ALINK_LOGI("function : WiFi%s%s", 292 | (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", 293 | (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); 294 | ALINK_LOGI("silicon revision : %d", chip_info.revision); 295 | ALINK_LOGI("flash : %dMB %s", spi_flash_get_chip_size() / (1024 * 1024), 296 | (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); 297 | 298 | #ifdef CONFIG_ALINK_VERSION_SDS 299 | ALINK_LOGI("alink version : esp32-alink_sds\n"); 300 | #else 301 | ALINK_LOGI("alink version : esp32-alink_embed\n"); 302 | #endif 303 | 304 | ESP_ERROR_CHECK(nvs_flash_init()); 305 | tcpip_adapter_init(); 306 | ESP_ERROR_CHECK(esp_event_loop_init(NULL, NULL)); 307 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 308 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 309 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 310 | 311 | /** 312 | * @brief You can use other trigger mode, to trigger the distribution network, activation and other operations 313 | */ 314 | extern void alink_key_trigger(void *arg); 315 | xTaskCreate(alink_key_trigger, "alink_key_trigger", 1024 * 2, NULL, 10, NULL); 316 | 317 | #ifdef CONFIG_ALINK_VERSION_SDS 318 | alink_product_t product_info = { 319 | .name = "alink_product", 320 | /*!< Product version number, ota upgrade need to be modified */ 321 | .version = "1.0.0", 322 | .model = "OPENALINK_LIVING_LIGHT_SDS_TEST", 323 | /*!< The Key-value pair used in the product */ 324 | .key = "1L6ueddLqnRORAQ2sGOL", 325 | .secret = "qfxCLoc1yXEk9aLdx5F74tl1pdxl0W0q7eYOvvuo", 326 | }; 327 | 328 | // #define CONFIG_USE_TEST_DEVICE_ID 329 | 330 | #ifdef CONFIG_USE_TEST_DEVICE_ID 331 | uint8_t test_device_mac[] = {0x24, 0x0a, 0xc4, 0x11, 0x45, 0xfc}; 332 | 333 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 334 | ESP_ERROR_CHECK(esp_wifi_set_mac(ESP_IF_WIFI_STA, test_device_mac)); 335 | 336 | product_info.key_device = "8Rd98k3Ht0bxblf3TSf9"; 337 | product_info.secret_device = "NrazMjfM9ta87HzqHEHXAaVa0glLb1Ym"; 338 | #endif 339 | 340 | #else 341 | const alink_product_t product_info = { 342 | .name = "alink_product", 343 | /*!< Product version number, ota upgrade need to be modified */ 344 | .version = "1.0.0", 345 | .model = "ALINKTEST_LIVING_LIGHT_ALINK_TEST", 346 | /*!< The Key-value pair used in the product */ 347 | .key = "5gPFl8G4GyFZ1fPWk20m", 348 | .secret = "ngthgTlZ65bX5LpViKIWNsDPhOf2As9ChnoL9gQb", 349 | /*!< The Key-value pair used in the sandbox environment */ 350 | .key_sandbox = "dpZZEpm9eBfqzK7yVeLq", 351 | .secret_sandbox = "THnfRRsU5vu6g6m9X6uFyAjUWflgZ0iyGjdEneKm", 352 | }; 353 | #endif 354 | 355 | ESP_ERROR_CHECK(alink_init(&product_info, alink_event_handler)); 356 | reduce_serial_print(); 357 | xTaskCreate(read_task_test, "read_task_test", 1024 * 4, NULL, 9, NULL); 358 | xTaskCreate(free_heap_task, "free_heap_task", 1024 * 2, NULL, 3, NULL); 359 | } 360 | #endif 361 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | # include $(IDF_PATH)/make/component_common.mk 6 | -------------------------------------------------------------------------------- /sdkconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # Espressif IoT Development Framework Configuration 4 | # 5 | 6 | # 7 | # SDK tool configuration 8 | # 9 | CONFIG_TOOLPREFIX="xtensa-esp32-elf-" 10 | CONFIG_PYTHON="python" 11 | CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y 12 | 13 | # 14 | # Bootloader config 15 | # 16 | CONFIG_LOG_BOOTLOADER_LEVEL_NONE= 17 | CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= 18 | CONFIG_LOG_BOOTLOADER_LEVEL_WARN= 19 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y 20 | CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= 21 | CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= 22 | CONFIG_LOG_BOOTLOADER_LEVEL=3 23 | 24 | # 25 | # Security features 26 | # 27 | CONFIG_SECURE_BOOT_ENABLED= 28 | CONFIG_FLASH_ENCRYPTION_ENABLED= 29 | 30 | # 31 | # Serial flasher config 32 | # 33 | CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" 34 | CONFIG_ESPTOOLPY_BAUD_115200B= 35 | CONFIG_ESPTOOLPY_BAUD_230400B= 36 | CONFIG_ESPTOOLPY_BAUD_921600B= 37 | CONFIG_ESPTOOLPY_BAUD_2MB= 38 | CONFIG_ESPTOOLPY_BAUD_OTHER=y 39 | CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=1152000 40 | CONFIG_ESPTOOLPY_BAUD=1152000 41 | CONFIG_ESPTOOLPY_COMPRESSED=y 42 | CONFIG_FLASHMODE_QIO= 43 | CONFIG_FLASHMODE_QOUT= 44 | CONFIG_FLASHMODE_DIO=y 45 | CONFIG_FLASHMODE_DOUT= 46 | CONFIG_ESPTOOLPY_FLASHMODE="dio" 47 | CONFIG_ESPTOOLPY_FLASHFREQ_80M= 48 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y 49 | CONFIG_ESPTOOLPY_FLASHFREQ_26M= 50 | CONFIG_ESPTOOLPY_FLASHFREQ_20M= 51 | CONFIG_ESPTOOLPY_FLASHFREQ="40m" 52 | CONFIG_ESPTOOLPY_FLASHSIZE_1MB= 53 | CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y 54 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB= 55 | CONFIG_ESPTOOLPY_FLASHSIZE_8MB= 56 | CONFIG_ESPTOOLPY_FLASHSIZE_16MB= 57 | CONFIG_ESPTOOLPY_FLASHSIZE="2MB" 58 | CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y 59 | CONFIG_ESPTOOLPY_BEFORE_RESET=y 60 | CONFIG_ESPTOOLPY_BEFORE_NORESET= 61 | CONFIG_ESPTOOLPY_BEFORE="default_reset" 62 | CONFIG_ESPTOOLPY_AFTER_RESET=y 63 | CONFIG_ESPTOOLPY_AFTER_NORESET= 64 | CONFIG_ESPTOOLPY_AFTER="hard_reset" 65 | CONFIG_MONITOR_BAUD_9600B= 66 | CONFIG_MONITOR_BAUD_57600B= 67 | CONFIG_MONITOR_BAUD_115200B=y 68 | CONFIG_MONITOR_BAUD_230400B= 69 | CONFIG_MONITOR_BAUD_921600B= 70 | CONFIG_MONITOR_BAUD_2MB= 71 | CONFIG_MONITOR_BAUD_OTHER= 72 | CONFIG_MONITOR_BAUD_OTHER_VAL=115200 73 | CONFIG_MONITOR_BAUD=115200 74 | 75 | # 76 | # Partition Table 77 | # 78 | CONFIG_PARTITION_TABLE_SINGLE_APP= 79 | CONFIG_PARTITION_TABLE_TWO_OTA=y 80 | CONFIG_PARTITION_TABLE_CUSTOM= 81 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" 82 | CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 83 | CONFIG_PARTITION_TABLE_FILENAME="partitions_two_ota.csv" 84 | CONFIG_APP_OFFSET=0x10000 85 | 86 | # 87 | # Compiler options 88 | # 89 | CONFIG_OPTIMIZATION_LEVEL_DEBUG=y 90 | CONFIG_OPTIMIZATION_LEVEL_RELEASE= 91 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y 92 | CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= 93 | CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= 94 | 95 | # 96 | # Component config 97 | # 98 | 99 | # 100 | # Application Level Tracing 101 | # 102 | CONFIG_ESP32_APPTRACE_DEST_TRAX= 103 | CONFIG_ESP32_APPTRACE_DEST_NONE=y 104 | CONFIG_ESP32_APPTRACE_ENABLE= 105 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y 106 | 107 | # 108 | # FreeRTOS SystemView Tracing 109 | # 110 | CONFIG_AWS_IOT_SDK= 111 | CONFIG_BT_ENABLED= 112 | CONFIG_BT_RESERVE_DRAM=0 113 | 114 | # 115 | # ESP32-specific 116 | # 117 | CONFIG_ESP32_DEFAULT_CPU_FREQ_80= 118 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160= 119 | CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y 120 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 121 | CONFIG_MEMMAP_SMP=y 122 | CONFIG_SPIRAM_SUPPORT= 123 | CONFIG_MEMMAP_TRACEMEM= 124 | CONFIG_MEMMAP_TRACEMEM_TWOBANKS= 125 | CONFIG_ESP32_TRAX= 126 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0 127 | CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= 128 | CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= 129 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y 130 | CONFIG_ESP32_ENABLE_COREDUMP= 131 | CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= 132 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y 133 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 134 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 135 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=4096 136 | CONFIG_MAIN_TASK_STACK_SIZE=8192 137 | CONFIG_IPC_TASK_STACK_SIZE=1024 138 | CONFIG_TIMER_TASK_STACK_SIZE=4096 139 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y 140 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= 141 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= 142 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= 143 | CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= 144 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y 145 | CONFIG_NEWLIB_NANO_FORMAT= 146 | CONFIG_CONSOLE_UART_DEFAULT=y 147 | CONFIG_CONSOLE_UART_CUSTOM= 148 | CONFIG_CONSOLE_UART_NONE= 149 | CONFIG_CONSOLE_UART_NUM=0 150 | CONFIG_CONSOLE_UART_BAUDRATE=115200 151 | CONFIG_ULP_COPROC_ENABLED= 152 | CONFIG_ULP_COPROC_RESERVE_MEM=0 153 | CONFIG_ESP32_PANIC_PRINT_HALT= 154 | CONFIG_ESP32_PANIC_PRINT_REBOOT=y 155 | CONFIG_ESP32_PANIC_SILENT_REBOOT= 156 | CONFIG_ESP32_PANIC_GDBSTUB= 157 | CONFIG_ESP32_DEBUG_OCDAWARE=y 158 | CONFIG_INT_WDT=y 159 | CONFIG_INT_WDT_TIMEOUT_MS=300 160 | CONFIG_INT_WDT_CHECK_CPU1=y 161 | CONFIG_TASK_WDT=y 162 | CONFIG_TASK_WDT_PANIC= 163 | CONFIG_TASK_WDT_TIMEOUT_S=5 164 | CONFIG_TASK_WDT_CHECK_IDLE_TASK=y 165 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y 166 | CONFIG_BROWNOUT_DET=y 167 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y 168 | CONFIG_BROWNOUT_DET_LVL_SEL_1= 169 | CONFIG_BROWNOUT_DET_LVL_SEL_2= 170 | CONFIG_BROWNOUT_DET_LVL_SEL_3= 171 | CONFIG_BROWNOUT_DET_LVL_SEL_4= 172 | CONFIG_BROWNOUT_DET_LVL_SEL_5= 173 | CONFIG_BROWNOUT_DET_LVL_SEL_6= 174 | CONFIG_BROWNOUT_DET_LVL_SEL_7= 175 | CONFIG_BROWNOUT_DET_LVL=0 176 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC= 177 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y 178 | CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= 179 | CONFIG_ESP32_TIME_SYSCALL_USE_NONE= 180 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y 181 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= 182 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 183 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 184 | CONFIG_ESP32_XTAL_FREQ_40=y 185 | CONFIG_ESP32_XTAL_FREQ_26= 186 | CONFIG_ESP32_XTAL_FREQ_AUTO= 187 | CONFIG_ESP32_XTAL_FREQ=40 188 | CONFIG_DISABLE_BASIC_ROM_CONSOLE= 189 | CONFIG_NO_BLOBS= 190 | 191 | # 192 | # Wi-Fi 193 | # 194 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 195 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 196 | CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= 197 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 198 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 199 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 200 | CONFIG_ESP32_WIFI_AMPDU_ENABLED=y 201 | CONFIG_ESP32_WIFI_TX_BA_WIN=6 202 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 203 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 204 | 205 | # 206 | # PHY 207 | # 208 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y 209 | CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= 210 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 211 | CONFIG_ESP32_PHY_MAX_TX_POWER=20 212 | CONFIG_ALINK_ENABLE=y 213 | CONFIG_ALINK_VERSION_EMBED= 214 | CONFIG_ALINK_VERSION_SDS=y 215 | CONFIG_ALINK_VERSION=1 216 | CONFIG_ALINK_WRITE_NOT_BUFFER= 217 | CONFIG_WIFI_WAIT_TIME=60 218 | CONFIG_ALINK_TASK_PRIOTY=6 219 | CONFIG_ALINK_EVENT_STACK_SIZE=4096 220 | CONFIG_ALINK_POST_DATA_STACK_SIZE=4096 221 | CONFIG_DOWN_CMD_QUEUE_NUM=3 222 | CONFIG_UP_CMD_QUEUE_NUM=3 223 | CONFIG_ALINK_DATA_LEN=2048 224 | CONFIG_ALINK_CHIPID="esp32" 225 | CONFIG_ALINK_MODULE_NAME="ESP-WROOM-32" 226 | CONFIG_LOG_ALINK_LEVEL_NONE= 227 | CONFIG_LOG_ALINK_LEVEL_ERROR= 228 | CONFIG_LOG_ALINK_LEVEL_WARN= 229 | CONFIG_LOG_ALINK_LEVEL_INFO=y 230 | CONFIG_LOG_ALINK_LEVEL_DEBUG= 231 | CONFIG_LOG_ALINK_LEVEL_VERBOSE= 232 | CONFIG_LOG_ALINK_LEVEL=3 233 | CONFIG_LOG_ALINK_SDK_LEVEL_NONE= 234 | CONFIG_LOG_ALINK_SDK_LEVEL_ERROR= 235 | CONFIG_LOG_ALINK_SDK_LEVEL_WARN= 236 | CONFIG_LOG_ALINK_SDK_LEVEL_INFO= 237 | CONFIG_LOG_ALINK_SDK_LEVEL_DEBUG= 238 | CONFIG_LOG_ALINK_SDK_LEVEL_TRACE=y 239 | CONFIG_LOG_ALINK_SDK_LEVEL=6 240 | 241 | # 242 | # Ethernet 243 | # 244 | CONFIG_DMA_RX_BUF_NUM=10 245 | CONFIG_DMA_TX_BUF_NUM=10 246 | CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= 247 | CONFIG_EMAC_TASK_PRIORITY=20 248 | 249 | # 250 | # FAT Filesystem support 251 | # 252 | CONFIG_FATFS_CODEPAGE_ASCII=y 253 | CONFIG_FATFS_CODEPAGE_437= 254 | CONFIG_FATFS_CODEPAGE_720= 255 | CONFIG_FATFS_CODEPAGE_737= 256 | CONFIG_FATFS_CODEPAGE_771= 257 | CONFIG_FATFS_CODEPAGE_775= 258 | CONFIG_FATFS_CODEPAGE_850= 259 | CONFIG_FATFS_CODEPAGE_852= 260 | CONFIG_FATFS_CODEPAGE_855= 261 | CONFIG_FATFS_CODEPAGE_857= 262 | CONFIG_FATFS_CODEPAGE_860= 263 | CONFIG_FATFS_CODEPAGE_861= 264 | CONFIG_FATFS_CODEPAGE_862= 265 | CONFIG_FATFS_CODEPAGE_863= 266 | CONFIG_FATFS_CODEPAGE_864= 267 | CONFIG_FATFS_CODEPAGE_865= 268 | CONFIG_FATFS_CODEPAGE_866= 269 | CONFIG_FATFS_CODEPAGE_869= 270 | CONFIG_FATFS_CODEPAGE_932= 271 | CONFIG_FATFS_CODEPAGE_936= 272 | CONFIG_FATFS_CODEPAGE_949= 273 | CONFIG_FATFS_CODEPAGE_950= 274 | CONFIG_FATFS_CODEPAGE=1 275 | CONFIG_FATFS_MAX_LFN=255 276 | 277 | # 278 | # FreeRTOS 279 | # 280 | CONFIG_FREERTOS_UNICORE= 281 | CONFIG_FREERTOS_CORETIMER_0=y 282 | CONFIG_FREERTOS_CORETIMER_1= 283 | CONFIG_FREERTOS_HZ=1000 284 | CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y 285 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= 286 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL= 287 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y 288 | CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= 289 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y 290 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 291 | CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y 292 | CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= 293 | CONFIG_FREERTOS_ASSERT_DISABLE= 294 | CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG= 295 | CONFIG_ENABLE_MEMORY_DEBUG= 296 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 297 | CONFIG_FREERTOS_ISR_STACKSIZE=1536 298 | CONFIG_FREERTOS_LEGACY_HOOKS= 299 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 300 | CONFIG_SUPPORT_STATIC_ALLOCATION= 301 | CONFIG_TIMER_TASK_PRIORITY=1 302 | CONFIG_TIMER_TASK_STACK_DEPTH=2048 303 | CONFIG_TIMER_QUEUE_LENGTH=10 304 | CONFIG_FREERTOS_DEBUG_INTERNALS= 305 | 306 | # 307 | # Heap memory debugging 308 | # 309 | CONFIG_HEAP_POISONING_DISABLED=y 310 | CONFIG_HEAP_POISONING_LIGHT= 311 | CONFIG_HEAP_POISONING_COMPREHENSIVE= 312 | CONFIG_HEAP_TRACING= 313 | 314 | # 315 | # Log output 316 | # 317 | CONFIG_LOG_DEFAULT_LEVEL_NONE= 318 | CONFIG_LOG_DEFAULT_LEVEL_ERROR= 319 | CONFIG_LOG_DEFAULT_LEVEL_WARN= 320 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 321 | CONFIG_LOG_DEFAULT_LEVEL_DEBUG= 322 | CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= 323 | CONFIG_LOG_DEFAULT_LEVEL=3 324 | CONFIG_LOG_COLORS=y 325 | 326 | # 327 | # LWIP 328 | # 329 | CONFIG_L2_TO_L3_COPY= 330 | CONFIG_LWIP_MAX_SOCKETS=10 331 | CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 332 | CONFIG_LWIP_SO_REUSE=y 333 | CONFIG_LWIP_SO_RCVBUF= 334 | CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 335 | CONFIG_LWIP_IP_FRAG= 336 | CONFIG_LWIP_IP_REASSEMBLY= 337 | 338 | # 339 | # TCP 340 | # 341 | CONFIG_TCP_MAXRTX=12 342 | CONFIG_TCP_SYNMAXRTX=6 343 | CONFIG_TCP_MSS=1436 344 | CONFIG_TCP_MSL=60000 345 | CONFIG_TCP_SND_BUF_DEFAULT=5744 346 | CONFIG_TCP_WND_DEFAULT=5744 347 | CONFIG_TCP_RECVMBOX_SIZE=6 348 | CONFIG_TCP_QUEUE_OOSEQ=y 349 | CONFIG_TCP_OVERSIZE_MSS=y 350 | CONFIG_TCP_OVERSIZE_QUARTER_MSS= 351 | CONFIG_TCP_OVERSIZE_DISABLE= 352 | 353 | # 354 | # UDP 355 | # 356 | CONFIG_UDP_RECVMBOX_SIZE=6 357 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y 358 | CONFIG_TCPIP_TASK_STACK_SIZE=2560 359 | CONFIG_PPP_SUPPORT= 360 | 361 | # 362 | # ICMP 363 | # 364 | CONFIG_LWIP_MULTICAST_PING= 365 | CONFIG_LWIP_BROADCAST_PING= 366 | 367 | # 368 | # mbedTLS 369 | # 370 | CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 371 | CONFIG_MBEDTLS_DEBUG= 372 | CONFIG_MBEDTLS_HARDWARE_AES=y 373 | CONFIG_MBEDTLS_HARDWARE_MPI= 374 | CONFIG_MBEDTLS_HARDWARE_SHA= 375 | CONFIG_MBEDTLS_HAVE_TIME=y 376 | CONFIG_MBEDTLS_HAVE_TIME_DATE= 377 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y 378 | CONFIG_MBEDTLS_TLS_SERVER_ONLY= 379 | CONFIG_MBEDTLS_TLS_CLIENT_ONLY= 380 | CONFIG_MBEDTLS_TLS_DISABLED= 381 | CONFIG_MBEDTLS_TLS_SERVER=y 382 | CONFIG_MBEDTLS_TLS_CLIENT=y 383 | CONFIG_MBEDTLS_TLS_ENABLED=y 384 | 385 | # 386 | # TLS Key Exchange Methods 387 | # 388 | CONFIG_MBEDTLS_PSK_MODES= 389 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y 390 | CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y 391 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y 392 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y 393 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y 394 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y 395 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y 396 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y 397 | CONFIG_MBEDTLS_SSL_PROTO_SSL3= 398 | CONFIG_MBEDTLS_SSL_PROTO_TLS1=y 399 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y 400 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y 401 | CONFIG_MBEDTLS_SSL_PROTO_DTLS= 402 | CONFIG_MBEDTLS_SSL_ALPN=y 403 | CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y 404 | 405 | # 406 | # Symmetric Ciphers 407 | # 408 | CONFIG_MBEDTLS_AES_C=y 409 | CONFIG_MBEDTLS_CAMELLIA_C= 410 | CONFIG_MBEDTLS_DES_C= 411 | CONFIG_MBEDTLS_RC4_DISABLED=y 412 | CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= 413 | CONFIG_MBEDTLS_RC4_ENABLED= 414 | CONFIG_MBEDTLS_BLOWFISH_C= 415 | CONFIG_MBEDTLS_XTEA_C= 416 | CONFIG_MBEDTLS_CCM_C=y 417 | CONFIG_MBEDTLS_GCM_C=y 418 | CONFIG_MBEDTLS_RIPEMD160_C= 419 | 420 | # 421 | # Certificates 422 | # 423 | CONFIG_MBEDTLS_PEM_PARSE_C=y 424 | CONFIG_MBEDTLS_PEM_WRITE_C=y 425 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y 426 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y 427 | CONFIG_MBEDTLS_ECP_C=y 428 | CONFIG_MBEDTLS_ECDH_C=y 429 | CONFIG_MBEDTLS_ECDSA_C=y 430 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y 431 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y 432 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y 433 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y 434 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y 435 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y 436 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y 437 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y 438 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y 439 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y 440 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y 441 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y 442 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y 443 | 444 | # 445 | # OpenSSL 446 | # 447 | CONFIG_OPENSSL_DEBUG= 448 | CONFIG_OPENSSL_ASSERT_DO_NOTHING=y 449 | CONFIG_OPENSSL_ASSERT_EXIT= 450 | 451 | # 452 | # PThreads 453 | # 454 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 455 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=2048 456 | 457 | # 458 | # SPI Flash driver 459 | # 460 | CONFIG_SPI_FLASH_ENABLE_COUNTERS= 461 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y 462 | 463 | # 464 | # tcpip adapter 465 | # 466 | CONFIG_IP_LOST_TIMER_INTERVAL=120 467 | 468 | # 469 | # Wear Levelling 470 | # 471 | CONFIG_WL_SECTOR_SIZE_512= 472 | CONFIG_WL_SECTOR_SIZE_4096=y 473 | CONFIG_WL_SECTOR_SIZE=4096 474 | -------------------------------------------------------------------------------- /tools/FLASH_DOWNLOAD_TOOLS_V3.6.2_ID.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp32-alink-demo/1fd9c1b5dd0a04fe845303ae8758816915dd4651/tools/FLASH_DOWNLOAD_TOOLS_V3.6.2_ID.tar.gz -------------------------------------------------------------------------------- /tools/check_log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | param=$1 4 | 5 | dirt=`pwd | grep 'tools' | wc -l` 6 | if [ "$dirt" -gt 0 ];then 7 | cd .. 8 | fi 9 | 10 | if [ "$param" = "crash" ] ; then 11 | grep -n "Backtrace:" ./serial_log/*.log 12 | elif [ "$param" = "reboot" ] ; then 13 | grep -n "boot:" serial_log/*.log | grep "2nd stage bootloader" 14 | elif [ "$param" = "heap" ] ; then 15 | grep -n "Heap summary for capabilities" ./serial_log/*.log 16 | elif [ "$param" = "clr" ] ; then 17 | for file in ./serial_log/*.log 18 | do 19 | echo "clear log content ..." > $file 20 | done 21 | else 22 | echo -e "\033[32m-------------------help info-----------------" 23 | echo " paramters:" 24 | echo " 'crash': detect whether devices crash" 25 | echo " 'reboot': detect whether devices reboot" 26 | echo " 'heap': detect whether devices malloc error" 27 | echo " 'clr': clear log files in directory ./serial_log/*" 28 | echo -e "---------------------------------------------\033[00m" 29 | fi 30 | -------------------------------------------------------------------------------- /tools/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | dirt=`pwd | grep 'tools' | wc -l` 5 | if [ "$dirt" -gt 0 ];then 6 | cd .. 7 | fi 8 | 9 | find $1 -type f | xargs dos2unix 10 | find $1 -type f | xargs astyle -A3s4SNwm2M40fpHUjk3n 11 | -------------------------------------------------------------------------------- /tools/idf_monitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # esp-idf serial output monitor tool. Does some helpful things: 4 | # - Looks up hex addresses in ELF file with addr2line 5 | # - Reset ESP32 via serial RTS line (Ctrl-T Ctrl-R) 6 | # - Run "make flash" (Ctrl-T Ctrl-F) 7 | # - Run "make app-flash" (Ctrl-T Ctrl-A) 8 | # - If gdbstub output is detected, gdb is automatically loaded 9 | # 10 | # Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # 24 | # Contains elements taken from miniterm "Very simple serial terminal" which 25 | # is part of pySerial. https://github.com/pyserial/pyserial 26 | # (C)2002-2015 Chris Liechti 27 | # 28 | # Originally released under BSD-3-Clause license. 29 | # 30 | from __future__ import print_function, division 31 | import subprocess 32 | import argparse 33 | import codecs 34 | import re 35 | import os 36 | try: 37 | import queue 38 | except ImportError: 39 | import Queue as queue 40 | import time 41 | import sys 42 | import serial 43 | import serial.tools.miniterm as miniterm 44 | import threading 45 | import ctypes 46 | 47 | file_handler=None 48 | key_description = miniterm.key_description 49 | 50 | # Control-key characters 51 | CTRL_A = '\x01' 52 | CTRL_B = '\x02' 53 | CTRL_F = '\x06' 54 | CTRL_H = '\x08' 55 | CTRL_R = '\x12' 56 | CTRL_T = '\x14' 57 | CTRL_RBRACKET = '\x1d' # Ctrl+] 58 | 59 | # ANSI terminal codes 60 | ANSI_RED = '\033[1;31m' 61 | ANSI_YELLOW = '\033[0;33m' 62 | ANSI_NORMAL = '\033[0m' 63 | 64 | def color_print(message, color): 65 | """ Print a message to stderr with colored highlighting """ 66 | sys.stderr.write("%s%s%s\n" % (color, message, ANSI_NORMAL)) 67 | 68 | def yellow_print(message): 69 | color_print(message, ANSI_YELLOW) 70 | 71 | def red_print(message): 72 | color_print(message, ANSI_RED) 73 | 74 | __version__ = "1.0" 75 | 76 | # Tags for tuples in queues 77 | TAG_KEY = 0 78 | TAG_SERIAL = 1 79 | 80 | # regex matches an potential PC value (0x4xxxxxxx) 81 | MATCH_PCADDR = re.compile(r'0x4[0-9a-f]{7}', re.IGNORECASE) 82 | 83 | DEFAULT_TOOLCHAIN_PREFIX = "xtensa-esp32-elf-" 84 | 85 | class StoppableThread(object): 86 | """ 87 | Provide a Thread-like class which can be 'cancelled' via a subclass-provided 88 | cancellation method. 89 | 90 | Can be started and stopped multiple times. 91 | 92 | Isn't an instance of type Thread because Python Thread objects can only be run once 93 | """ 94 | def __init__(self): 95 | self._thread = None 96 | 97 | @property 98 | def alive(self): 99 | """ 100 | Is 'alive' whenever the internal thread object exists 101 | """ 102 | return self._thread is not None 103 | 104 | def start(self): 105 | if self._thread is None: 106 | self._thread = threading.Thread(target=self._run_outer) 107 | self._thread.start() 108 | 109 | def _cancel(self): 110 | pass # override to provide cancellation functionality 111 | 112 | def run(self): 113 | pass # override for the main thread behaviour 114 | 115 | def _run_outer(self): 116 | try: 117 | self.run() 118 | finally: 119 | self._thread = None 120 | 121 | def stop(self): 122 | if self._thread is not None: 123 | old_thread = self._thread 124 | self._thread = None 125 | self._cancel() 126 | old_thread.join() 127 | 128 | class ConsoleReader(StoppableThread): 129 | """ Read input keys from the console and push them to the queue, 130 | until stopped. 131 | """ 132 | def __init__(self, console, event_queue): 133 | super(ConsoleReader, self).__init__() 134 | self.console = console 135 | self.event_queue = event_queue 136 | 137 | def run(self): 138 | self.console.setup() 139 | try: 140 | while self.alive: 141 | try: 142 | if os.name == 'nt': 143 | # Windows kludge: because the console.cancel() method doesn't 144 | # seem to work to unblock getkey() on the Windows implementation. 145 | # 146 | # So we only call getkey() if we know there's a key waiting for us. 147 | import msvcrt 148 | while not msvcrt.kbhit() and self.alive: 149 | time.sleep(0.1) 150 | if not self.alive: 151 | break 152 | c = self.console.getkey() 153 | except KeyboardInterrupt: 154 | c = '\x03' 155 | if c is not None: 156 | self.event_queue.put((TAG_KEY, c), False) 157 | finally: 158 | self.console.cleanup() 159 | 160 | def _cancel(self): 161 | if hasattr(self.console, "cancel"): 162 | self.console.cancel() 163 | elif os.name == 'posix': 164 | # this is the way cancel() is implemented in pyserial 3.1 or newer, 165 | # older pyserial doesn't have this method, hence this hack. 166 | # 167 | # on Windows there is a different (also hacky) fix, applied above. 168 | import fcntl, termios 169 | fcntl.ioctl(self.console.fd, termios.TIOCSTI, b'\0') 170 | 171 | class SerialReader(StoppableThread): 172 | """ Read serial data from the serial port and push to the 173 | event queue, until stopped. 174 | """ 175 | def __init__(self, serial, event_queue): 176 | super(SerialReader, self).__init__() 177 | self.baud = serial.baudrate 178 | self.serial = serial 179 | self.event_queue = event_queue 180 | if not hasattr(self.serial, 'cancel_read'): 181 | # enable timeout for checking alive flag, 182 | # if cancel_read not available 183 | self.serial.timeout = 0.25 184 | 185 | def run(self): 186 | if not self.serial.is_open: 187 | self.serial.baudrate = self.baud 188 | self.serial.rts = True # Force an RTS reset on open 189 | self.serial.open() 190 | self.serial.rts = False 191 | try: 192 | while self.alive: 193 | data = self.serial.read(self.serial.in_waiting or 1) 194 | if len(data): 195 | current_time=time.strftime("[%Y-%m-%d %H:%M:%S]", time.localtime()) 196 | data=data.replace("\n","\n"+current_time+' ') 197 | file_handler.write(data) 198 | file_handler.flush() 199 | self.event_queue.put((TAG_SERIAL, data), False) 200 | finally: 201 | self.serial.close() 202 | 203 | def _cancel(self): 204 | if hasattr(self.serial, 'cancel_read'): 205 | try: 206 | self.serial.cancel_read() 207 | except: 208 | pass 209 | 210 | 211 | class Monitor(object): 212 | """ 213 | Monitor application main class. 214 | 215 | This was originally derived from miniterm.Miniterm, but it turned out to be easier to write from scratch for this 216 | purpose. 217 | 218 | Main difference is that all event processing happens in the main thread, not the worker threads. 219 | """ 220 | def __init__(self, serial_instance, elf_file, make="make", toolchain_prefix=DEFAULT_TOOLCHAIN_PREFIX, eol="CRLF"): 221 | super(Monitor, self).__init__() 222 | self.event_queue = queue.Queue() 223 | self.console = miniterm.Console() 224 | if os.name == 'nt': 225 | sys.stderr = ANSIColorConverter(sys.stderr) 226 | self.console.output = ANSIColorConverter(self.console.output) 227 | self.console.byte_output = ANSIColorConverter(self.console.byte_output) 228 | 229 | self.serial = serial_instance 230 | self.console_reader = ConsoleReader(self.console, self.event_queue) 231 | self.serial_reader = SerialReader(self.serial, self.event_queue) 232 | self.elf_file = elf_file 233 | self.make = make 234 | self.toolchain_prefix = toolchain_prefix 235 | self.menu_key = CTRL_T 236 | self.exit_key = CTRL_RBRACKET 237 | 238 | self.translate_eol = { 239 | "CRLF": lambda c: c.replace(b"\n", b"\r\n"), 240 | "CR": lambda c: c.replace(b"\n", b"\r"), 241 | "LF": lambda c: c.replace(b"\r", b"\n"), 242 | }[eol] 243 | 244 | # internal state 245 | self._pressed_menu_key = False 246 | self._read_line = b"" 247 | self._gdb_buffer = b"" 248 | 249 | def main_loop(self): 250 | self.console_reader.start() 251 | self.serial_reader.start() 252 | try: 253 | while self.console_reader.alive and self.serial_reader.alive: 254 | (event_tag, data) = self.event_queue.get() 255 | if event_tag == TAG_KEY: 256 | self.handle_key(data) 257 | elif event_tag == TAG_SERIAL: 258 | self.handle_serial_input(data) 259 | else: 260 | raise RuntimeError("Bad event data %r" % ((event_tag,data),)) 261 | finally: 262 | try: 263 | self.console_reader.stop() 264 | self.serial_reader.stop() 265 | except: 266 | pass 267 | sys.stderr.write(ANSI_NORMAL + "\n") 268 | 269 | def handle_key(self, key): 270 | if self._pressed_menu_key: 271 | self.handle_menu_key(key) 272 | self._pressed_menu_key = False 273 | elif key == self.menu_key: 274 | self._pressed_menu_key = True 275 | elif key == self.exit_key: 276 | self.console_reader.stop() 277 | self.serial_reader.stop() 278 | else: 279 | try: 280 | key = self.translate_eol(key) 281 | self.serial.write(codecs.encode(key)) 282 | except serial.SerialException: 283 | pass # this shouldn't happen, but sometimes port has closed in serial thread 284 | 285 | def handle_serial_input(self, data): 286 | # this may need to be made more efficient, as it pushes out a byte 287 | # at a time to the console 288 | for b in data: 289 | self.console.write_bytes(b) 290 | if b == b'\n': # end of line 291 | self.handle_serial_input_line(self._read_line.strip()) 292 | self._read_line = b"" 293 | else: 294 | self._read_line += b 295 | self.check_gdbstub_trigger(b) 296 | 297 | def handle_serial_input_line(self, line): 298 | for m in re.finditer(MATCH_PCADDR, line): 299 | self.lookup_pc_address(m.group()) 300 | 301 | def handle_menu_key(self, c): 302 | if c == self.exit_key or c == self.menu_key: # send verbatim 303 | self.serial.write(codecs.encode(c)) 304 | elif c in [ CTRL_H, 'h', 'H', '?' ]: 305 | red_print(self.get_help_text()) 306 | elif c == CTRL_R: # Reset device via RTS 307 | self.serial.setRTS(True) 308 | time.sleep(0.2) 309 | self.serial.setRTS(False) 310 | elif c == CTRL_F: # Recompile & upload 311 | self.run_make("flash") 312 | elif c == CTRL_A: # Recompile & upload app only 313 | self.run_make("app-flash") 314 | else: 315 | red_print('--- unknown menu character {} --'.format(key_description(c))) 316 | 317 | def get_help_text(self): 318 | return """ 319 | --- idf_monitor ({version}) - ESP-IDF monitor tool 320 | --- based on miniterm from pySerial 321 | --- 322 | --- {exit:8} Exit program 323 | --- {menu:8} Menu escape key, followed by: 324 | --- Menu keys: 325 | --- {menu:7} Send the menu character itself to remote 326 | --- {exit:7} Send the exit character itself to remote 327 | --- {reset:7} Reset target board via RTS line 328 | --- {make:7} Run 'make flash' to build & flash 329 | --- {appmake:7} Run 'make app-flash to build & flash app 330 | """.format(version=__version__, 331 | exit=key_description(self.exit_key), 332 | menu=key_description(self.menu_key), 333 | reset=key_description(CTRL_R), 334 | make=key_description(CTRL_F), 335 | appmake=key_description(CTRL_A), 336 | 337 | ) 338 | 339 | def __enter__(self): 340 | """ Use 'with self' to temporarily disable monitoring behaviour """ 341 | self.serial_reader.stop() 342 | self.console_reader.stop() 343 | 344 | def __exit__(self, *args, **kwargs): 345 | """ Use 'with self' to temporarily disable monitoring behaviour """ 346 | self.console_reader.start() 347 | self.serial_reader.start() 348 | 349 | def prompt_next_action(self, reason): 350 | self.console.setup() # set up console to trap input characters 351 | try: 352 | red_print(""" 353 | --- {} 354 | --- Press {} to exit monitor. 355 | --- Press {} to run 'make flash'. 356 | --- Press {} to run 'make app-flash'. 357 | --- Press any other key to resume monitor (resets target).""".format(reason, 358 | key_description(self.exit_key), 359 | key_description(CTRL_F), 360 | key_description(CTRL_A))) 361 | k = CTRL_T # ignore CTRL-T here, so people can muscle-memory Ctrl-T Ctrl-F, etc. 362 | while k == CTRL_T: 363 | k = self.console.getkey() 364 | finally: 365 | self.console.cleanup() 366 | if k == self.exit_key: 367 | self.event_queue.put((TAG_KEY, k)) 368 | elif k in [ CTRL_F, CTRL_A ]: 369 | self.event_queue.put((TAG_KEY, self.menu_key)) 370 | self.event_queue.put((TAG_KEY, k)) 371 | 372 | def run_make(self, target): 373 | with self: 374 | yellow_print("Running make %s..." % target) 375 | p = subprocess.Popen([self.make, 376 | target ]) 377 | try: 378 | p.wait() 379 | except KeyboardInterrupt: 380 | p.wait() 381 | if p.returncode != 0: 382 | self.prompt_next_action("Build failed") 383 | 384 | def lookup_pc_address(self, pc_addr): 385 | translation = subprocess.check_output( 386 | ["%saddr2line" % self.toolchain_prefix, 387 | "-pfia", "-e", self.elf_file, pc_addr], 388 | cwd=".") 389 | if not "?? ??:0" in translation: 390 | yellow_print(translation) 391 | 392 | def check_gdbstub_trigger(self, c): 393 | self._gdb_buffer = self._gdb_buffer[-6:] + c # keep the last 7 characters seen 394 | m = re.match(b"\\$(T..)#(..)", self._gdb_buffer) # look for a gdb "reason" for a break 395 | if m is not None: 396 | try: 397 | chsum = sum(ord(p) for p in m.group(1)) & 0xFF 398 | calc_chsum = int(m.group(2), 16) 399 | except ValueError: 400 | return # payload wasn't valid hex digits 401 | if chsum == calc_chsum: 402 | self.run_gdb() 403 | else: 404 | red_print("Malformed gdb message... calculated checksum %02x received %02x" % (chsum, calc_chsum)) 405 | 406 | 407 | def run_gdb(self): 408 | with self: # disable console control 409 | sys.stderr.write(ANSI_NORMAL) 410 | try: 411 | subprocess.call(["%sgdb" % self.toolchain_prefix, 412 | "-ex", "set serial baud %d" % self.serial.baudrate, 413 | "-ex", "target remote %s" % self.serial.port, 414 | "-ex", "interrupt", # monitor has already parsed the first 'reason' command, need a second 415 | self.elf_file], cwd=".") 416 | except KeyboardInterrupt: 417 | pass # happens on Windows, maybe other OSes 418 | self.prompt_next_action("gdb exited") 419 | 420 | def main(): 421 | parser = argparse.ArgumentParser("idf_monitor - a serial output monitor for esp-idf") 422 | 423 | parser.add_argument( 424 | '--port', '-p', 425 | help='Serial port device', 426 | default=os.environ.get('ESPTOOL_PORT', '/dev/ttyUSB0') 427 | ) 428 | 429 | parser.add_argument( 430 | '--baud', '-b', 431 | help='Serial port baud rate', 432 | type=int, 433 | default=os.environ.get('MONITOR_BAUD', 115200)) 434 | 435 | parser.add_argument( 436 | '--make', '-m', 437 | help='Command to run make', 438 | type=str, default='make') 439 | 440 | parser.add_argument( 441 | '--toolchain-prefix', 442 | help="Triplet prefix to add before cross-toolchain names", 443 | default=DEFAULT_TOOLCHAIN_PREFIX) 444 | 445 | parser.add_argument( 446 | "--eol", 447 | choices=['CR', 'LF', 'CRLF'], 448 | type=lambda c: c.upper(), 449 | help="End of line to use when sending to the serial port", 450 | default='CRLF') 451 | 452 | parser.add_argument( 453 | 'elf_file', help='ELF file of application', 454 | type=argparse.FileType('r')) 455 | 456 | parser.add_argument( 457 | '--save_file','-sf', help='save the serial file', 458 | type=str) 459 | 460 | args = parser.parse_args() 461 | 462 | if args.port.startswith("/dev/tty."): 463 | args.port = args.port.replace("/dev/tty.", "/dev/cu.") 464 | yellow_print("--- WARNING: Serial ports accessed as /dev/tty.* will hang gdb if launched.") 465 | yellow_print("--- Using %s instead..." % args.port) 466 | 467 | serial_instance = serial.serial_for_url(args.port, args.baud, 468 | do_not_open=True) 469 | serial_instance.dtr = False 470 | serial_instance.rts = False 471 | 472 | args.elf_file.close() # don't need this as a file 473 | 474 | # remove the parallel jobserver arguments from MAKEFLAGS, as any 475 | # parent make is only running 1 job (monitor), so we can re-spawn 476 | # all of the child makes we need (the -j argument remains part of 477 | # MAKEFLAGS) 478 | try: 479 | makeflags = os.environ["MAKEFLAGS"] 480 | makeflags = re.sub(r"--jobserver[^ =]*=[0-9,]+ ?", "", makeflags) 481 | os.environ["MAKEFLAGS"] = makeflags 482 | except KeyError: 483 | pass # not running a make jobserver 484 | global file_handler 485 | file_handler=open(args.save_file,'w') 486 | monitor = Monitor(serial_instance, args.elf_file.name, args.make, args.toolchain_prefix, args.eol) 487 | 488 | yellow_print('--- idf_monitor on {p.name} {p.baudrate} ---'.format( 489 | p=serial_instance)) 490 | yellow_print('--- Quit: {} | Menu: {} | Help: {} followed by {} ---'.format( 491 | key_description(monitor.exit_key), 492 | key_description(monitor.menu_key), 493 | key_description(monitor.menu_key), 494 | key_description(CTRL_H))) 495 | 496 | monitor.main_loop() 497 | 498 | if os.name == 'nt': 499 | # Windows console stuff 500 | 501 | STD_OUTPUT_HANDLE = -11 502 | STD_ERROR_HANDLE = -12 503 | 504 | # wincon.h values 505 | FOREGROUND_INTENSITY = 8 506 | FOREGROUND_GREY = 7 507 | 508 | # matches the ANSI color change sequences that IDF sends 509 | RE_ANSI_COLOR = re.compile(b'\033\\[([01]);3([0-7])m') 510 | 511 | # list mapping the 8 ANSI colors (the indexes) to Windows Console colors 512 | ANSI_TO_WINDOWS_COLOR = [ 0, 4, 2, 6, 1, 5, 3, 7 ] 513 | 514 | GetStdHandle = ctypes.windll.kernel32.GetStdHandle 515 | SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute 516 | 517 | class ANSIColorConverter(object): 518 | """Class to wrap a file-like output stream, intercept ANSI color codes, 519 | and convert them into calls to Windows SetConsoleTextAttribute. 520 | 521 | Doesn't support all ANSI terminal code escape sequences, only the sequences IDF uses. 522 | 523 | Ironically, in Windows this console output is normally wrapped by winpty which will then detect the console text 524 | color changes and convert these back to ANSI color codes for MSYS' terminal to display. However this is the 525 | least-bad working solution, as winpty doesn't support any "passthrough" mode for raw output. 526 | """ 527 | 528 | def __init__(self, output): 529 | self.output = output 530 | self.handle = GetStdHandle(STD_ERROR_HANDLE if self.output == sys.stderr else STD_OUTPUT_HANDLE) 531 | self.matched = b'' 532 | 533 | def write(self, data): 534 | for b in data: 535 | l = len(self.matched) 536 | if b == '\033': # ESC 537 | self.matched = b 538 | elif (l == 1 and b == '[') or (1 < l < 7): 539 | self.matched += b 540 | if self.matched == ANSI_NORMAL: # reset console 541 | SetConsoleTextAttribute(self.handle, FOREGROUND_GREY) 542 | self.matched = b'' 543 | elif len(self.matched) == 7: # could be an ANSI sequence 544 | m = re.match(RE_ANSI_COLOR, self.matched) 545 | if m is not None: 546 | color = ANSI_TO_WINDOWS_COLOR[int(m.group(2))] 547 | if m.group(1) == b'1': 548 | color |= FOREGROUND_INTENSITY 549 | SetConsoleTextAttribute(self.handle, color) 550 | else: 551 | self.output.write(self.matched) # not an ANSI color code, display verbatim 552 | self.matched = b'' 553 | else: 554 | self.output.write(b) 555 | self.matched = b'' 556 | 557 | def flush(self): 558 | self.output.flush() 559 | 560 | 561 | if __name__ == "__main__": 562 | main() 563 | -------------------------------------------------------------------------------- /tools/setup_toolchain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # install softwares 5 | sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial 6 | 7 | # download toochain 8 | echo "create directory: esp/ in root directory" 9 | mkdir -p ~/esp 10 | cd ~/esp 11 | 12 | echo "download toochain fror esp official website" 13 | sys_bit=$(sudo uname --m) 14 | if [ "$sys_bit" = "x86_64" ] ; then 15 | wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-73-ge28a011-5.2.0.tar.gz 16 | tar -xzf xtensa-esp32-elf-linux64-1.22.0-73-ge28a011-5.2.0.tar.gz 17 | elif [ "$sys_bit" = "i686" ] ; then 18 | wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux32-1.22.0-73-ge28a011-5.2.0.tar.gz 19 | tar -xzf xtensa-esp32-elf-linux32-1.22.0-73-ge28a011-5.2.0.tar.gz 20 | else 21 | echo "please checkout you system, it is neither 32bit nor 64bit" 22 | exit 0 23 | fi 24 | 25 | # configure env_param 26 | echo "configure env_param" 27 | echo 'export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin' >> ~/.profile 28 | source ~/.profile --------------------------------------------------------------------------------