AliOS-Things新增一个模块

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41863685/article/details/84403830

AliOS-Things新增一个模块


这个版本是直接clone下来的分支,2.0.0以上进行新增加一个模块。

1 目标一

增加一个新模块供现有的app调用,运行查看结果。 nano是aos自带的一个最简单的app例子,它实现了最简单的延时循环打印功能,我们用它来作为例子中所用的app。 新增模块名设为 info_a,功能是打印一条特定的信息。

1.1 选择新模块放置位置

COMPONENT_DIRECTORIES := . \
                         example   \
                         board     \
                         kernel    \
                         platform  \
                         utility   \
                         middleware \
                         tools     \
                         test      \
                         device    \
                         security

我是在middleware 目录下创建的。

|----AliOS-Things
     |----app
     |-------example
             |      |----nano  # example目录下的工程文件将会被编译运行,它将调用info_a组件
             |      |      |----nano.c
             |      |      |----nano.h
             |      |      |----nano.mk
             |      |......
     |----middleware
           |----info_a  # framwork目录下的新组件,有.mk文件
           |      |----info_a.c
           |      |----info_a.h
           |      |----info_a.mk
           |......

1.2 增加新模块源文件

在 info_a 目录中创建 info_a.c :

#include <stdio.h>

void info_a_fun()
{
	printf("this is in info_a\n");
}

1.3 增加新模块的对外头文件

如在 info_a 目录中创建 info_a.h :

#ifndef INFO_A_H
#define INFO_A_H

#ifdef __cplusplus
extern "C" {
#endif

extern void info_a_fun();

#ifdef __cplusplus
}
#endif

#endif  /* INFO_A_H */

1.4 增加新模块的.mk文件

.mk文件是模块存在的标志。每一个模块都会有一个对应的mk文件,makefile通过搜索mk后缀的文件来查找模块。其中声明了一些针对该模块的定制化的东西。最基本的两个就是该模块所包含的源文件,头文件路径和该模块依赖的其他模块。如在info_a目录下创建 info_a.mk:

NAME := info_a
$(NAME)_SOURCES := info_a.c
GLOBAL_INCLUDES += .

1.5 修改 nano 源文件调用新接口

#include <stdio.h>
#include <aos/aos.h>
#include "info_a.h"

static void app_delayed_action(void *arg)
{
    printf("%s:%d %s\r\n", __func__, __LINE__, aos_task_name());
    info_a_fun();	
}

int application_start(int argc, char *argv[])
{
    do
    {
        app_delayed_action(NULL);
        aos_msleep(10);
    }while(1);
}

1.6 修改 nano的 .mk 文件依赖新模块

在nano.mk中新增一行:

$(NAME)_COMPONENTS += info_a

1.7 运行

在原版的程序中直接运行会有如下错误,需要对nano的mk文件进行修改,报错如下:
在这里插入图片描述

解决方法:

在mk文件中把“GLOBAL_INCLUDES += ./ ”去掉,这个代表全局头文件的路径,也可以改为”GLOBAL_INCLUDES += . “,将 会运行成功。

最终的nano.mk文件如下:

GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP

$(NAME)_COMPONENTS += middleware.info_a

mesh ?= 0

ifeq ($(BENCHMARKS),1)
$(NAME)_COMPONENTS  += benchmarks
GLOBAL_DEFINES      += CONFIG_CMD_BENCHMARKS
endif

GLOBAL_INCLUDES += .

编译通过后下载到板子运行,得到的结果如下:

app_delayed_action:11 aos-init
this is in info_a
app_delayed_action:11 aos-init
this is in info_a
app_delayed_action:11 aos-init
this is in info_a
app_delayed_action:11 aos-init

1.8 新增一个模块总结

  • 再编译,我的头文件还是这么写的#include <../framework/info_a/info_a.h>,编译通过!
  • 那我改改头文件#include <info_a/info_a.h>,编译失败!
  • 再改文件#include <info_a.h>,编译成功!

添加一个新模块的总结
1、新模块的C文件、H文件、mk文件缺一不可!
2、调用模块时,工程里面的mk文件一定要添加模块:$(NAME)_COMPONENTS += info_a
3、头文件的包含方式就两种:

  • 绝对路径:#include <…/framework/info_a/info_a.h>
  • 单独头文件:#include <info_a.h>

2 目标二

再添加一个组件:info_b

2.1 选择新模块放置位置

目录结构

|----AliOS-Things
     |----app
     		|----example
             |      |----nano  # example目录下的工程文件将会被编译运行,它将调用info_a、info_b组件
             |      |      |----nano.c
             |      |      |----nano.h
             |      |      |----nano.mk
             |      |......
     |----middleware 
           |----info_a  # framwork目录下的新组件a,有.mk文件
           |      |----info_a.c
           |      |----info_a.h
           |      |----info_a.mk # 通过在这里面添加关系,来带出info_b组件
           |----info_b  # framwork目录下的新组件b,有.mk文件
           |      |----info_b.c
           |      |----info_b.h
           |      |----info_b.mk
           |......

使用同样的方法添加一个info_b文件夹 :

  • info_b.c
  • info_b.h
  • info_b.mk

2.2 代码实现

具体的实现代码如下:

info_b.c:

#include <stdio.h>

void info_b_fun()
{
	printf("this is in info_b\n");
}

info_b.h:

#ifndef INFO_B_H
#define INFO_B_H

#ifdef __cplusplus
extern "C" {
#endif

extern void info_b_fun();

#ifdef __cplusplus
}
#endif

#endif  /* INFO_A_H */

info_b.mk:

NAME := info_b
$(NAME)_SOURCES := info_b.c

GLOBAL_INCLUDES += .

现在想让组件b“依附”在组件a上面,即,nano工程只需要#include "info_a.h"就可以调用组件b的info_b_fun()函数。只需要在info_a.mk里面写:

NAME := info_a
$(NAME)_SOURCES := info_a.c
$(NAME)_COMPONENTS += info_b   # 添加这个依赖就可以了
GLOBAL_INCLUDES += .

对nano.c进行修改:

#include <stdio.h>
#include <aos/aos.h>
#include <info_a.h>    // 没有info_b.h的头文件

static void app_delayed_action(void *arg)
{
    printf("nano %s:%d %s\r\n", __func__, __LINE__, aos_task_name());
    info_b_fun();	  // 却可以调用info_b里面的组件
}

int application_start(int argc, char *argv[])
{
    do
    {
        app_delayed_action(NULL);
        aos_msleep(1000);
    }while(1);
}

2.3 输出结果

nano app_delayed_action:11 aos-init
this is in info_b
nano app_delayed_action:11 aos-init
this is in info_b
nano app_delayed_action:11 aos-init
this is in info_b
nano app_delayed_action:11 aos-init
this is in info_b

3 目标三

再添加一个组件:info_c/info_c_a

3.1 选择模块放置位置

目录结构如下:

|----AliOS-Things
     |----app
     		|----example
             |      |----nano  # example目录下的工程文件将会被编译运行,它将调用info_a、info_b组件
             |      |      |----nano.c
             |      |      |----nano.h
             |      |      |----nano.mk
             |      |......
     |----middleware 
           |----info_a  # framwork目录下的新组件a,有.mk文件
           |      |----info_a.c
           |      |----info_a.h
           |      |----info_a.mk # 通过在这里面添加关系,来带出info_b组件
           |----info_b  # framwork目录下的新组件b,有.mk文件
           |      |----info_b.c
           |      |----info_b.h
           |      |----info_b.mk
           |----info_c # 该目录中没有.mk文件,它的子目录中有.mk文件(加了一层)
           |      |----info_c_a
           |      |     |----info_c_a.c
           |      |     |----info_c_a.h
           |      |     |----info_c_a.mk
           |      |----info_c_b # 更多的新组件
           |      |.......
           |......

3.2 代码实现

同样和以上的同样方式编写如下代码:

  • info_c_a.c
  • info_c_a.h
  • info_c_a.mk

info_c_a.c:

#include <stdio.h>

void info_c_a_fun()
{
	printf("this is in info_c_a\n");
}

info_c_a.h:

#ifndef INFO_C_A_H
#define INFO_C_A_H

#ifdef __cplusplus
extern "C" {
#endif

extern void info_c_a_fun();

#ifdef __cplusplus
}
#endif

#endif  /* INFO_A_H */

info_c_a.mk:

NAME := info_c_a
$(NAME)_SOURCES := info_c_a.c

GLOBAL_INCLUDES += .

nano.mk:

NAME := nano

$(NAME)_SOURCES := nano.c

$(NAME)_COMPONENTS += info_c/info_c_a  # info_c里面没有.mk文件所以....

GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP

mesh ?= 0

ifeq ($(BENCHMARKS),1)
$(NAME)_COMPONENTS  += benchmarks
GLOBAL_DEFINES      += CONFIG_CMD_BENCHMARKS
endif

nano.c:

#include <stdio.h>
#include <aos/aos.h>
#include <info_c_a.h>  // 新组件c的头文件

static void app_delayed_action(void *arg)
{
    printf("nano %s:%d %s\r\n", __func__, __LINE__, aos_task_name());
    info_c_a_fun();	// 新组件c里面的函数
}

int application_start(int argc, char *argv[])
{
    do
    {
        app_delayed_action(NULL);
        aos_msleep(1000);
    }while(1);
}

总结

通过以上的实现,对AliOS0-Things组件的实现和调用了更清晰的认识,也对mk文件的配置有了更深的了解。这篇主要是参考如下的文章,感谢这位大佬。

参考

猜你喜欢

转载自blog.csdn.net/weixin_41863685/article/details/84403830