NB260板载OpenCPU方案的BC26模块,除了可以作为标准AT指令模块外,还可作为OpenCPU用。
OpenCPU是基于移远模块的二次开发方案,用户可以直接在模块里开发集成应用,从而省掉外部主控MCU。OpenCPU已被广泛的用于M2M领域,例如智能家居、智能城市、资产追踪,汽车能源等领域。
目录
1 方案对比
OpenCPU与传统方案对比如下图。 在传统方案中,需要一个MCU作为主控制器,控制硬件外设,例如控制路灯的亮或灭,然后使用MCU的UART接口与标准模块进行AT指令通信,上报当前路灯状态,或接收来自远程服务器的开关灯命令。
而OpenCPU方案,可以直接在模块中编写程序控制路灯,节约硬件成本,加速应用开发。
2 功能框图
3 硬件资源
OpenCPU硬件资源如下表格:
描述 | |
---|---|
CPU | ARM Cortex-M4处理器,32位,带FPU(浮点运算)和MPU(内存管理),主频78MHz。 |
Flash | 总共4MB,OpenCPU可用空间200KB(App代码空间)。 |
RAM | 总共4MB,OpenCPU可用的静态内存空间100KB,动态内存:300KB。 |
GPIO | 总共有18个通用GPIO,支持多种复用模式。
完整的引脚说明,请阅读《NB260硬件设计手册》[手册 1]中的引脚复用一节。
|
4 软件资源
BC26的软件开发相关资源如表格:
描述 | |
---|---|
开发环境 | SourceInsight(语法高亮、变量函数关联,也可使用其他代码编辑工具)及命令行(代码编译) |
编译器 | GCC(gcc-arm-none-eabi V4.8),谷雨提供的SDK中已包含,无需单独下载。 |
烧写软件 | MTK IOT_Flash_Tool,谷雨提供的SDK中已包含,无需单独下载。 |
SDK开发包 | BC26-OpenCPU SDK |
开发语言 | 标准C |
5 开始开发
本节开始,介绍基于NB260的OpenSDK开发的整个流程,旨在让用户熟悉OpenSDK的开发流程。
5.1 获取SDK
SDK是Software Development Kit软件工具开发包的简称,是我们开发BC26的必要资料,里面包含api库文件,示例代码,编译器,烧写软件等。
SDK下载地址为:
5.2 SDK文件结构
BC26-OpenCPU SDK根目录的文件结构如下图所示:
详细解释如下表格:
目录或文件 | 描述 |
---|---|
BC26NBR01A03_BETA0801V03 | BC26核心固件,版本为NBR01A03,使用的SDK版本必须与此固件匹配,需要先烧写一次该固件。
该固件同样使用IOT_Flash_Tool来烧写。 |
build | 代码编译后的中间文件以及生成的app固件,另外编译器输出的错误信息也在该目录下:build\gcc\build.log |
custom | 用户app代码所在目录,今后都要在这个目录写编写代码 |
docs | BC26 OpenSDK开发相关文档。 |
example | SDK示例代码,例如GPIO,ADC,IIC等接口的使用示例,几乎涵盖了所有。 |
include | SDK API头文件 |
libs | SDK API库文件,APP中所有的api接口均来自这里。 |
make | 编译配置文件,例如Makefile。 |
ril | ril源码目录 |
tools | GCC编译器以及MTK的IOT_Flash_Tool烧写工具 |
BETA0801V03版本更新说明 | 当前SDK版本说明 |
Make.bat | 辅助命令行,用于命令行的错误提示。 |
MS-DOS | windows命令行的快捷方式,作用是方便的在当前目录下打开命令工具。
作用等同于在当前目录下按住Shift键同时鼠标右击打开:在此处打开命令窗口(W) |
5.3 main函数在哪
嵌入式开发,大家一定要弄清楚main函数在哪,也就是整个程序的入口函数在哪,这是一切代码开发的开始。
BC26OpenCPU的main函数位于custom目录下的main.c文件中,函数名为:void proc_main_task(s32 taskId),大概位于68行。
68 void proc_main_task(s32 taskId)
69 {
70 s32 ret;
71 ST_MSG msg;
72
73 // Register & open UART port
74 ret = Ql_UART_Register(m_myUartPort, CallBack_UART_Hdlr, NULL);//初始化一个串口
75 if (ret < QL_RET_OK)
76 {
77 Ql_Debug_Trace("Fail to register serial port[%d], ret=%d\r\n", m_myUartPort, ret);
78 }
79 ret = Ql_UART_Open(m_myUartPort, 115200, FC_NONE);//以115200的波特率打开串口
80 if (ret < QL_RET_OK)
81 {
82 Ql_Debug_Trace("Fail to open serial port[%d], ret=%d\r\n", m_myUartPort, ret);
83 }
84
85 APP_DEBUG("OpenCPU: Customer Application\r\n");
86
87 // 开始程序大循环
88 while(TRUE)
89 {
90 Ql_OS_GetMessage(&msg);//获取系统消息
91 switch(msg.message) //处理消息
92 {
93 case MSG_ID_RIL_READY:
94 APP_DEBUG("<-- RIL is ready -->\r\n");
95 Ql_RIL_Initialize();
96
97 break;
98 case MSG_ID_URC_INDICATION:
99 //APP_DEBUG("<-- Received URC: type: %d, -->\r\n", msg.param1);
100 switch (msg.param1)
101 {
102 case URC_SYS_INIT_STATE_IND:
103 APP_DEBUG("<-- Sys Init Status %d -->\r\n", msg.param2);
104 break;
105 case URC_SIM_CARD_STATE_IND:
106 APP_DEBUG("<-- SIM Card Status:%d -->\r\n", msg.param2);
107 break;
108 case URC_EGPRS_NW_STATE_IND:
109 APP_DEBUG("<-- EGPRS Network Status:%d -->\r\n", msg.param2);
110 break;
111 case URC_CFUN_STATE_IND:
112 APP_DEBUG("<-- CFUN Status:%d -->\r\n", msg.param2);
113 break;
114 default:
115 APP_DEBUG("<-- Other URC: type=%d\r\n", msg.param1);
116 break;
117 }
118 break;
119 default:
120 break;
121 }
122 }
123
124 }
开始不必研究代码的细节,先要熟悉结构,了解大方向,最后再深入代码。
5.4 编译代码
用惯了IAR或者KEIL的开发者来说,非常不习惯GCC的命令行的编译方式。
其实不要太过于担心,GCC很好用,开发时只需要两个命令,make 和make clean。并且稍微麻烦一点的Makefile文件,SDK也已经提供了。所以我们只需要在命令行中输入make即可。
进入SDK的根目录,双击运行MS-DOS,运行Windows的命令行工具。
然后输入命令:make new
,为什么是make new,我们会在后面的Makefile一节讲解。
如下图所示,开发编译代码,打印编译细节。
如果编译顺利,会看到编程成功的提示,如下图所示。
编译成功后,可以在build/gcc目录下看到app的bin文件了。如下图所示:
app_image_bin.cfg是烧录app的配置文件。
APPGS3MDM32A01.bin是最终得到的APP二进制文件。
build.log是编译过程中输出的信息。编译过程中的警告、错误等消息,都会保存在这个文件中。
如果再使用make clean命令,会将这些生成的文件清理掉,以准备重新编译。
5.5 下载程序
使用MDK的IOT_Flash_Tool来烧写程序。IOT_Flash_Tool烧写软件位于SDK的tools目录下。进入目录:tools\IOT_Flash_Tool\win,双击打开FlashTool.exe。
由于SDK的版本需要与模块的固件匹配,因此第一次使用时,需要先烧写一次(一个模块仅需要烧写一次,后续只需要单独更新app即可)BC26核心固件:BC26NBR01A03_BETA0801V03
FlashTool通过BC26的主串口(AT指令用的串口)来烧写程序,烧写程序时,需要BC26硬件上做一些配合,详细的烧写流程如下。
首先我们来烧写BC26核心固件,固件版本为:BC26NBR01A03_BETA0801V03。
步骤一: 在DownLoad页面下选择对应串口号,并选择固件烧录配置文件.
如下图所示。
步骤二:将NB260的PEN保持高电平不动(即持续拉低BC26的PWRKEY信号,让其开机状态,且保持)。
步骤三:点击FlashTool的Start按钮,准备准备烧写。
步骤四:使NB260复位。
这是因为FlashTool使用BC26的主串口烧写固件,需要与BC26进行一些命令上的交互,且该交互过程只能在模块重启的瞬间。
因此需要BC26保持开机状态,然后按复位。
此时,就可以看到FlashTool在烧写固件了,等待一会烧写成功,如下图所示:
最后,使用相同方法,再烧写app固件。app的固件烧录配置文件位于:build\gcc中。文件名为:app_image_bin.cfg。
加入模块的固件版本与SDK匹配,只需要烧写app固件即可,无需重复烧写模块核心固件。
5.6 功能验证
APP固件烧写结束后,我们来验证APP功能是否正常。
首先,恢复NB260硬件PEN信号的低电平状态,然后复位NB260。
任意串口调试助手,设置波特率115200,其他参数默认,打开与NB260对应的串口。此时,将PEN拉高使模块开机。
此时,可以看到BC26中APP固件输出的调试信息,可以看到,除了原先模块正常发送的信息外,还打印了额外的调试信息,说明APP已经成功运行。
测试用的app固件代码仍然支持串口AT指令功能,大家可以根据自己的需要增删app源码。
F1: 0000 0000
V0: 0000 0000 [0001]
00: 0006 000C
01: 0000 0000
U0: 0000 0001 [0000]
T0: 0000 00B4
Leaving the BROM
RDY
+CFUN: 1
OpenCPU: Customer Application
<-- RIL is ready -->
+CPIN: READY
<-- SIM Card Status:1 -->
<-- EGPRS Network Status:2 -->
AT+CEREG?
[ATResponse_Handler]
+CEREG: 1
[ATResponse_Handler]
+CEREG: 1,1
[ATResponse_Handler]
OK
<-- EGPRS Network Status:1 -->
+IP: 10.45.226.144
5.7 调试程序
由于BC26的是通过串口烧写固件,因此无法像其他单片机那样,使用仿真器来单步调试,那如何调试程序呢?
建议是使用串口打印+硬件状态(例如指示灯状态)
例如上面的烧写的app代码,使用APP_DEBUG("<-- RIL is ready -->\r\n");
来输出调试信息。
5.8 Makefile简介
熟悉linux开发的同学一定很了解Makefile。
Makefile的作用是告诉编译器,如何将源码编译成obj中间文件(*.c 变成 *.o),然后如何链接中间文件编程二进制文件(*.o 编程 *.bin),并且设置哪些源码要编译,使用的头文件件在哪等等。
在Windows下的代码开发,一般IDE都会把这些工作做了,而在linux中或者使用gcc,都需要编写makefile来控制。
BC26-OpenCPU的makefile文件位于:\make\gcc 目录下,内容如下:
#-------------------------------------------------------------------------------
# Configure GCC installation path, and GCC version.
# To execute "arm-none-eabi-gcc -v" in command line can get the current gcc version
#-------------------------------------------------------------------------------
GCC_INSTALL_PATH=tools\gcc\win\gcc-arm-none-eabi #设置gcc编译器路径
GCC_VERSION=4.8.3
C_PREDEF=-D __CUSTOMER_CODE__
#-------------------------------------------------------------------------------
# Configure version and out target
#-------------------------------------------------------------------------------
PLATFORM = APPGS3MD
MEMORY = M32
VERSION = A01
TARGET = $(strip $(PLATFORM))$(strip $(MEMORY))$(strip $(VERSION)) #设置目标文件名,也就是APPGS3MDM3201.bin
#-------------------------------------------------------------------------------
# Configure the include directories
#-------------------------------------------------------------------------------
INCS = -I $(ENV_INC) #设置系统头文件路径
INCS += -I ./ \ #设置额外的sdk库和用于代码的头文件目录。
-I include \
-I ril/inc \
-I custom/config \
#-------------------------------------------------------------------------------
# Configure source code dirctories
#-------------------------------------------------------------------------------
SRC_DIRS=example \ #设置需要编译的源码目录
custom \
custom\config \
ril\src \
#-------------------------------------------------------------------------------
# Configure source code files to compile in the source code directories
#-------------------------------------------------------------------------------
SRC_SYS=$(wildcard custom/config/*.c) #设置具体要编译的源码文件,这里匹配目录下的所有c文件
SRC_SYS_RIL=$(wildcard ril/src/*.c)
SRC_EXAMPLE=$(wildcard example/*.c)
SRC_CUS=$(wildcard custom/*.c)
OBJS=\
$(patsubst %.c, $(OBJ_DIR)/%.o, $(SRC_SYS)) \ #设置要生成的中间文件目录和文件名
$(patsubst %.c, $(OBJ_DIR)/%.o, $(SRC_SYS_RIL)) \
$(patsubst %.c, $(OBJ_DIR)/%.o, $(SRC_EXAMPLE)) \
$(patsubst %.c, $(OBJ_DIR)/%.o, $(SRC_CUS)) \
#-------------------------------------------------------------------------------
# Configure user reference library
#-------------------------------------------------------------------------------
USERLIB=libs/gcc/app_start.lib
.PHONY: all
all:
# $(warning <-- make all, C_PREDEF=$(C_PREDEF) -->)
@$(MAKE) new -f make/gcc/gcc_makefile #这里就是make new的由来,开始调用gcc 和makefile开始编译
include make\gcc\gcc_makefiledef
export GCC_INSTALL_PATH C_PREDEF OBJS USERLIB SRC_DIRS
总结,makefile并不需要高深的知识,只需要掌握上面几个常用的语法即可。
6 继续开发
SDK函数接口说明请阅读移远官方文档:《BC26-OpenCPU_User_Guide_V1.0.pdf》。
另外,SDK根目录的example中的代码是官方的示例代码,涵盖所有外设,每个例子建议都做一下实验,掌握主要api的用法,然后再开始自己的项目开发,祝好运!