前言
本文以ESP-12F模组开办板为例,学习ESP8266 SDK 相关使?方法,包括编译前的准备、SDK 的编译和固件的下载,程序编写等。如有错误,请联系。 作者:孙韶辉
一、概述
SDK使用框图:
1.HDK(模组及开发板等硬件设备)
ESP8266 Hardware Development Kit(HDK)包括芯片 ESP8266EX、ESP8266模组以及 ESP8266开发板(比如NodeMcu)等硬件设备。用户使用烧录工具下载编译好的固件到硬件设备上。
2.ESP8266 SDK
ESP8266 Software Development Kit(SDK)是乐鑫为开发者提供的物联网(IOT)应用开发平台,包括基础平台以及上层应用开发示例等。
SDK的基础平台按照是否基于操作系统可分为:Non-OS 和 RTOS 两个版本。
版本 | 介绍 |
---|
non-OS | Non-OS SDK 是不基于操作系统的 SDK,提供 IOT_Demo 和 AT 的编译 | RTOS | RTOS SDK基于FreeRTOS,引入OS多任务处理机制(不学习) |
3.ESP8266 FW
ESP8266 Firmware (FW) 是一些可直接下载到 ESP8266 HDK 中的 BIN 文件,用户可以选择下载 Firmware Over-The-Air(FOTA,支持云端升级)和 non-FOTA(不支持云端升级)的 BIN 文件。
文件列表 | 是否必选 | 说明 | Non-FOTA | FOTA |
---|
esp_init_data_default.bin | 必选 | 初始化射频参数,在 SDK 根目录中提供。 | √ | √ | blank.bin | 必选 | 初始化系统参数,在 SDK 根目录中提供。 | √ | √ | eagle.flash.bin | 必选 | 主程序,编译代码生成 | √ | × | eagle.irom0text.bin | 必选 | 主程序,编译代码生成 | √ | × | boot.bin | 必选 | Bootloader,在 SDK 根目录中提供。 | × | √ | user1.bin | 初次使?用必选 | 主程序,编译代码生成 | × | √ | user2.bin | 升级时使 | 主程序,编译代码生成 | × | √ |
注意区分 Non-FOTA 和 FOTA 分别需要烧录哪些文件。这里主要学习 Non-FOTA
4.ESP8266 工具集
编译器
编译ESP8266 SDK需要使用Linux操作系统,若使用Windows操作系统,建议使用VirtualBox作为ESP8266虚拟机。为了简编译操作,乐鑫已编译SDK所需要的工具安装到虚机中。用户只需安装虚机,导入ESP8266编译器(OVA镜像文件)即可直接编译ESP8266 SDK
固件下载工具
ESP8266 DOWNLOAD TOOL工具是由乐鑫官方开发的固件下载工具,用户可根据实际的编译方式和Flash的容量,将多个BIN文件一键下载到ESP8266母板(开发板或者模组)的SPI Flash中。
串口调试工具
串口调试工具可以通过标准RS-232端口直接与ESP8266建立通信。对于不带有物理串口的PC,可以使用USB转串口模块来虚拟出一个串口设备。用户可以直接在串口终端输入命令和实时查看相关打印信息。
二、硬件准备
这里我用的是esp-12f做的开发板
三、软件准备
1.Non-OS SDK
Non-OS SDK内容
- bin:编译生成的BIN文件,可直接下载到Flash中。
- documents: SDK相关的文档或链接。
- driver lib:外设驱动的库文件,如: UART,12C和GPIO等。后面我们会把这里重命名为 app目录开发我们的用户程序
- examples:可供用户二次开发的示例代码,如1oT Demo等。
- include: SDK自带头文件,包含了用户可使用的相关API函数及其他宏定义,用户无需修改。需要什么直接调用头文件
- ld:链接时所需的脚本文件,若无特殊需求,用户无需修改。
- lib: SDK提供的库文件。
- tools:编BIN文件所需的工具,用户无需修改。
- third_party:第三方库,可以忽略
bin:编译生成的 BIN 文件,可直接下载到 Flash 中
2.软件环境搭建 —— 安信可一体化开发环境
运行IDE文件 点开这里,然后点import, 修改下,编译方式选择Cross GCC,不然会报错
3.编译nonos-Template
命名下载下来的SDK文件,这个APP就是我们编写程序的地方 然后进入examples内 复制这个文件夹内的东西,替换掉APP内的,然后删除掉examples文件夹
然后打开third_party文件,将Makefile命名为Makefile.bak 然后重新导入编译器中,这样就配置完毕 当我们导入成功工程之后,首次编译模板工程看看
正常的编译步骤:
- Clean Project
- Build Project
出现这个编译成功
四、Flash布局
布局说明
存储大小位置修改
用户可以通过修改ESP8266-NONOS-SDKId/eagle.app.v6.ld文件来改变eagle.iromOtext.bin的上限值,即修改文件中iromo-o-seg参数的len字段,如图4-2中红色标示。 不同版本SDK中irom0.text文件的地址也不同。用户必须查阅eagle.app.v6.ld文件,确保将eagle.irom0.text.bin下载到正确的地址。图4-2中蓝色标示即为eagle.irom0.text.bin的地址。 不不同的 Flash 容量量,len 的值和修改后 eagle.irom0text.bin 的存储上限值如表 4-1 所示。 ESP8266 目前系统程序区最大支持 1024 KB。
下载地址
一般烧录,请使?工具 ESP Flash Download Tool,建议按照烧录地址从低到高按顺序排列列烧录。
烧录工具
- 进入 Windows系统。
- 2·双击ESP-DOWNLOAD-TOOL.exe打开Flash工具。
参照这表,依次从低位到高位烧入
五:SDK程序架构
1.普通单片机的程序运行是基于“主循环”的方式
main.c文件中: int main (void) //程序入口 { 初始化.: // 10口、定时器、设置中断 while(1) { … //主循环,完成程序功能 } return 0; } void xxxIRQHandler (void)//中断函数 { …//执行中断处理
}
2.ESP8266的SDK编程是基于“内核回调”的方式
user main.c文中:
void user_init (void);
{
....初始化;
}
{
..........
user_init()
while()
{
}
}
void xxxcb(void)
{
.......
}
void xxx Task (void)
{
......
}
void xxx_IRQHandler (void)
{
......
}
3.乐鑫官方SDK API使用说明
参考资料《ESP8266 Non-OS SDK API》
1.简介说明
- Non-OS SDK简介Non-OS SDK为用户提供了一套应用程序编程接口(AP),能够实现ESP8266的核心功能改,例如数据接收/发送、TCPIP功能、硬件接口功能,以及基本的系统管理功能等。用户不必关心底层网络,如Wi-Fi,TCP/IP等的具体实现,只需要专注于物联网上层应用的开发,利用相应接口实现各种功能即可。
- ESP8266物联网平台的所有网络功能均在库中实现,对用户不透明。用户应用的初始化功能可以在user-main.c中实现。
- void user-init(void)是上层程序的入口函数,给用户提供一个初始化接口,用户可在该函数内增加硬件初始化、网络参数设置、定时器初始化等功能。
? 对于ESP8266-NONOS-SDK-v3.0.0及之后版本,请在user-main.c增加函数 void ICACHE-FLASHATTR user-pre-init(void) ,并且在user-pre-init中注册自己的partition table. ? 对于ESP8266NONOS-SDK-v1.5.2至ESP8266NONOS-SDK-v2.2.1之间的版本,请在user-main.c增加函数void user-rf-pre-init(void)和uint32user_rf-cal_sector_set(void),可参考10TDemo的user-main.c。用户可在user_rf_pre_init中配置RF初始化, RF设置接口为system_phy_set_rfoption,或者在Deep-sleep前调用system_deep-sleep-set_option,如果设置为RF不打开,则ESP8266 Station及SoftAP均无法使用,请勿调用Wi-F相关接口及网络功能。RF关闭时, Wi-Fi射频功能和网络堆栈管理API均无法使用。 对于ESP8266NONOS-SDK-v2.1.0及之后版本,用户如果并未使用DIO-To-QIO flash,可以在user-main.c中增加空函数void user-spi-flash-dio-to-qio-pre-init(void)来优化iRAM空间。SDK中提供了对JSON包的处理API,用户也可以采用自定义数据包格式, 自行对数据进行处理。
2. 代码结构
Non-OS SDK中的代码结构具有以下特征:, Non-OS SDK不像基于RTOS的应用程序支持任务调度。Non-OS SDK使用四种类型的函数:
- 应用函数
- 回调函数
- 用户任务
- 中断服务程序(Interrupt Service Routines, ISR)
-
应用函数 类似于嵌入式C编程中的常用C函数。这些函数必须由另一个函数调用。应用函数在定义时建议添加ICACHE-FLASH-ATTR宏,相应程序将存放在flash中,被调用时才加载到cache运行。而如果添加了IRAM_ATTR宏的函数,则会在上电启动时就加载到iRAM中 -
回调函数 是指不直接从用户程序调用的函数,而是当某系统事件发生时,相应的回调函数由non-OS SDK内核调用执行。这使得开发者能够在不使用RTOS或者轮询,事件的情况下响应实时事件。 要编写回调函数,用户首先需要使用相应的register_cb API注册回调函数。回调函数的示例包括定时器回调函数和网络事件回调函数。 -
中断服务程序(ISR) 是一种特殊类型的回调函数。发生硬件中断时会调用这些函数。当使能中断时,必须注册相应的中断处理函数。请注意, ISR必须添加IRAM_ATTR。 -
用户任务 可以分为三个优先级: 0,1、2,任务优先级为2>1>0,即Non-OSSDK最多只支持3个用户任务,优先级分别为0、1、2·用户任务一般用于函数不能直接被调用的情况下。要创建用户任务,请参阅本文档中的system_os_task()的API描述。例如, espconn-disconnect() API不能直接在espconn的回调函数中调用,因此建议开发者可以在espconn回调中创建用户任务来执行espconn_disconnect.
六. 调用API,添加源文件
参考资料《ESP8266 Non-OS SDK API》
1. 调用到的2个接口及头文件
在编写程序前,要调用这2接口的头文件
2. 串口打印“Hello world”和版本信息
在初始化函数中写入我们要用的程序
user_init(void)
{
os_printf("\r\n-----------\r\n");
os_printf("SDK version: %s \n", system_get_sdk_version());
os_printf("\r\nHello World\r\n");
os_printf("\r\n------------\r\n");
}
下载 打开串口助手
3. 设置串口信息
如何设置串口的波特率、数据格式?需要调用串口驱动函数
将此串口C文件复制添加到我们的工程里 将头文件也同样的复制添加到我们的工程内 然后打开编译器,刷新 能看到这三个,说明已经将文件成功添加进工程了 然后在程序调用头文件 打开串口C文件 当波特率!=74880时, ESPB266复位后,会打印一些信息(乱码),这是正常的。因为内核在初始化时,会默认从UART_0打印一些初始化信息。 使用40MHz晶振时,该段打印波特率为115200T 使用26MHz晶振时,该段打印波特率为74880 (ESP-12F) 调整波特率以后,上面系统初始化文件为乱码为正常
七.看门狗
- 参考资料《ESP8266 Non-OS SDK API》
- 如前所述, non-OS SDK不支持抢占任务或进程切换。因此开发者需要自行保证程序的正确执行,用户代码不能长期占用CPU,否则会导致看门狗复位, ESP8266重启。
- 如果某些特殊情况下,用户线程必须执行较长时间(比如大于500 ms) ,建议经常调用system-soft-wdt_feed() API来喂软件看门狗,而不建议禁用软件看门狗。
1. 看门狗函数
2.函数所调用的头文件
3. 程序模拟用户长时间占用CPU,看门狗重启
看门狗启动,系统一直复位重启
4.调用喂狗程序
八.ESP8266的延迟函数delay
1.delay函数
2.调用的头文件
3.编写延迟秒函数
4 .串口打印函数
每隔一秒,串口接受到一个信息
九.设置8266的GPIO接口为输出模式
参考技术资料《ESP8266 Non-OS SDK API》《ESP8266-技术参考手册》 《ESP8266-管脚清单》《ESP8266物联网开发板原理图》
1.实现功能
让LED2 闪烁 开发板原理图👆
1.设置IO口功能
1.需要调用的头文件及C文件
2.管脚功能选择
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPI012);
参数里,前面是代表管脚,后面代表实现的功能。 main.c函数中调用头文件
3.ESP-12F和ESP8266芯片管脚位置和名称对应图
- ESP-12F 模组共接出16 个接口,如管脚示意图,管脚功能定义表是接口定义。此图为模组背面视角
ESP-12F 管脚示意图 表管脚功能定义
参考官方资料,GPIO4第一个功能为IO口 官方说明
2.设置IO口为输出模式
函数位置
1.实例
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,0);
GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);
```c
user_init(void)
{
u8 LED=1;
uart_init(115200,115200);
os_delay_us(1000);
os_printf("\n\r----------------------");
os_printf("\n\rHello,Wolrd");
os_printf("\n\rSDK version: %s \n", system_get_sdk_version());
os_printf("\r------------------------\n\r");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,0);
GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);
while(1)
{
system_soft_wdt_feed();
LED=!LED;
delayms(500);
os_printf("\n\rhello,孙韶辉");
GPIO_OUTPUT_SET(GPIO_ID_PIN(4), LED);
}
}
补充理解:经测试,【gpio_no】可直接写GPIO口的序列号 4可以运行,不一定要用官方的宏定义,太麻烦
3.设置管脚为输入模式(读引脚状态)
1:思路
设置管脚功能属性是IO口还是其他
设置管脚输入输出宏输出输入或关闭
设置IO口为上拉或下拉
while循环
喂狗函数
判断读取端口状态函数
执行函数
循环
2:函数库各函数官方解释
- 设置管脚功能属性是IO口还是其他
- 设置管脚输入输出宏输出输入或关闭
- 设置IO口为上拉或者下拉
- 喂狗函数
- 获取IO口状态
- 执行函数
LED点亮
3.实例
user_init(void)
{
uart_init(115200,115200);
os_delay_us(1000);
os_printf("\n\r----------------------");
os_printf("\n\rHello,Wolrd");
os_printf("\n\rSDK version: %s \n", system_get_sdk_version());
os_printf("\r------------------------\n\r");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U ,0);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U,0);
GPIO_OUTPUT_SET(GPIO_ID_PIN(0), 1);
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U);
while(1)
{
system_soft_wdt_feed();
if( GPIO_INPUT_GET(4)==0)
{
os_printf("\n\rhello,孙韶辉");
GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 0);
}
else
{
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1);
}
}
}
十.入门完结
到此位置,相信大家已经对SDK编程有一定的了解了,现在完全可以自己下载和查阅SDK相关文档了。
|