目录说明: bin 编译固件生成目录、boot、配置参数bin文件所在 et_app 用户应用程序所在目录 extra_include 一些第三方库头文件目录 include 系统相关头文件所在目录 ld 连接器相关一些东西 lib 系统相关一些库(如LWIP之类的) third_party 第三方源码库和相关源代码(如操作系统,JOSN) tools 编译过程中一些工具 Makefile 编译的Makefile文件 LICENSE、 README.md 都是一些说明文本文件
et_app 是应用程序的主目录,下面就这目录进行下一步说明
.output 编译过程中一些早间文件 driver 驱动相应源代码目录 include 头文件所在目录 sample_lib 示例库文件所在目录(没有使用) user 用户应用程序所在目录 gen_misc.bat 编译整个工程源码脚本 gen_misc.sh 编译整个工程源友脚本(linux 使用) makefile Makefile文件 readme.txt 说明文件
user 目录是应用程序所在目录,下面进一步说明
user_main.c 应用程序入口函数所在文件 et_user_app.c 主应用程序所在 factory.c 工厂测试代码所在,可以不关注 wifi_led.c wifi LED灯控制程序所在 Makefile makefile 管理文件
特别说明一下,如果开发者要新增加文件,可以直接在这个目录下面增加.c 文件,把.h文件放在和级目录的inlcude目录下面,就可以了。
下面分析对于主要文件的函数进行一下说明,让大家了解整个源码实现过程:
user_main.c 中的 user_init 这是整个应用程序的入口函数,程序先进入这里执行:
- void user_init(void)
- {
- key_gpio_t key;
- struct station_config config;
- struct ip_info info;
- et_uchar result=0;
- os_printf("now SDK version:%sn", system_get_sdk_version());
-
- if(get_fac_norm_mode(&result) != SPI_FLASH_RESULT_OK)
- {
- os_printf("get_fac_norm_mode error, NORMAL moden");
- }
- if(result == FAC_MODE)
- {
- os_printf("run in factory moden");
- uart_init_new_uart1(BIT_RATE_115200);
- UART_SetPrintPort(UART1);
- uart_init_new(BIT_RATE_9600, result);
- return;
- }
-
- os_printf("run in normal moden");
- // show logo
- user_show_logo();
-
- if (RETURN_OK != user_get_work_mode(&work_mode))
- {
- os_printf("get work mode fail !!!n");
- return;
- }
-
- if (RETURN_OK != user_init_work_mode(work_mode, result))
- {
- os_printf("init work mode fail !!!n");
- return;
- }
- // wifi led control
- xTaskCreate(user_wifi_led_control, "wifi_led_control", 256, NULL, 2, NULL);
- //wifi event handle
- wifi_set_event_handler_cb(et_wifi_event_cb);
- memset(&key, 0, sizeof(key_gpio_t));
- key.key_gpio_pin = AIRKISS_KEY_IO_PIN;
- key.key_num = AIRKISS_KEY_IO_NUM;
-
- airkiss_key_init(&key);
- wifi_set_opmode(STATION_MODE);
-
- wifi_reconnect_start_flag = 0;
-
- xTaskCreate(airkiss_key_poll_task, "smartconfig_task", 256, NULL, 2, NULL);
-
- memset(&config, 0, sizeof(struct station_config));
- if(wifi_station_get_config_default(&config) == true)
- {
- os_printf("ssid=%sn", config.ssid);
- wifi_station_set_config_current(&config);
- //for static ip set
- /*wifi_station_dhcpc_stop();
- IP4_ADDR(&info.ip, 192, 168, 1, 43);
- IP4_ADDR(&info.gw, 192, 168, 1, 1);
- IP4_ADDR(&info.netmask, 255, 255, 255, 0);
- wifi_set_ip_info(STATION_IF, &info);*/
- }
- os_timer_disARM(&test_timer);
- os_timer_setfn(&test_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL);
- os_timer_arm(&test_timer, 1000, 0);
-
- }
复制代码
然后从这个源码里,可以看出,这进而进行了一系列的操作,先是判断是正常模式,还是工厂生产模式,如果是正常模式,接下通过ADC读取当时的程序所在模式(就是档位开关,这就是一档(显示屏,温度)等的由来),接着创建WIFI指示灯和airkiss工作线程,然后会试图去连接WIFI,并启动定时器去监听WIFI连接是否完成。
在监听WIFI是否完成的定时器回调函数里:
- void ICACHE_FLASH_ATTR
- user_esp_platform_check_ip(void)
- {
- static et_uint32 time = 0;
- struct ip_info ipconfig;
-
- os_timer_disarm(&test_timer);
- //get ip info of ESP8266 station
- wifi_get_ip_info(STATION_IF, &ipconfig);
- if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0)
- {
- os_printf("got ip !!! rn");
- user_set_wifi_led_on();
- if (user_main_start_flag == 0)
- {
- user_main_start_flag = 1;
- xTaskCreate(et_user_main, "et_user_main", 512, NULL, 5, NULL);
- }
- wifi_reconnect_start_flag = 1;
- }
- else
- {
- if (wifi_station_get_connect_status() == STATION_WRONG_PASSWORD
- || wifi_station_get_connect_status() == STATION_NO_AP_FOUND
- || wifi_station_get_connect_status() == STATION_CONNECT_FAIL)
- {
- if ((system_get_time() - time) >= 5000000)
- {
- os_printf("connect fail wrong password or ssid wrong!!! rn");
- time = system_get_time();
- }
- if (air_kiss_start_flag == 1)
- {
- wifi_station_set_reconnect_policy(false);
- smartconfig_stop();
- air_kiss_start_flag = 0;
- }
- }
- //re-arm timer to check ip
- os_timer_setfn(&test_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL);
- os_timer_arm(&test_timer, 1000, 0);
- }
- }
-
- 我们可以看到,如果获取IP地址成功,将会启动et_user_main线程开始真正的任务循环,同时会点亮LED显示灯。
-
- 在et_user_app.c 的et_user_main中,
-
- void et_user_main(void *pvParameters)
- {
- et_int32 rc = -1;
- et_int32 num = 0;
- id_info_t *id;
- /* g_cloud_con_para.auto_relogin = TRUE;
- g_cloud_con_para.clr_offline_mes = TRUE;
- g_cloud_con_para.server_addr = ADDRESS;
- g_cloud_con_para.server_port = PORT;*/
- os_printf("ET U-SDK var%sn",et_sdk_var());
- to_stop_app = 0;
-
- id = (id_info_t *)malloc(sizeof(id_info_t));
- if(id == NULL)
- {
- os_printf("et_user_main, malloc id failedn");
- return ;
- }
- memset(id, 0, sizeof(id_info_t));
- if(get_uid(id) != SPI_FLASH_RESULT_OK)
- {
- os_printf("et_user_main, get_uid errorn");
- free(id);
- return ;
- }
- id->uid[UID_LEN - 1] = '\0';
- id->appkey[APPKEY_LEN - 1] = '\0';
- g_cloud_handle = et_create_context(id->uid, id->appkey, SECRETKEY);
- if(NULL == g_cloud_handle)
- os_printf("Init et account failedn");
- et_set_callback(g_cloud_handle,et_message_process, et_event_process);
- rc = et_start_svr(g_cloud_handle);
-
- if(rc != 0)
- {
- os_printf("et_start_svr failn");
- }
- do
- {
- rc = et_login_cloud(g_cloud_handle, g_cloud_con_para);
-
- if(rc != 0)
- {
- os_printf("login_cloud failn");
- }
- num++;
- vTaskDelay(num*100*portTICK_RATE_MS);
- }while(rc != 0 && num < 3 && to_stop_app == 0);
-
- if(rc == 0)
- {
- os_printf("now start init friendn");
- init_clients();
- // rc = et_get_buddies_online(g_cloud_handle);
- rc = et_req_buddies_list(g_cloud_handle, LIST_ONLINE);
- if(rc < 0)
- os_printf("Get online buddies failedn");
- else
- os_printf("Get online buddies sucessn");
- rc = et_sub_allbuddies_state(g_cloud_handle);
- if(rc < 0)
- os_printf("Sub all buddies state failedn");
- else
- os_printf("Sub all buddies state sucessn");
- }
- free(id);
- vTaskDelete(NULL);
- return ;
- }
复制代码
从上面可以看出来,在这个函数里,主要读取 flash里的APPKEY,UID等信息,从而创建与ilink 服务器的连接,以后接收来自微信(或者手机APP,WEB网页等其它方式)的消息,同时也可以向他们回复相应的消息(备注:关于这部分代码实现过程,请参考文档《小e-API用户手册》),这里就是详细说明。现在只说明一下,收到消息的回调函数里
- void et_message_process(et_int32 type, et_char *send_userid, et_char *topic_name, et_int32 topic_len, et_context_mes_type *message)
- {
- et_dfs_file_info_type i_file_info;
- struct hostent *ip_addr = NULL;
- et_char server_ip[32];
- int rc = -1;
- switch(type)
- {
- case MES_CHAT_TO_CHAT:
- os_printf("Chat mes from %s:%sn", send_userid, topic_name);
- memset(g_user_id, 0, sizeof(g_user_id));
- snprintf(g_user_id, sizeof(g_user_id), "%s",send_userid);
- parse_msg_from_mqtt(message->payload, message->payload_len);
- break;
- case MES_FILE_TRANSFERS:
- os_printf("File trans mes from %s:%sn", send_userid, topic_name);
- memset(&i_file_info, 0, sizeof(et_dfs_file_info_type));
- rc = et_file_info(g_cloud_handle,message->payload, &i_file_info);
- if(rc == -1)
- os_printf("file info parse failedn");
-
- ip_addr = gethostbyname(i_file_info.source_ip_addr);
- if(ip_addr == NULL)
- {
- os_printf("lb gethostbyname failn");
- return;
- }
- memset(i_file_info.source_ip_addr, 0, sizeof(i_file_info.source_ip_addr));
- strcpy(i_file_info.source_ip_addr, inet_ntoa(*(ip_addr->h_addr)));
- while(write_flash_end)
- {
- os_delay_us(5);
- }
- et_down_file(g_cloud_handle,&i_file_info, write_flash_callback);
- break;
- case MES_FROM_GROUP_SUBTOPIC:
- os_printf("Group mes from %s:%sn", send_userid, topic_name);
- snprintf(g_user_id, sizeof(g_user_id), "%s",send_userid);
- if(topic_len+1 > sizeof(g_group_id))
- {
- memcpy(g_group_id, topic_name, topic_len);
- g_group_message = 1;
- }
- parse_msg_from_mqtt(message->payload, message->payload_len);
- break;
- case MES_FROM_LOCAL:
- os_printf("Local mes from %s:%sn", send_userid, topic_name);
- memset(g_user_id, 0, sizeof(g_user_id));
- snprintf(g_user_id, sizeof(g_user_id), "%s",send_userid);
- parse_msg_from_mqtt(message->payload, message->payload_len);
- break;
- case MES_NOTICE_ADD_BUDDY:
- os_printf("You are be add buddy by %s:%sn", send_userid, topic_name);
- break;
- case MES_NOTICE_REMOVE_BUDDY:
- os_printf("You are be remove buddy by %s:%sn", send_userid, topic_name);
- break;
- case MES_USER_OFFLINE:
- os_printf("%s Offline:%sn", send_userid, topic_name);
- break;
- case MES_USER_ONLINE:
- os_printf("%s Online:%sn", send_userid, topic_name);
- break;
- case MES_USER_STATUS:
- os_printf("%s Status:%sn", send_userid, topic_name);
- break;
- case MES_ONLINE_BUDDIES_LIST:
- os_printf("Get online buddies list%s:%sn", send_userid, topic_name);
- break;
- }
- #ifdef USER_PRINT_DEBUG
- os_printf("message: id%d, qos%d-->n", message->mes_id, message->mes_qos);
- if(MES_CHAT_TO_CHAT == type || MES_FROM_GROUP_SUBTOPIC == type || MES_FROM_LOCAL == type )
- {
- print_hex("payload:", message->payload, message->payload_len);
- }
- else
- {
- os_printf("payload len:%dn", message->payload_len);
- if(message->payload_len > 0)
- os_printf("payload:%sn", message->payload);
- }
- #endif
- }
复制代码
会根据微信(或者手机APP),发过来控制消息,进入函数parse_msg_from_mqtt,怎么消息命令解析,从而进行相应操作(如查询温度,点RGB灯等),并且回复相应操作和数据。 这样基本流程就说完了。
1
|
|
|
|