1 前言* x# J0 f2 M4 R8 r: U4 g
随着2016年NB-IoT技术标准的冻结,物联网(IoT)整个领域迎来新一轮的快速发展,行业机构预测物联网技术(IoT)在2017~2021期间将持续火爆。同时随着十几年互联网技术、大数据、云计算、IoT技术等进一步发展与成熟、芯片存储成本的降低、IoT应用的快速普及等等,物联网RTOS作为IoT设备的基础软件,在一定程度上可以破解物联网下游的碎片化困局,加快下游物联网应用的开发进程,因此RTOS插上物联网的翅膀再次焕发新生。! s9 E4 Y' l* d/ j6 [+ y. I
物联网RTOS相比嵌入式RTOS(linux、安卓…)面向物联网的应用范畴更为广泛,但是目前阶段,物联网终端应用很多都是基于MCU的裸机开发(Bare-metal)模式,而基于MCU开发,国内开发者更多是基于Window系统,习惯使用的开发工具是IDE(KEIL\IAR等),而不是linux的命令行方式。基于两种平台的开发方式各有千秋,主要还是看个人技术积累与使用习惯。8 s0 D L4 f' a5 G: w
本文主要描述了基于Window系统,使用STM32L476与MDK5来搭建Alios Things(以下简称为 AOS )系统的基础软件开发环境。主要内容涉及: - AliOS Things 2.1.0代码仓库的组织架构说明 i9 d" f$ I, D2 ^5 F
a. AliOS Things MDK开发调试方式 - 基于STM32L与MDK搭建AliOS Things的软硬件开发环境搭建- {. k( c# y+ y1 _" ^/ {7 ?
a. AliOS Things MDK工程生成方式7 {8 z1 k: C# Y3 D
b. STM32L476RG-Nucleo的hello world MDK工程搭建实例
8 t8 q# t- l* N. r 2 AliOS Things入门知识2.1 AliOS Things代码仓库的组织架构8 Q. y$ i6 A0 o( Q! I- Z& u Q* H
AliOS Things源代码组织架构符合分层架构与组件化架构。( L% ?, j3 `/ o( l
AliOS Things架构至下(层)而上(层),分别是1 i- b8 B6 _! t" R
- 板级支持包(BSP):主要由SoC供应商开发和维护
- 硬件抽象层(HAL):比如WiFi和UART、SPI
- 内核(Kernel):包括Rhino实时操作系统内核、Yloop, VFS, KV 存储…
- 协议栈(Protocol Stack):包括TCP/IP协议栈(LwIP),uMesh网络协议栈,Bluetooth、LoRaWAN…
- 安全(Security):安全传输层协议(TLS),可信服务框架(TFS)、可信运行环境(TEE)
- AOS API:提供可供应用软件和中间件使用的API…
- 中间件(Middleware):包括常见的物联网组件和阿里巴巴增值服务中间件,比如AT组件、Alink、MQTT、Udata…
- 示例应用(App):阿里自主开发的示例代码,以及通过了完备测试的应用程序(比如helloworld、Alinkapp)
8 `4 u, \, \( b2 n . H0 z3 n$ \% O: z
2.2 AliOS Things文件夹目录树
7 V5 T5 v" T7 R, P AliOS Things源代码主要托管在Github上,可以从github下载的源码 AliOS Things latest version,截止2019年6月份,当前最新release版本为2.1.0 http://github.com/alibaba/AliOS-Things/tree/rel_2.1.0 # w5 `; D; J: _
/ K% A3 e- D+ y* b$ ]1 n) _) `: lAOS源代码目录树 - AliOS Things 2.1.0文件夹架构 分层 | 所属文件夹 | 说明 | APP | app | 该目录下包含了example 代码示例,通过了完备测试的应用程序(比如Alink) | APP | project | IDE工程目录。比如KEIL、IAR、GCC、e2studio | APP | test | UT测试用例 | APP | utility | IoT通用软件库,比如 cJSON | APP | include | 该目录下包含了AliOS Things内核、各组件的头文件 | 中间件 | middleware | IoT 通用组件,主要有3 N( n3 g7 w7 B% C# P: [
- linkkit4 y! P1 I; P3 q' y
- udata0 ~" |" T7 h. E# [0 B: x9 q/ O
- ulocation: H7 `2 z o# o
- uagent | AOS API | osal | AOS API,提供可供应用软件和中间件使用的API | 安全组件 | security | 包括TLS,TFS, TEE在内的安全组件 | 应用驱动 | drivers | 该目录下包含了应用驱动代码,主要有
% Y! f+ j6 I5 p# l/ I- sensor" N( j. y& c9 @5 l, U% B {) h
- sal
7 b0 w Q( e6 \+ q3 \0 Y5 P9 i- gprs
& Q: |' Z; m' k3 g; j+ [% o) g1 [3 u2 W- wifi | 网络连接 | network | 该目录下包含了当前支持的网络协议栈: U( |( ], z" n' `: g1 F; H0 F- H
- bluetooth5 y6 K' P' ^: v$ ]
- breeze
3 ~) s) w! V, R9 b/ J3 r$ ~, }- bt_host
& C! w0 j6 k6 g6 {) Z8 t& I- bt_mesh
. T2 ], I+ X7 N" G0 Y6 Q1 {; F- canopen
$ s5 U9 z" d) ~. ~( I# T- lwip
- m) @' E9 F3 H9 a- lorawan
* f8 D' w) }% W) o- umesh
6 o* [& \- K2 n/ ? K A- nal
. k. \- e0 t2 K6 G7 Z8 _* C3 q J- atparse
2 z1 a( n7 n' i8 W, B% O0 Y- athost. V8 J" q' r' o `4 v2 D* { n
- netmgr8 i' p8 O _/ u+ l
- yloop
3 D4 c6 g* W! t: X- … | AOS内核 | kernel | 该目录下包含了Rhino、命令行(CLI) | HAL | board | 实际硬件开发平台,包括评估板、用户自己的硬件平台等(如STM32L496G-Discovery) | BSP | platform | 该目录下包含了mcu与arch文件夹 5 Z) R6 c' G9 m- c
- mcu
3 |! L8 O$ f# N. y- L; y/ I& O: z8 \- 该目录主要存放厂商提供的芯片底层软件库代码(如STM32L4xx_cube库),主要由SoC供应商开发和维护,以及二进制文件,如系统启动、驱动、编译/链接脚本等。mcu下的目录结构按“厂商/芯片系列”进行区分 ) A8 z# H+ w- {1 y8 y
- arch , @ t' F4 ]# ]& a, @' e5 [& k7 V
- 主要存放硬件体系架构所需要的移植接口实现文件,如任务切换、启动、开关中断等(即arch/include/port.h中所定义的接口),硬件体系架构如arm、risc-v、linux、misp…
6 T5 m% b$ t, B: k+ t* H# ]" L- 示例(armv7m):- 头文件:arch/arm/armv7m/gcc/m4/port*.h, 代码示例。
- L+ Z, e2 V" S2 b, l( Q) y3 r- 源代码:arch/arm/armv7m/gcc/m4/下的.c文件和汇编文件, 代码示例。
/ O& }0 ?' o: c( c/ N- 注:arch下的目录结构按CPU架构区分,请参照已有目录。 | Tool | build | 编译框架,包含了ucube.py、makefile、编译规则、编译py脚本等文件 | Tool | tools | 用于建立远程设备中心的testbed工具、doxygen生成文件 |
4 n: v* [7 G o; o3 Z2.3 AliOS Things开发与调试方式
6 \" a, v5 F X* O; t
3 H7 Y* {8 ^. Q2 M! eAliOS Things支持多种调试手段,针对不同的功能模块,不同的使用场景,开发者可以根据需要自己选择: , Z/ r, P' |* X5 C
- linux host模拟环境:适合于硬件无关的模块或者代码,可以使用gdb,valgrind等流行的工具
- CLI环境:适合板上轻度调试,使用系统的各种内存调试工具
- JTAG环境:适合板上调试,利用硬件调试能力与IDE功能(MDK\IAR\AOS Studio)本身提供的在线调试功能
' m+ b- t/ l7 ~
3 l/ z3 |) {9 m: g4 o具体可参看《AliOS-Things调试概述 Debugging-Overview》 ! L3 i% V4 v" X% H; N
3 AliOS Things MDK环境搭建# Q9 g& ~6 ` O8 N: j" |
# ]) n) G% G: V3 S7 YAliOS Things MDK环境搭建目前可以有两种方式,一种是通过aos-cube工具(aos-cube 是 AliOS Things 在 Python 下面开发的项目管理工具包)通过aos make等构建命令自动生成MDK工程,另外一种是使用MDK自己新建工程,添加项目文件。 AliOS Things uCube ≈ RT-Thread ENV (都是基于命令行的项目管理工具包). G9 K6 r9 e, n
目前这块RT-Thread支持的比较成熟,通过ENV工具的Scons快速编译生成KEIL工程,同时对于新的平台,也可以通过现有的文件,快速修改得到。
" d3 d3 L! I& H ~! W' }) D" C3.1 aos-cube自动生成MDK* l6 c# L* I& i
Alios-things 支持将特定的目标转化成keil和iar来进行开发。自动生成keil或iar工程的命令就是在原有构建命令的基础上加上 IDE=keil 或 IDE=iar 的选项,会自动生成一个keil工程或者iar工程。构建命令: - aos make mqttapp@b_l475e IDE=keil, `) ~, E( T1 z0 ^0 P2 O' w
- aos make mqttapp@b_l475e IDE=iar
复制代码
当前使用aos-cube工具自动生成MDK的板子还比较少,具体可以参看《AliOS-Things自动生成KEIL\IAR工程 Auto-generate-keil-iar-project》这篇文章 支持情况
$ C5 M- m; L- s, X% y" z; f- 目前支持 b_l475e 和 startkit 两个board工程自动生成。其他stm32系列的自动生成的工程可能需要人为做一些修改。
- 转化出的工程默认未开优化选项
- 工程内存信息,可能与board实际的有所差别,需要完善& a4 D% ?! X( q; P
+ H6 ~" \& U! k& Y2 r9 ^2 a/ l: {
3.1.1 AliOS Things 2.1版本KEIL工程
. ^3 F+ P$ E% a4 |5 M* Y0 B# c从2.1.0版本,keil目录下已经不再包含示例工程,是通过aos-cube工具自动生成。
D$ D( j0 u( T0 F* i3 K& o( Z _3.2 手动新建MDK工程. k0 t- c& d Z9 s2 V6 M
虽说是手动搭建新工程,但最好还是找到源代码版本一致情况下的KEIL模板工程或者相似平台(比如采用上述提到的“aos-cube自动生成MDK”工程),直接复制,重命名,然后再根据实际修改。
/ v0 g& P6 Y: z# X# U; n因为AliOS Things最新发布2.1.0代码库中,KEIL默认采用自动生成方式,project目录下里面没有包含KEIL工程,当前采用的办法是参考之前版本(包含了KEIL示例工程)(可以到develop等分支下载),由于AliOS Things 2.1.0版本与之前版本对文件目录结构等做了不少调整,因此不能直接使用,需要适当修改。1 b9 i, Q, r! m1 p5 o2 m! q$ ?
相比于之前版本,2.1版本的变化如: - 从直接mcu文件夹中分离出board相关文件,放在新增加了board文件夹内,这样有利于共用mcu中的文件
- kernel文件夹删去子文件夹core分类
- arch增加了common文件夹,用来存放port_c.c
- 新增了osal文件夹,用于存放aos api文件* T' S' |8 V/ p' w
2 g, F; B& a. D4 J
接下来第4部分内容,将详细说明MDK工程的搭建过程与可能遇到的问题。 9 ~. X3 U" m% E; V! {: k
4 搭建AliOS Things第一个MDK工程
0 C" [/ Q2 Z+ R/ c: R2 x$ R$ ?; z
' v$ H2 a. Q- L( w7 x 以手动搭建AliOS Things 2.1.0版本中 STM32L476RG-Nucleo的hello world MDK工程为例
7 ?8 n0 D8 @! T& r3 X% `/ P. \% a" e% T首先直接拷贝之前版本的AliOS-Things\project\STM32L476RG-Nucleo\helloworld到2.1.0相同路径下面/ p0 d* A0 W9 l, k
7 l o5 h V1 a- R$ c- F0 ^0 }4.1 AliOS Things系统所需基础依赖文件4 ?" {2 y6 J* E1 x1 j, d
基于MDK与STM32L4,AliOS Things 2.1.0系统所需的基础依赖文件主要包括如下内容,下面具体展开的是移植中比较容易出错的部分文件: - 具体应用文件! w/ A4 O9 S4 }, @" C9 }( _0 }) i
- example" Q' Q* P& g6 o" A) {
- helloworld, U9 O3 o# ~ k9 {& O
- AOS API文件,应用层或者中间件通过这层API接口访问内核1 l( m( {, r8 H$ V1 j: M
- osal\aos4 `/ w! E8 X2 Q
- rhino.c
9 n9 M7 C- i, U. H/ ~2 |4 `- aos_init初始化入口
- aos_start 内核启动入口
- aos_msleep 系统延时
- *aos_malloc、aos_free…
/ t A( k: @, @" w$ w
- 具体硬件平台文件
9 I2 C+ i8 a$ g |! R- board\STM32L476RG-Nucleo5 n, ~' b. s1 P, l7 M7 a7 v" o
- 启动文件startup_stm32l476xx_keil.s
- 分散加载文件STM32L476RGTx_FLASH.sct
& i4 z3 [- S4 k! o: U. H
- board\STM32L476RG-Nucleo\aos
; N7 m1 w8 ~7 C- 内核特性移植与裁剪文件k_config.h,通过修改k_config.h来使能kernel的功能模块, ]3 }0 y: D: Q* T, R4 v7 m
- 堆分配等文件
5 N5 L9 Y( Y2 l9 F- utility\libc\compilers\armlibc\armcc_lib.c
* l! K! l7 L h C
- 内核特性移植相关文件.soc_impl.c、aos.c
) U6 P0 N a4 c- B- platform\mcu\stm32l4xx\aos' [4 l9 i$ `9 D5 e4 i. v* g
- soc_impl.c里面必须要实现的是内存分配这块的配置g_mm_region
- aos.c包含了main入口函数
; f9 s% o5 e \
- 内核文件
3 p. x9 K# f6 {- kenerl\rhino
& ^3 z- ~5 h; c) U, \- 内核初始化文件
& H- r O- F, G- kernel\rhino\core\init\aos_init.c+ g5 H" H* K; v8 T& M+ s
- 面向板级的HAL驱动文件" K) e4 B1 n! m6 F
- platform\mcu\stm32l4xx_cube\hal
7 b$ a6 `. n' ^* x: w0 e
- STM32L4 cube库文件; v, Z3 @0 U: h' Z2 x0 M( y
- platform\mcu\stm32l4xx_cube\Drivers\STM32L4xx_HAL_Driver\Src4 C4 b: p/ ^- I% I8 |6 Q, b% a& c
- 硬件体系架构所需要的移植接口实现文件
1 I, C6 D* |3 s. i( b2 w- platform\arch\arm\armv7m\armcc\m4\port_s.S
- platform\arch\arm\armv7m\common\port_c.c
. M& f$ ], }6 i: u1 x
8 P# O0 G. Y1 `4 K7 \- {1 ^5 ^4.2 可能遇到的问题
5 _0 i5 r7 C! ` 打开STM32L476RGTx.uvprojx工程,会发现有左边的工程文件很多感叹,主要是因为文件路径发生变化,可以对STM32L476RGTx.uvprojx使用文本编辑器打开(比如Sublime Text3…),将相关出现感叹号的文件替换为新版本的对应路径。
, X8 p% R* t+ M. v" j; p具体方法是: - 点击出现感叹号的文件,会弹出提示框,根据对应当前老版本的文件路径调整,然后修改为新版本AliOS Things 2.1.0下的对应路径
- 如果刚上手不熟悉AliOS Things,如何找到AliOS Things 2.1.0下的对应.c、.h文件路径?
- 一种方式是在AliOS Things的github代码仓库搜索,github提供了非常强大搜索功能
- github搜索示例:
- 在文本编辑器中修改了STM32L476RGTx.uvprojx,保存后,切换会MDK工程,MDK会自动重载STM32L476RGTx.uvprojx中修改的文件。如果修改顺利,则可以看到文件的感叹号已有消失了。
# ?9 V% P3 J5 A
* L$ D3 y; G. l" ^1 |
+ U9 C y# O7 p! k4.2.1 core文件路径找不到
" t3 i5 j' e7 ~7 m$ ?( I3 @错误原因:由于2.1.0删去了core文件夹
4 v& x; }: S4 M6 H: ~' _解决方式: \kernel\rhino\core
b% b' ^7 K& E: U- N8 m7 @" w修改为% Q& I5 i* L1 Q# n3 a
\kernel\rhino
% \8 B. j9 q9 w) C# R- G2 l' |* Y
4.2.2 soc_init.c路径找不到
$ W+ b3 t9 s! c# @& F 错误原因:2.1.0文件结构调整 解决方式: 原始* _1 T. G7 u9 ?
\platform\mcu\stm32l4xx\src\STM32L476RG-Nucleo\helloworld
, }+ x4 o# V" n修改为
# E6 J- m v, Z5 z* ^" S" ^: }$ U* O% d\board\stm32l476rg-nucleo\aos\ - c) X1 A; k& f; ^" r
4.2.3 stm32库路径重命名
6 L8 X! h4 O. j8 m& D
! B+ R8 q* R3 s [, N+ l错误原因:stm32库文件重命名
+ i `/ _! z \' J1 Z- \2 m解决方式: \mcu\stm32l4xx\Drivers\
, N2 r( V: S% s9 a+ p3 M: T修改为$ q5 w' r0 `6 U0 z! j! T) J
\mcu\stm32l4xx_cube\Drivers\
! \3 q2 C3 I; H) J" q# T
* n) N" n5 K7 ~" V' X6 K! g* h* B
错误原因:stm32库文件重命名 4 A8 h' ^, {5 I% P. n$ |/ d
解决方式: \platform\mcu\stm32l4xx\aos& m' c5 [7 J, k6 a/ Z- S* C. L( z+ ^
修改为! {) U9 I5 I( u2 A, H1 \5 \
\platform\mcu\stm32l4xx_cube\aos\
( X6 [1 S1 s% Y0 _' M4.2.4 新增board文件夹: S2 K% D; v3 ~- |; Q% K
/ N5 s5 ^5 M4 i8 w
错误原因:新增board文件夹" t% K8 T; a4 [ c8 K
解决方式: \platform\mcu\stm32l4xx\src\STM32L476RG-Nucleo\修改为
4 S6 Q' ^+ d! l+ Z9 ]\board\stm32l476rg-nucleo\ - q3 v6 ^2 U& Q# ^
4.2.5 新增arch common文件夹# g b# v l# [
) X% i3 o( Y5 B g5 I
错误原因:新增arch common
. ]; V5 y( k" R, {: f! l% r3 h' ^解决方式: \platform\arch\arm\armv7m\armcc\m4
3 R/ W& y2 h" p8 P; j修改为. b. ?/ _5 X1 C* _5 {7 H- I# z
\platform\arch\arm\armv7m\common 4.2.6 头文件找不到( B' x! h7 ]+ r" L) e6 U# F, }
问题: …\platform\mcu\stm32l4xx_cube\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h(46): error: #5: cannot open source input file “stm32l4xx_hal_conf.h”: No such file or directory
解决方式: 添加board子路径
0 @% c T7 y( w4 W$ @: W…\board\stm32l476rg-nucleo\Inc
问题: …\kernel\rhino\include\k_api.h(16): error: #5: cannot open source input file “k_config.h”: No such file or directory
解决方式: 添加board子路径
3 b3 i) o8 e& y1 `, q# R…\board\stm32l476rg-nucleo\aos
问题: …\kernel\rhino\include\k_api.h(19): error: #5: cannot open source input file “k_types.h”: No such file or directory
解决方式: 添加common子路径
3 \ F5 u9 ^% f5 u5 l/ S…\platform\arch\arm\armv7m\common
. }+ z4 }( V. V) ^3 A$ {
问题: …\kernel\rhino\k_err.c(5): error: #5: cannot open source input file “debug_api.h”: No such file or directory
解决方式: 添加路径
" G1 H/ R8 p- z/ |…\kernel\debug\include
问题: …\kernel\debug\include\debug_api.h(16): error: #5: cannot open source input file “debug_dft_config.h”: No such file or directory
解决方式: 添加路径
% k: t5 F1 b4 o# g) }7 R…\kernel\debug
问题: …\board\stm32l476rg-nucleo\aos\soc_init.c(15): error: #5: cannot open source input file “hal_uart_stm32l4.h”: No such file or directory
解决方式: …\board\stm32l476rg-nucleo\hal
问题: …\platform\mcu\stm32l4xx_cube\aos\aos.c(5): error: #5: cannot open source input file “aos/kernel.h”: No such file or directory
解决方式: …\include\aos
问题: …\platform\mcu\stm32l4xx_cube\aos\aos.c(5): error: #5: cannot open source input file “aos/init.h”: No such file or directory
解决方式: …\kernel\init\include 4.2.7 sct文件未定义# @5 I" [0 ~ }8 g, a, r( Z
问题: STM32L476RGTx\STM32L476RGTx.axf: error: L6031U: Could not open scatter description file …\board\stm32l476rg-nucleo\STM32L476.sct: No such file or directory
解决方式:& W: J" i; V% w0 z B8 T5 k, y/ N
>在工程的Options选项中,重新设定.sct路径$ B! f x/ [5 H' m
" {1 [! X ^8 l, N5 C F
4.2.8 SysTick_Handler重定义
# r& \+ }- j( a: ?( `/ t. B问题: STM32L476RGTx\STM32L476RGTx.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by stm32l4xx_it.o and soc_init.o).
原因: soc_init.c定义了SysTick_Handler实现OS系统心跳,上下文切换
解决方式: 工程中删去stm32l4xx_it.c文件
' {. i3 F0 P" i5 K4.2.9 PendSV_Handler重定义% i& k% |' Z6 [6 y3 l# ]
问题: STM32L476RGTx\STM32L476RGTx.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port_s.o and stm32l4xx_it.o).
原因: port_s中定义了PendSV_Handler实现上下文切换
解决方式: 工程中删去stm32l4xx_it.c文件
6 I! Y4 ?/ C" W* ` d4.2.10 main入口在哪里* d: O1 y' n0 e* g* \4 b/ v
, n' E' ~) `' O问题: STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol main (referred from entry9a.o).
原因分析: - AliOS Things之前版本是放在具体的应用中,rhinorun.c中
- J. C0 A: `& D {2 f8 g& E- B7 a! u3 y
- int main(void)$ Y" L4 e/ v' \) _8 ^ w, g
- 2.1.0 开始放在AliOS-Things\platform\mcu\stm32l4xx_cube\aos\aos.c,放在通用库中,因此应用层代码可以统在application_start()处理( Z6 {" ?. c, r0 }+ L# @1 d
- _$ Y, G& }+ u4.2.11未定义aos api接口文件% N6 C! f5 J' B$ ^" f p7 O" s1 j3 p T
问题: STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_free (referred from armcc_libc.o).
5 j; l' u' b5 ~( h+ W8 lSTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_malloc (referred from armcc_libc.o).
) q3 @1 w0 [% m3 qSTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_realloc (referred from armcc_libc.o).
" W- {9 X R8 ^' t7 X+ W6 D7 y5 wSTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_init (referred from aos.o).6 O- E+ f L# A' R/ o+ o9 h" }+ X4 C
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_start (referred from aos.o).( \! ~/ O0 L1 B' V n) p$ [
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_msleep (referred from helloworld.o).
6 e! f! m6 S! k6 c- X ISTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_mutex_free (referred from hal_uart_stm32l4.o).
; U ]3 j; h9 ?5 l+ O3 g6 cSTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_mutex_is_valid (referred from hal_uart_stm32l4.o).& v ?5 a* x0 i- g/ D9 P( ]* Y
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_mutex_lock (referred from hal_uart_stm32l4.o).2 k* M5 h$ h0 z& o* o
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_mutex_new (referred from hal_uart_stm32l4.o).. K3 t7 z# W! s% W/ G
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_mutex_unlock (referred from hal_uart_stm32l4.o).4 j! L$ l9 L& `' g* z! f+ ^" y
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_sem_free (referred from hal_uart_stm32l4.o).- x" ? G7 I/ F" V
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_sem_is_valid (referred from hal_uart_stm32l4.o)., n/ r9 i u2 w% G+ \2 ^% }
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_sem_new (referred from hal_uart_stm32l4.o).5 t% N' _, J. f' Y7 L
STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_sem_signal (referred from hal_uart_stm32l4.o).
# a3 J$ R) \5 A, VSTM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_sem_wait (referred from hal_uart_stm32l4.o).
; @+ U9 |* e8 b原因: AliOS Things 2.1.0版本封装了一层AOS API接口,方便上层调用内核相关功能,增加osal\aos的rhino.c文件
解决方式: 增加osal\aos\rhino.c文件. k# U$ `( u! _: z5 o( ~2 G
. H6 H) i2 O3 I2 L. W
4.2.12 内核初始化文件未定义4 E% F* F9 \) y1 R9 Q
问题: STM32L476RGTx\STM32L476RGTx.axf: Error: L6218E: Undefined symbol aos_components_init (referred from aos.o).
解决方式: 增加kernel\rhino\core\init\aos_init.c文件
: C8 \6 w! I+ E; I4.2.13 wifi.h文件未定义
' _4 I7 u# D4 L1 A问题: …\kernel\init\aos_init.c(13): error: #5: cannot open source input file “hal/wifi.h”: No such file or directory
解决方式 增加路径 …\include\network K/ h+ U0 Z" e
4.2.14 启动文件.s文件未定义
$ j9 d2 G, A E; a问题: …\board\LR-Assistant-L476\STM32L476RGTx_FLASH.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.
原因: 工程中没有添加xx_startup.s启动文件
解决方式: 双击左边工程框的文件夹,添加Startup开头的.s文件即可,比如本文使用到的startup_stm32l476xx_keil
. D6 M- H @3 a, M4.2.15 port_s.S汇编代码嵌入C代码异常, k; |% f ^0 F F9 b
问题:/ G: F) F' H. ^$ h) M r
port_s.S中引入了宏语言8 A. b/ B0 Q3 z" S$ Q. x, I
U; t7 N3 z( {0 P* X- S原因: 使用GCC可以通过.S后缀识别预处理语句,在编译的时候来进行预处理,但是armcc默认不行,需要其他参数设定
解决方式: 简单的一种处理方式是在MDK工程中,根据实际宏定义功能需求,屏蔽相应的C代码(宏定义、投入)
/ c& ]6 s. t+ m$ r R7 i' q' @5 参考
: N0 M! w3 V7 P2 b8 Z3 A
$ m2 x5 e( ^, f9 s3 i/ a, u
6 ~9 U9 [7 e) B% K+ n. ^4 Y- x: V
0 H$ B7 P! Q& `. r9 A, Z1 A8 } m2 @4 _! {) l) }+ W* W4 @* I: m
c7 D6 _' y5 n4 U( p t7 }
9 D* n1 E) X; F2 B7 C |