LV01-01-AliOSThings-09-源码与编译-03-源码编译工具GCC

本文主要是源码与编译——源码编译工具GCC的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu22.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
点击查看本文参考资料
分类 网址 说明
官方网站 阿里云 阿里云官网主页
阿里生活物联平台 生活物联网平台(飞燕平台)主页
AliGenie 天猫精灵开放平台AliGenie主页
阿里物联网平台 阿里物联网平台主页
Bluetooth 技术网站 蓝牙协议规范什么的可以来这里找
Telink Telink | Chips for a Smarter IoT (telink-semi.com)
Telink中文官网
开发手册 AliOS Things开发指南 AliOS Things开发指南,这里是最新版本,可以直接从官网找到
AliOS Things开发指南 AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档
AliOS Things开发指南(3.0) AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档
生活物联网平台开发文档 生活物联网平台(飞燕平台)开发文档
《设备端开发指南》
Wi-Fi IoT品类定义与功能开发 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发
硬件平台 mk3080 WiFi开发板 WiFi开发板使用指南-阿里云开发者社区
esp8266开发板 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com)
TLSR8258 Datasheet Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258
参考资料 AliOS Things 3.0 应用开发指南 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考
IP知识百科 - 华为 (huawei.com) IP的一些相关知识点
点击查看相关文件下载
分类 网址 说明
蓝牙规范相关文档 Core Specification 5.2 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。
《Core_v5.2.pdf》
Mesh Model(v1.1) 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。
本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。
《MshMDL_v1.1.pdf》
Mesh Profile(v1.0.1) 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。
《MshPRFv1.0.1.pdf》
Mesh Device Properties 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。
但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》
GATT Specification Supplement GATT Specification Supplement | Bluetooth® Technology Website。
好像可以在线看:《GATT Specification Supplement》
Assigned Numbers GATT的一些类型定义可以在这里找。
AliOS Things alios-things/AliOS-Things Gitee上的AliOSThings SDK源码仓库
alibaba/AliOS-Things GitHub上的AliOSThings SDK源码仓库
天猫精灵蓝牙Mesh协议栈 alibaba-archive/genie-bt-mesh-stack GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。
之前是在alibaba/genie-bt-mesh-stack这个仓库。
写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a
蓝牙Mesh设备开发指南 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容

一、GCC简介

1. 什么是GCC?

image-20200714163218014

2. 为什么要用GCC?

之前我们学习STM32,或者说51单片机,我们都是在windows下进行开发,使用keil润健或者IAR软件这些集成的IDE来做开发。第一,成本问题,我们在安装那些IDE的时候就会发现,那些软件都是收费的,我们通过某些途径来使用了免费的软件,作为商业用途的话,我们是很危险的。而GCC是完全免费的,我们可以任意使用。第二,GCC的编译效率是高于那些IDE的。第三,我们想要对一些芯片进行开发,就例如STM32,我们在使用keil的时候,是要安装一个芯片支持包的,这个芯片支持包就是支持编译出可以运行在固定芯片上的代码的,而IDE中想要加入这些支持包,是要收费的,也就是说,芯片厂商要给keil的厂商一定的费用,让他们吧这些集成的keil软件中,所以我们才能使用keil这种IDE来进行开发,但是有些新的芯片或者说厂商不愿意出这笔费用怎么办?当然也是有办法的,那就是GCC啦。因为GCC是免费的,并且是开源的,芯片厂商完全可以直接修改源码,开发适配自己芯片的GCC编译器,这样成本就会低很多了。

3. 学习资料

去哪里找学习资料?当然是官网啦:GCC, the GNU Compiler Collection - GNU Project。官网上只有英文原版的说明文档,但是这个文档是有中文版的,我找了一个,可以在线看:GCC 中文手册 (uml.com.cn)

image-20200716132605575

二、GCC编译原理

1. 编译过程

image-20200701120344812

2. keil下的编译过程

image-20200714172843638

keil生成的文件:

image-20200716145951847

keil 生成可执行文件:

image-20200716150330482

3. gcc常用的编译选项

常用选项 描述
-E 预处理,开发过程中想快速确定某个宏可以使用“-E -dM”
-c 把预处理、编译、汇编都做了,但是不链接
-S 把.c文件汇编为.s文件
-D 定义宏
-o 指定输出文件
-I 指定头文件目录
-L 指定链接时库文件目录
-l 指定链接哪一个库文件
-MD 告诉预处理器输出一个适合 make 的规则的文件,也就是依赖文件,这个依赖文件用于描述各目标文件的依赖关系,把依赖信息输出在文件中。文件名通过把输出文件名末尾的.o替换为 .d 。同时继续指定的编译工作,-MD不像-M那样阻止正常的编译任务Mach的实用工具md能够合并d文件,产生适用于make命令的单一的依赖文件。为什么要这样?后边下一节笔记会有一个例子说明,主要是因为不加这个的话,Make不会去检查修改的头文件,但是当我们加了这个选项后,在只有头文件更新的时候,make也能正常去更新可执行文件。
1
2
3
gcc -E main.c                # 查看预处理结果,比如头文件是哪个
gcc -E -dM main.c > 1.txt # 把所有的宏展开,存在1.txt里
gcc -MD -c main.c -o main.o # 生成依赖文件 后面Makefile会用

三、GCC的使用

1. 测试文件源码

1.1 main.c

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

extern void sub_fun(void);

int main(int argc, char* argv[])
{
printf("Main fun!\n");
sub_fun();
return 0;
}

1.2 sub.c

1
2
3
4
5
6
7
#include <stdio.h>
#include "sub.h"

void sub_fun(void)
{
printf("Sub fun, A= %d!\n", A);
}

1.3 sub.h

1
2
#define A  2
void sub_fun(void);

1.4 Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
objs := main.o sub.o

test : $(objs)
gcc -o test $^


dep_files := $(wildcard *.d)

# 把依赖文件包含进来
ifneq ($(dep_files),)
include $(dep_files)
endif

%.o : %.c
gcc -MD -c $< -o $@
clean:
rm *.d *.o test -f

2. 怎么编译多个文件

  • 方式一:一起编译,链接
1
gcc  main.c  sub.c -o test
  • 方式二:分开编译,统一链接
1
2
3
4
gcc -c   main.c -o main.o
gcc -c sub.c -o sub.o
gcc main.o sub.o -o test

3. 制作使用动态库

  • (1)制作、编译
1
2
3
4
gcc -c main.c -o main.o
gcc -fPIC -c sub.c -o sub.o # 生成位置无关代码
gcc -shared sub.o (可以使用多个.o生成动态库) -o libsub.so
gcc main.o -lsub -L . -o test
  • (2)运行

先把libusb.so放到/lib目录,然后就可以运行test程序。如果不想把libusb.so放到 /lib ,也可以放在某个目录比如 /a ,然后如下执行:

1
2
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a  
./test

4. 制作使用静态库

1
2
3
4
gcc -c main.c -o main.o
gcc -c sub.c -o sub.o
ar crs libsub.a sub.o
gcc main.o libsub.a -o test