AliOS-Things--EMW3060--nano--添加一个新模块

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

https://github.com/alibaba/AliOS-Things/wiki/Add-a-new-component-example.zh

一、添加一个组件:info_a

架构简介

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

nano例程是最简单的工程:它的路径在AliOS-Things\example\nano\nano.c

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

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

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

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

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

在framework下创建一个 info_a 目录

1.增加新模块源文件

在 info_a 目录中创建 info_a.c :

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#include <stdio.h>

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

2.增加新模块的对外头文件

在 info_a 目录中创建 info_a.h :

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#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 */

3.增加新模块的.mk文件

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

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

4.修改 nano 源文件调用新接口

如:

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#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);
}

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

在nano.mk中新增一行:

$(NAME)_COMPONENTS += info_a

坑一:找不到头文件

example/nano/nano.c:7:10: fatal error: info_a.h: No such file or directory
 #include <info_a.h>
          ^~~~~~~~~~

那好,我改:
我把#include <info_a.h>改成#include <../framework/info_a/info_a.h>头文件,直接通过绝对目录来指定头文件的地方。嘚,没报错了,说明这是可以解决的。
不过又出现了新的问题:

out/nano@mk3060/libraries/nano.a(nano.o): In function `app_delayed_action':
D:\Output\AliOS\AliOS-Things/example/nano/nano.c:12: undefined reference to `info_a_fun'

函数info_a_fun没有找到?抱歉,头文件都没报错了,头文件里面有的函数你居然说找不到!再仔细找!
靠!!!nano.mk里面写错了!
原有的没改的,按照文档,我要在里面添加一句:$(NAME)_COMPONENTS += info_a

NAME := nano

$(NAME)_SOURCES := nano.c


GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP

mesh ?= 0

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

然后,我就改成了以下这种错误的了!

NAME := nano

$(NAME)_SOURCES := nano.c


GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP

mesh ?= 0

ifeq ($(BENCHMARKS),1)
$(NAME)_COMPONENTS  += benchmarks \ 
                       info_a                        # 注意不能在这里加啊!!
GLOBAL_DEFINES      += CONFIG_CMD_BENCHMARKS
endif

正确的mk

NAME := nano

$(NAME)_SOURCES := nano.c
$(NAME)_COMPONENTS += info_a      # 正确的做法是要在这添加啊!

GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP

mesh ?= 0

ifeq ($(BENCHMARKS),1)
$(NAME)_COMPONENTS  += benchmarks
GLOBAL_DEFINES      += CONFIG_CMD_BENCHMARKS
endif
  • 再编译,我的头文件还是这么写的#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、头文件的包含方式就两种:
(1)绝对路径:#include <../framework/info_a/info_a.h>
(2)单独头文件:#include <info_a.h>

二、再添加一个组件:info_b

架构简介

|----AliOS-Things
     |----example
     |      |----nano  # example目录下的工程文件将会被编译运行,它将调用info_a、info_b组件
     |      |      |----nano.c
     |      |      |----nano.h
     |      |      |----nano.mk
     |      |......
     |----framwork
           |----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

info_b.c

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#include <stdio.h>

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

info_b.h

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#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又做好了。
现在想让组件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 += .

如下就可以编译了

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#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);
}

三、再再添加一个组件:info_c/info_c_a

架构简介

|----AliOS-Things
     |----example
     |      |----nano  # example目录下的工程文件将会被编译运行,它将调用info_a、info_b组件
     |      |      |----nano.c
     |      |      |----nano.h
     |      |      |----nano.mk
     |      |......
     |----framwork
           |----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 # 更多的新组件
           |      |.......
           |......

文件还是老三样(写法和组件a的几乎一模一样就是,名字加了"_c"):

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

就是组件在其他目录之下,那么在nano工程中该怎么调用呢?

首先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头文件就可以直接使用了

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#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);
}

四、总结

 把这几种类型的组件全部试用一次,就可以大致了解到AliOS-Things的文件依赖与调用,包括.mk文件的写法就没那么迷糊了,还有就是大型的C工程里面包含头文件的写法也是头痛,经过以上的实验之后,好像有那么点清楚了。

猜你喜欢

转载自blog.csdn.net/qq_28877125/article/details/82894603