物联网之WiFi二

1、ESP8266 SDK介绍

2、FreeRTOS工作原理

3、第一个任务hello word

4、第二个任务点灯

5、WiFi-STATION&AP连接

ESP8266 SDK介绍

1、SDK 目录结构

2、SDK API接口

3、编译工程模板

SDK 目录结构

SDK目录结构

Bin目录:(重点使用的目录

编译形成的BIN文件,可直接下载到Flash中 

    根目录下为官方提供的bin文件(一般烧写最新版本的bin文件:boot_v1.7.bin

    Upgrade为工程编译后生成的用户代码

documents目录:(重点使用的目录

SDK 相关的文档或链接

    PDF文档为API参考手册,相当于STM32的标准库

    html网页版的API参考手册

driver_lib目录:(重点使用的目录

ESP8266外设驱动代码

    Driver:外设驱动源码

    Include:外设驱动头文件

    Makefile:外设驱动自动编译脚本

    Make_lib.sh 外设驱动shell脚本

example目录:(重点使用的目录

ESP8266示例代码

    mqtt_demo:mqtt协议示例代码

    openssl:OpenSSL接口功能代码

    Project_template:工程模板

    Smart_config: 智能联网示例代码(我们目前使用官方提供的这个示例代码

    spiffs: SPI文件系统代码

    websocket_demo: WEB网络编程代码

    Wifi_station_machine_demo: wifi站点示例代码

    wps: wifi 保护设置示例代码

extra_include目录:ESP8266-xtensa内核接口(重点使用的目录

include目录:SDK 自带头文件,包含了用户可使用的相关 API 函数及其他宏定义,用户无需修改。(重点使用的目录

ld目录:链接时所需的脚本文件,如无特殊需求,用户无需修改(不需要了解)

lib目录:SDK 提供的库文件。(不需要了解)

third_party目录:乐鑫开放源代码的第三方库,当前包含 freeRTOS、 JSON、 lwIP、mbedTLS、 noPoll、 OpenSSL、SPIFFS 和 SSL。 (不需要了解)

tool目录:编译 BIN 文件所需的工具,用户无需修改(不需要了解)

SDK API接口

API接口

序号

接口名称

接口说明

1

WiFi Related APIs  

WiFi相关的接口

2

AirKiss APIs  

AirKiss的接口

3

SoftAP APIs  

软件无线接入点接口

4

Station APIs  

站点接口

5

Common APIs  

通用接口

6

Force Sleep APIs  

休眠接口

7

Rate Control APIs  

速率控制接口

8

User IE APIs  

用户接口

9

Sniffer APIs  

嗅探器接口

10

WPS APIs  

无线安全设置接口

11

Smartconfig APIs  

智能联网接口

12

Misc APIs  

混合接口

13

Spiffs APIs  

SPI文件系统接口

14

SSC APIs  

SSC接口 

15

System APIs  

系统接口

16

Boot APIs  

启动接口

17

Upgrade APIs  

云端升级接口

18

Software timer APIs  

软件定时器接口

19

Network Espconn APIs  

ESP网络接口

20

ESP-NOW APIs  

ESP接口

21

Mesh APIs  

网状网络接口

22

Driver APIs  

外设驱动接口

23

PWM Driver APIs  

脉宽调制接口

24

SPI Driver APIs  

SPI通信接口

25

GPIO Driver APIs  

通用IO接口

26

Hardware timer APIs

硬件定时器接口

27

UART Driver APIs

串口通信接口

编译工程模板

搭建app目录

在SDK目录下新建app目录

cd 到examples目录下

拷贝smart_config下所有文件到app目录下

cd 到app目录下查看文件是否拷贝成功

修改gen_misc.sh

vim 打开gen_misc.sh进行编辑

修改SDK_PATH为当前SDK路径(绝对)

修改BIN_PATH为当前BIN路径(绝对)

export SDK_PATH=$/home/esp8266/Share/ESP8266_RTOS_SDK-2.0.0
export BIN_PATH=$/home/esp8266/Share/ESP8266_RTOS_SDK-2.0.0/bin

Wq保存退出

修改Makefile

因为分离了sdk和project目录,所以编译之前必须先指定一个 SDK_PATH 和 BIN_PATH,修改 ESP8266_RTOS_SDK/app 目录下的 makefile,添加以下内容:

parent_dir:=$(abspath $(shell pwd)/$(lastword $(MAKEFILE_LIST)))
parent_dir:=$(shell dirname $(parent_dir))
parent_dir:=$(shell dirname $(parent_dir))

SDK_PATH= $(parent_dir)
BIN_PATH=$(SDK_PATH)/bin

编译

./gen_misc.sh

运行gen_misc脚本进行编译

编译配置

FreeRTOS实时操作工作原理

1、FreeRTOS实时操作系统

2、FreeRTOS任务

3、FreeRTOS使用说明

FreeRTOS实时操作系统

前后台系统

早期嵌入式开发没有嵌入式操作系统的概念 ,直接操作裸机,在裸机上写程序,比如用51单片机基本就没有操作系统的概念。通常把程序分为两部分:前台系统和后台系统。

RTOS系统

RTOS全称为:Real Time OS,就是实时操作系统,强调的是:实时性。实时操作系统又分为硬实时和软实时。硬实时要求在规定的时间内必须完成操作 ,硬实时系统不允许超时,在软实时里面处理过程超时的后果就没有那么严格。

在实时操作系统中,我们可以把要实现的功能划分为多个任务,每个任务负责实现其中的一部分,每个任务都是一个很简单的程序,通常是一个死循环。

RTOS操作系统:FreeRTOS,UCOS,RTX,RT-Thread,DJYOS等。

RTOS操作系统的核心内容在于:实时内核。

可剥夺型内核

可剥夺内核顾名思义就是可以剥夺其他任务的CPU使用权,它总是运行就绪任务中的优先级最高的那个任务。

RTOS的内核负责管理所有的任务,内核决定了运行哪个任务,何时停止当前任务切换到其他任务,这个是内核的多任务管理能力。多任务管理给人的感觉就好像芯片有多个CPU,多任务管理实现了CPU资源的最大化利用,多任务管理有助于实现程序的模块化开发,能够实现复杂的实时应用。

RTOS工作机制

FreeRTOS介绍

FreeRTOS是一个可裁剪、可剥夺型的多任务内核,而且没有任务数限制。FreeRTOS提供了实时操作系统所需的所有功能,包括资源管理、同步、任务通信等。

FreeRTOS特点:

    FreeROTS开源

    FreeRTOS免费

    FreeRTOS是很多第三方组件钦定的系统!

FreeRTOS使用

FreeRTOS下载: http://www.freertos.org/

FreeRTOS还是有一定难度的,在学习的过程中难免会遇到看不懂的东西,如果遇到不懂的就先不要管,开发ESP8266只需要学会怎么调用FreeRTOS的API函数

对C语言的要求,需要了解指针、结构体、数据结构中的链表等。

FreeRTOS任务

FreeRTOS任务特性

简单

没有使用限制

支持抢占

支持优先级

每个任务都拥有堆栈导致了 RAM 使用量增大

如果使用抢占的话的必须仔细的考虑重入的问题 

FreeRTOS任务状态:运行态、就绪态、 阻塞态、挂起态

FreeRTOS任务优先级

任务优先级决定了任务的执行优先级别,在FreeRTOS中任务优先级可选范围为:
 0 ~ configMAX_PRIORITIES-1

数字越大,优先级越高!

FreeRTOS任务创建函数

头文件:task.h
portBASE_TYPE xTaskCreate (
pdTASK_CODE pvTaskCode, 指向任务的实现函数的指针。效果上仅仅是函数名
const portCHAR * const pcNane, 具有描述性的任务名。FreeRTOS 不会使用它。
unsigned portSHORT usStackDepth, 指定任务堆栈的大小(4个字节为单位,如该项填写256表示堆栈有1024个字节)
void *pvParameters, 指针用于作为一个参数传向创建的任务
unsigned portBASE_TYPE uxPriority, 任务运行时的优先级(重要)
xTaskHandle *pvCreatedTask 用于传递任务的句柄,可以引用从而对任务进行其他操作。(一般不使用)
) 

FreeRTOS任务延时函数

头文件:task.h
void vTaskDelay (//如果填写的是1秒钟,实际返回的任务往往大于1秒钟(软实时)
portTickType xTicksToDelay 时间数量,调用任务应该锁住的时间片周期
)
void vTaskDelayUntil (//精准延时(硬实时)
portTickType *pxPreviousWakeTime, 指定一个变量来掌握任务最后开启的时间, 第一次使用时必须
使用当前时间来初始化, 在 vTaskDelayUntil 中,这个变量是自动修改的
portTickType xTimeIncrement 循环周期时间
)

FreeRTOS任务删除函数

头文件:task.h
void vTaskDelete (
xTaskHandle pxTask 处理要删除的任务。传递 NULL 将删除自己
)

FreeRTOS任务实现函数模板

void ATaskFunction( void *pvParameters )
{
/* 可以像普通函数一样定义变量。用这个函数创建的每个任务实例都有一个属于自己的iVarialbleExample变
量。但如果iVariableExample被定义为static,这一点则不成立 – 这种情况下只存在一个变量,所有的任务实
例将会共享这个变量。 */
int iVariableExample = 0;
/* 任务通常实现在一个死循环中。 */
for( ;; )
{
/* 完成任务功能的代码将放在这里。 */
}
/* 如果任务的具体实现会跳出上面的死循环,则此任务必须在函数运行完之前删除。传入NULL参数表示删除
的是当前任务 */
vTaskDelete( NULL );
} 

FreeRTOS任务优先级函数

头文件:task.h
unsigned portBASE_TYPE uxTaskPriorityGet (//获取优先级
xTaskHandle pxTask 需要处理的任务. 当传递 NULL 时,将返回调用该任务的优先级
)
void vTaskPrioritySet (//设置优先级
xTaskHandle pxTask , 需要设置优先级的任务。当传递 NULL,将设置调用任务的优先级
unsigned portBASE_TYPE uxNewPriority 任务需要设置的优先级
)

FreeRTOS任务挂起函数

头文件:task.h
void vTaskSuspend (//比如低功耗任务下需要调用该函数挂起其他任务
xTaskHandle pxTaskToSuspend 处理需要挂起的任务。传递 NULL 将挂起调用此函数的任务
)
void vTaskResume (//比如退出低功耗时需要运行其他任务,则调用该函数
xTaskHandle pxTaskToResume 就绪任务的句柄
)

FreeRTOS使用说明

FreeRTOS使用

RTOS SDK 的系统任务优先级为 15 ,创建任务的接口 xTaskCreate 为 freeRTOS 自带接口,使用 xTaskCreate 创建任务时,任务堆栈设置范围为 [176, 512]

在任务内部如需使使用度超过 60 的大数组,建议使用malloc 和 free 的方式操作,否则,大数组将占用任务的堆空间;

SDK 底层已占用部分优先级: pp task 优先级 13,精确 ets timer 线程优先级 12, lwip task优先级 10, freeRTOS timer 优先级 2, idle 优先级 0;

可供用户线程使用的优先级为 1 ~ 9,请勿修改 FreeRTOSConfig.h,优先级由 SDK 底层决定,此处修改头文件并不能生效。

第一个任务hello word

1、Source Insight安装

2、功能分析

3、功能实现

Source Insight安装

功能分析

使用freeRTOS新建一个任务,定时1秒,串口打印hello word

功能实现

新建hello word工程目录

在SDK目录下新建helloword:

拷贝app目录下所有文件到helloword:

SourceInsight下新建工程


代码实现

在user_main.c下实现helloword任务(打开user_main.c文件进行编码:user_main.c文件为函数入口

在user_init下新建helloword任务

/******************************************************************************
 * FunctionName : ATaskHelloWord
 * Description  : hello word
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskHelloWord( void *pvParameters )//helloword任务实现函数
{
    int iVariableExample = 0;
    
    for(;;)
    {

        printf("hello word!\n");
        vTaskDelay(100);//延时1秒钟
    }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    printf("SDK version:%s\n", system_get_sdk_version());

    /* need to set opmode before you set config */
   // wifi_set_opmode(STATION_MODE);

   // xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL, 2, NULL);
	xTaskCreate(ATaskHelloWord, "hello word", 256, NULL, 2, NULL);//helloword任务创建
}

功能调试

编译文件

烧写bin文件

使用串口调试工具,设置波特率为74880(SDK默认的boot的uart配置就是74880),查看打印日志

第二个任务点灯

1、功能分析

2、原理图分析

3、功能实现

功能分析

使用freeRTOS新建一个任务,使nodeMcu板上LED灯,1秒钟闪烁一次

原理图分析

功能实现

新建led工程目录

在SDK目录下新建led目录:

拷贝helloword目录下所有文件到led目录下:

添加外设驱动文件

led目录下新建driver目录

拷贝driver_lib/driver下所有文件到led/driver下

添加外设驱动文件

拷贝driver_lib/include下所有文件到led/include下:

修改Makefile

添加工程编译子目录driver:

生成libdriver.a静态库:

wq保存

Sourceinsight配置

代码实现

在user_main.c下,添加

    Led初始化

    Led任务

在user_init下

    使用led初始化

    新建led任务

Led初始化

包涵gpio.h

配置GPIO16为输出模式

设置GPIO16为高电平输出

user_main.c

#include "gpio.h"

/******************************************************************************
 * FunctionName : Led_init
 * Description  : led初始化 Parameters   : none
 * Returns      : none
*******************************************************************************/
void Led_init( void )
{
    gpio16_output_conf();//GPIO16设置为输出模式
    gpio16_output_set(1);//GPIO16引脚拉高,此时灯灭
}

Led任务

user_main.c

/******************************************************************************
 * FunctionName : ATaskLed
 * Description  : Led 实现函数
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskLed( void *pvParameters )//任务实现函数
{
    int iVariableExample = 0;
    
    for(;;)
    {
        gpio16_output_set(0);
        printf("ledon\n");
        vTaskDelay(100);
        gpio16_output_set(1);
        printf("ledoff\n");
        vTaskDelay(100);
    }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    printf("SDK version:%s\n", system_get_sdk_version());
    Led_init();

    /* need to set opmode before you set config */
   // wifi_set_opmode(STATION_MODE);

    //xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL, 2, NULL);
    xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);//添加任务
}

WiFi-Station&AP连接

1、功能分析

2、Station功能实现

3、AP功能实现

功能分析

配置WiFi为Station模式,连接到本地的WiFi网络里

配置WiFi为AP模式,PC机连接到WiFi AP下

Station功能实现

WiFi Station入网条件

本地有WiFi网络

    SSID:WiFi网络名称

    PASSWORD:WiFi入网密码

WiFi Station入网流程

新建Station工程目录

在SDK目录下新建Station目录

拷贝led目录下所有文件到Station目录下

Sourceinsight配置

代码实现

在user_init下完成WiFi Station功能开发:

user_main.c

#define SSID "chuangkexueyuan"//wifi账号
#define PASSWORD "makeru2017"//wifi密码
/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    printf("SDK version:%s\n", system_get_sdk_version());
    Led_init();
    wifi_set_opmode(STATION_MODE);//配置WiFi为Station模式
    struct station_config *config = (struct station_config *)\
        zalloc(sizeof(struct station_config));//动态的分配内存空间
    sprintf(config->ssid,SSID);
    sprintf(config->password,PASSWORD);

    wifi_station_set_config(config);//配置设置到寄存器里面
    free(config);//释放动态分配的内存

    wifi_station_set_auto_connect(TRUE);//启动wifi的一键连接
    
    /* need to set opmode before you set config */
   // wifi_set_opmode(STATION_MODE);

    //xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL, 2, NULL);
    xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);
}

验证测试

烧写固件

复位查看串口日志,获取到路由器分配的IP

AP功能实现

WiFi AP建立条件

SSID:WiFi网络名称(定义为自己的名字)

PASSWORD:WiFi入网密码(123456789)

加密模式:WAP2_PSK

WiFi AP建立流程

新建AP工程目录

在SDK目录下新建AP目录

拷贝Station目录下所有文件到AP目录下

Sourceinsight配置

代码实现

user_main.c

#define SSID "liuzhengdao"
#define PASSWORD "123456789"
/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    printf("SDK version:%s\n", system_get_sdk_version());
    Led_init();
    wifi_set_opmode(SOFTAP_MODE);//设置为AP模式
    struct softap_config *config = (struct softap_config *)\
        zalloc(sizeof(struct softap_config));
    wifi_softap_get_config(config);//获取当前参数
    sprintf(config->ssid,SSID);//传入自己定义的网络名称
    sprintf(config->password,PASSWORD);//传入自己定义的网络密码
    config->authmode = AUTH_WPA_WPA2_PSK;//授权加密方式
    config->ssid_len = 0;//设置网络名称长度为0,表示网络名称字符串中遇到'\0'时结束。
    config->max_connection = 4;//设置最大连接数

    wifi_softap_set_config(config);//设置到寄存器
    free(config);//释放动态存储

    //wifi_station_set_auto_connect(TRUE);
    
    /* need to set opmode before you set config */
   // wifi_set_opmode(STATION_MODE);

    //xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL, 2, NULL);
    xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);
}

验证测试

烧写固件

复位查看串口日志,PC连接AP,获取AP分配的IP地址

猜你喜欢

转载自blog.csdn.net/weixin_39148042/article/details/82057046