飞道的博客

如何创建一个新的AliOS Things组件

365人阅读  评论(0)

1、前言

当我们基于AliOS Things做应用或项目开发时,会发现自己写的很多代码具备很强的可复用性,不单本项目可以使用,可能后续的类似项目都可以用到。那我们怎么把这部分功能抽象成OS的一个能力呢?显然,我们把这部分代码从project中挪到components中当作一个组件是非常合适的。

 

接下来我们将详细介绍如何快速开发一个AliOS Thing的标准组件。

本案例基于以下平台:

2、快速掌握AliOS Things的编译系统

AliOS Things 编译系统由两部分组件。

  • 负责组件配置的Config.in
  • 负责具体编译的aos.mk

2.1、Config.in 介绍

如果大家玩过linux内核编译,应该清楚Config.in是munuconfig图形化配置的配置文件。

对于一个组件,需要一个config选项,如下格式:


  
  1. config AOS_COMP_XXX1
  2. bool "xxxx"
  3. select AOS_COMP_XXX2
  4. default n
  5. help
  6. what is this.

四要素:

  1. config后接组件名(配置系统中的名称);
  2. bool 代表选项类型,对于一个组件来说存在“选中“和“不选中“两种状态,故使用bool类型,bool后空一个写其在menuconfig中显示的名称;
  3. select 用于选中其必须依赖的组件,如CoAP这种应用层协议会依赖tcp/ip协议栈LwIP。
  4. default 默认状态,对于bool类型,只有“n”或“y”两种状态,建议默认n。
  5. help 功能描述。

另外需要注意的是,AliOS Things3.1支持创建工程,因此对Config.in做了一定的改造,加了“AOS_CREATE_PROJECT”控制开关,如果我们需要能主动创建工程,择需要如下方式改造一下,做前后兼容:


  
  1. #注意这里,如果AOS_CREATE_PROJECT使能的话,无需设置组件名,并且默认使能
  2. if AOS_CREATE_PROJECT
  3. config AOS_COMP_XXX1
  4. bool
  5. select AOS_COMP_XXX2
  6. default y
  7. help
  8. what is this.
  9. endif
  10. #注意这里,如果AOS_CREATE_PROJECT未使能的话,则按传统方式设置组件名,并且默认不使能
  11. if !AOS_CREATE_PROJECT
  12. config AOS_COMP_XXX1
  13. bool "xxx"
  14. default n
  15. select AOS_COMP_XXX2
  16. help
  17. what is this.
  18. endif

详细介绍可参考 配置系统简介

2.2、aos.mk介绍

aos.mk其实就是makefile,语法保持一致。

mk文件参数说明。

1、组件名:

NAME := mcoap

2、依赖组件,当有Config.in保证依赖关系时,此处可以不填写:

$(NAME)_COMPONENTS := 

3、编译类型:

$(NAME)_MBINS_TYPE := kernel

4、组件版本:

$(NAME)_VERSION := 1.0.0

5、组件描述:

$(NAME)_SUMMARY := Your component description.

6、指定编译源文件:


  
  1. #包含src目录下全部.c
  2. $(NAME)_SOURCES := src/*.c
  3. #包含src目录下指定.c
  4. $(NAME)_SOURCES := src/xxx.c src/xxxy.c

7、指定头文件路径:


  
  1. #全局头文件,组件外也可以找到
  2. GLOBAL_INCLUDES += public/
  3. #内部头文件,仅组件使用
  4. $(NAME)_INCLUDES += private/

8、定义全局宏:


  
  1. #整个编译系统下可见的宏
  2. GLOBAL_DEFINES += CONFIG_COAP
  3. #仅组件下可见的宏
  4. $(NAME)_DEFINES += CONFIG_COAP_WITH_TLS

9、CFLAGS设置:


  
  1. #整个编译系统下可见的CFLAG
  2. #GLOBAL_CFLAGS += -DON_DAILY
  3. #仅组件下可见的CFLAG
  4. $(NAME)_CFLAGS += -DON_DAILY

2.3、目录格式

组件默认都放在components目录下,然后根据具体功能又可细分目录,如我们示例移植一份开源的coap库,则可以放在components/network目录下。目录格式建议为:


  
  1. your_comp_dir
  2. --include
  3. --src

3、一步步实现自有组件

鉴于代码开源相关风险,本用例使用一个mit lisense的开源coap库(示例代码来源:https://github.com/1248/microcoap)当做示例代码加入到AliOS Things中,使其成为其标准组件。

 

1、在components/network/下新建microcoap文件夹,并新建两个子文件夹include/src分别用于存放.h和.c文件;

2、在src/include文件夹下分别创建你的.c和.h文件;

3、按2章节方法在microcoap目录下新建Config.in:


  
  1. #注意这里,如果AOS_CREATE_PROJECT使能的话,无需设置组件名,并且默认使能
  2. if AOS_CREATE_PROJECT
  3. config AOS_COMP_MICROCOAP
  4. bool
  5. select AOS_COMP_LWIP
  6. default y
  7. help
  8. A tiny open source CoAP server for microcontrollers.
  9. endif
  10. #注意这里,如果AOS_CREATE_PROJECT未使能的话,则按传统方式设置组件名,并且默认不使能
  11. if !AOS_CREATE_PROJECT
  12. config AOS_COMP_MICROCOAP
  13. bool "microcoap"
  14. default n
  15. select AOS_COMP_LWIP
  16. help
  17. A tiny open source CoAP server for microcontrollers.
  18. endif

同时在build/Config.in中增加此文件的索引:


  
  1. menu "Network Configuration"
  2. ...
  3. source "components/network/microcoap/Config.in"
  4. ...

4、按2章节方法在microcoap目录下新建aos.mk文件:


  
  1. NAME := microcoap
  2. $(NAME)_MBINS_TYPE := kernel
  3. $(NAME)_VERSION := 1.0.0
  4. $(NAME)_SUMMARY := A tiny open source CoAP server for microcontrollers.
  5. $(NAME)_SOURCES := src/coap.c src/endpoints.c
  6. GLOBAL_INCLUDES := include

5、完成代码开发(示例使用开源代码演示,略过)。

至此整个文件结构如图:

4、测试验证

4.1、编写测试demo

1、拷贝已经存在的helloworld_demo例程为模板创建自有demo:mcoap_demo。

2、修改aos.mk,如下:


  
  1. NAME := mcoap_demo
  2. $(NAME)_MBINS_TYPE := app
  3. $(NAME)_VERSION := 1.0.0
  4. $(NAME)_SUMMARY := microcoap demo
  5. $(NAME)_SOURCES := appdemo.c maintask.c
  6. $(NAME)_COMPONENTS += osal_aos cli
  7. $(NAME)_INCLUDES += ./

3、修改Config.in,如下:


  
  1. config AOS_APP_MCOAP_DEMO
  2. bool "mcoap Demo"
  3. select AOS_COMP_OSAL_AOS if !AOS_CREATE_PROJECT
  4. select AOS_COMP_MICROCOAP if !AOS_CREATE_PROJECT
  5. select AOS_COMP_YLOOP if !AOS_CREATE_PROJECT
  6. select AOS_COMP_NETMGR if !AOS_CREATE_PROJECT
  7. help
  8. microcoap demo
  9. if AOS_APP_MCOAP_DEMO
  10. # Configurations for app mcoap_demo
  11. config SYSINFO_APP_VERSION
  12. string "Firmware Version"
  13. default "app-1.0.0-20201208.140831"
  14. help
  15. application main firmware version
  16. endif

4、编辑application/example/Config.in,增加本demo信息:


  
  1. source "application/example/mcoap_demo/Config.in"
  2. if AOS_APP_MCOAP_DEMO
  3. config AOS_BUILD_APP
  4. default "mcoap_demo"
  5. endif

5、编辑appdemo.c,增加自己的测试验证代码。如下:


  
  1. /*
  2. * Copyright (C) 2015-2020 Alibaba Group Holding Limited
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <aos/errno.h>
  7. #include <aos/kernel.h>
  8. #include "aos/init.h"
  9. #include "board.h"
  10. #include <k_api.h>
  11. #include "coap.h"
  12. #include "network/network.h"
  13. #include "aos/yloop.h"
  14. #include "netmgr.h"
  15. #define PORT 5683
  16. int test_main(void *data)
  17. {
  18. int fd;
  19. struct sockaddr_in servaddr, cliaddr;
  20. uint8_t buf[ 1024];
  21. uint8_t scratch_raw[ 1024];
  22. coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)};
  23. fd = socket(AF_INET,SOCK_DGRAM, 0);
  24. bzero(&servaddr, sizeof(servaddr));
  25. servaddr.sin_family = AF_INET;
  26. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  27. servaddr.sin_port = htons(PORT);
  28. bind(fd,(struct sockaddr *)&servaddr, sizeof(servaddr));
  29. endpoint_setup();
  30. while( 1)
  31. {
  32. int n, rc;
  33. socklen_t len = sizeof(cliaddr);
  34. coap_packet_t pkt;
  35. n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len);
  36. #ifdef DEBUG
  37. printf( "Received: ");
  38. coap_dump(buf, n, true);
  39. printf( "\n");
  40. #endif
  41. if ( 0 != (rc = coap_parse(&pkt, buf, n)))
  42. printf( "Bad packet rc=%d\n", rc);
  43. else
  44. {
  45. size_t rsplen = sizeof(buf);
  46. coap_packet_t rsppkt;
  47. #ifdef DEBUG
  48. coap_dumpPacket(&pkt);
  49. #endif
  50. coap_handle_req(&scratch_buf, &pkt, &rsppkt);
  51. if ( 0 != (rc = coap_build(buf, &rsplen, &rsppkt)))
  52. printf( "coap_build failed rc=%d\n", rc);
  53. else
  54. {
  55. #ifdef DEBUG
  56. printf( "Sending: ");
  57. coap_dump(buf, rsplen, true);
  58. printf( "\n");
  59. #endif
  60. #ifdef DEBUG
  61. coap_dumpPacket(&rsppkt);
  62. #endif
  63. sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
  64. }
  65. }
  66. }
  67. }
  68. /*
  69. * WiFi Got IP event
  70. */
  71. static void wifi_service_event(input_event_t *event, void *priv_data)
  72. {
  73. static int started = 0;
  74. if (event->type != EV_WIFI) {
  75. return;
  76. }
  77. if (event->code != CODE_WIFI_ON_GOT_IP) {
  78. return;
  79. }
  80. netmgr_ap_config_t config;
  81. memset(&config, 0, sizeof( netmgr_ap_config_t));
  82. netmgr_get_ap_config(&config);
  83. LOG( "wifi_service_event config.ssid %s", config.ssid);
  84. if ( strcmp(config.ssid, "adha") == 0 || strcmp(config.ssid, "aha") == 0) {
  85. return;
  86. }
  87. /* Start CoAP task */
  88. if (!started) {
  89. aos_task_new( "iotx_example", test_main, NULL, 1024* 6);
  90. started = 1;
  91. }
  92. }
  93. int application_start(int argc, char *argv[])
  94. {
  95. int count = 0;
  96. printf( "nano entry here!\r\n");
  97. /* Register WiFi event handle */
  98. aos_register_event_filter(EV_WIFI, wifi_service_event, NULL);
  99. /* Initialize and start net manager */
  100. netmgr_init();
  101. netmgr_start( false);
  102. aos_loop_run();
  103. }

4.2、编译&测试

1、编译我们新增加的demo程序,生产固件。


  
  1. aos make mcoap_demo@haas100 -c config
  2. aos make

2、将上述编译的固件按照haas100开发板烧入指导手册烧入板中,进行相关功能验证。

5、总结

将一个通用能力集合当作一个组件加入到AliOS Things中并不难。主要有以下几步:

  1. 编写组件功能代码;
  2. 编写Config.in;
  3. 编写aos.mk;
  4. 将组件Config.in加入配置体系;
  5. 至此主要流程已经完成。当然你还可以做如下工作用于验证组件是否能正常工作:
  6. 编写测试demo;
  7. 编译测试固件,上板验证。

你学会了没?最后欢迎大家将自己的组件贡献到AliOS Things生态中来,可通过(https://github.com/alibaba/AliOS-Things/pulls)等开源仓库提交你的代码,我们审核通过后就将成为AliOS Things的一部分!

同时,我们推出了HaaS 年度大玩家计划,除了成为AliOS Things的一部分,也欢迎同学们在CSDN上踊跃投稿,还有机会被邀请到 云栖大会 现场来进行颁奖哦

6、开发者技术支持

如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/


转载:https://blog.csdn.net/HaaSTech/article/details/111351624
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场