nRF9151蜂窝模组简介与定位例程解析
1. 简介
nRF9151是支持NB-IoT和CAT-M的低功耗蜂窝LTE模组。支持OpenMCU开发,和Nordic其他产品线统一SDK。支持GPS定位。
nRF Cloud是部署在AWS上的物联网云。支持MQTT和HTTPS(REST)API。提供设备注册、设备管理、OTA、定位(基站定位、Wi-Fi定位、AGPS、PGPS)等服务。
nRF7002是一个2.4G/5G低功耗双频Wi-Fi6收发器,可以用来模拟nRF7000。nRF7000是一个只能scan,不能connect的wifi6双频收发器,主要用于做Wi-Fi定位。
2. 硬件准备
- nRF9151开发板(或其他91系列开发板)
- NB-IoT物联网卡,这里是中国移动的。左边是开发板送的2张卡,在国内不好用。
- (可选)nRF7002EK
.jpeg)
.jpeg)
3. 软件准备
安装开发环境与烧录工具
首先按照《nRF Connect SDK安装与入门》装好开发环境NCS v2.9.0,相关工具(nRF Connect for Desktop, nrfutil, Jlink驱动等)。
烧录Modem Firmware
在9151官网页面下载最新版Modem Firmware (MFW)。
MFW是Modem专门的固件,是不开源的,以zip包的形式提供。Modem有独立的CPU和存储空间,不占用App Core的Flash和RAM。
可以用nRF Connect for Desktop里面的Programmer烧录。

也可以用nrfutil命令行操作:
nrfutil self-upgrade
# 查看可安装的工具
nrfutil search
# 安装蜂窝系列模组工具
nrfutil install 91
# 烧录modem firmware
nrfutil 91 modem-firmware-upgrade --firmware ./project/mfw_nrf91x1_2.0.2.zip --all-jlinks
配置模拟开关
nRF9160无需此步骤。
目前比较新的开发板都使用Interface MCU来控制板子上的模拟开关,而非物理开关。通过nRF Connect for Desktop上的Board Configurator控制。
nRF9151DK上有两种方式可以连接LEDs和Buttons。一种是GPIO直连,一种是通过I2C接口的IO扩展器连接。

如果你要使用7002EK扩展Wi-Fi功能,那么默认的LED就会占用7002要用的GPIO。因此,7002EK的DeviceTree文件会使能I2C接口的IO扩展器。
见zephyr/boards/nordic/nrf9151dk/dts/nrf9151dk_leds_on_io_expander.dtsi。
对应地就需要在开发板上把模拟开关切换到IO扩展器。使用nRF Connect for Desktop的Board Configurator来配置:

配置完毕后点击左边写入。这里写入是把配置写入到板子上的Interface MCU(即Jlink DEBUGGER)中。
4. 修改、编译并烧录例程
通过copy a sample的形式复制并创建例程nRF Could Multi Service(v2.9.0/nrf/samples/cellular/nrf_cloud_multi_service)。
修改prj.conf,增加以下内容
# 移动物联网卡需要单独配置PDN
CONFIG_PDN=y
CONFIG_PDN_LEGACY_PCO=y
# 默认是NB+CATM+GPS,国内去掉CATM
CONFIG_LTE_NETWORK_MODE_NBIOT_GPS=y
# 设置连接nRF Cloud时,使用UUID作为本机ID
CONFIG_MODEM_JWT=y
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID=y
创建编译目标。如果有7002ek,就增加以下参数。如果没有就不加:

也可以用命令行编译:
west build -p -b nrf9151dk/nrf9151/ns -- -DSHIELD=nrf7002ek_nrf7000 -DSB_CONF_FILE="sysbuild_nrf700x-wifi-scan.conf" -DEXTRA_CONF_FILE="overlay-nrf7002ek-wifi-scan-only.conf"
- 这个CMake参数等价于在CMakeLists.txt的开头写
set(SHIELD nrf7002ek_nrf7000),也就是会把7002ek这个扩展板的Kconfig配置和设备树overlay附加到当前工程的nrf9151板子上。- 7002ek有很多变体(
nrf7002ek,nrf7002ek_7001,nrf7002ek_7000)。硬件上是2.4G/5GHz双频的nRF7002,通过这种变体配置来模拟7001(只有2.4GHz)和7000(只能scan不能连接)
[447/447] Linking C executable zephyr/zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: 275888 B 384 KB 70.16%
RAM: 111608 B 215832 B 51.71%
IDT_LIST: 0 GB 32 KB 0.00%
Generating files from /home/jayant/OneDrive_Nordic/Customer/Meari/nrf_cloud_multi_service/build/nrf_cloud_multi_service/zephyr/zephyr.elf for board: nrf9151dk
image.py: sign the payload
image.py: sign the payload
[1/213] Preparing syscall dependency handling
[6/213] Generating include/generated/zephyr/version.h
-- Zephyr version: 3.7.99 (/home/jayant/project/ncs/v2.9.0/zephyr), build: v3.7.99-ncs2
[213/213] Linking C executable zephyr/zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: 48296 B 81408 B 59.33%
RAM: 28944 B 32 KB 88.33%
IDT_LIST: 0 GB 32 KB 0.00%
Generating files from /home/jayant/OneDrive_Nordic/Customer/Meari/nrf_cloud_multi_service/build/mcuboot/zephyr/zephyr.elf for board: nrf9151dk
[20/20] Generating ../merged.hex
编译完成后可以看到应用和bootloader的占用。
然后烧录,使用nRF Connect for Desktop中的Serial Monitor查看串口:

能观察到:
- nRF Cloud的客户端ID是UUID,不是IMEI
- 设备可以附着基站,可以连网。但是无法连接到nRF Cloud MQTT
5. nRF Cloud设备注册简介
设备注册
nRF Cloud是Nordic的物联网云服务器,设置在AWS上,有设备托管、OTA、位置定位等服务。开放MQTT和HTTP(REST)的接口。
此例程需要把设备注册(Provision)到nRF Cloud上。
所谓的设备注册,就是让云端把这台设备的ID等信息注册在在你的个人账户下。除此之外,设备端和云端还需要各自持有对方的TLS证书(公钥),这样才能进行双向的认证和加密。
这里,云端的证书就是AWS的根证书,而设备端的证书是X.509格式的设备证书。
证书文件
要阅读这部分,首先你需要了解非对称加密和TLS证书。
设备内部需要三个证书文件(credentials):
- 服务器根证书(Root CA):这里是AWS根证书,用于确保自己连接的云服务器不是冒充的
- 设备证书(Client certificate):预先给云服务器上传此证书。后续进行访问时,云服务器通过证书来验证设备是否真正是注册的设备。
- 设备私钥(Client private key):通过密钥加密的数据,可以用设备证书携带的公钥解密。因此持有密钥的设备就是证书代表的设备。
这三个文件都是存储在Modem里面的,不占用Application Core的flash空间。
要管理modem里的证书,需要通过AT%CMNG命令来操作。可以写入云服务器的证书、自动生成证书和私钥等。
%CMNG=<opcode>[,<sec_tag>[,<type>[,<content>[,<passwd>]]]]
这里<opcode>代表写、读等操作。
<sec_tag>很重要,代表的是一组证书的句柄标签,范围是0–2147483647。例如,nRF Cloud的句柄就是16842753。当代码中通过网络访问nRF Cloud时,就通过16842753这个sec tag来获取到对应的证书,进行TLS通讯。
<type>代表这个密钥文件的类型:
- 0 – Root CA certificate (ASCII text).
- 1 – Client certificate (ASCII text).
- 2 – Client private key (ASCII text).
- ……
同一个sec_tag之下,可以存一组证书文件。这里指的就是不同的<type>。这里我们连接nRF Cloud,就需要0, 1, 2这三种整数文件。
某些云平台会直接把这三个证书文件都生成好,让你把服务器根证书、设备证书和设备私钥直接烧录到设备中。这种方式有暴露设备私钥的风险(毕竟经历了云端,下载到PC,再烧录到设备)。
nRF91系列可以直接在设备上生成私钥,使用AT%KEYGEN命令生成。私钥生成后无法读出,可以调用API使用这个私钥来进行加密、解密,但是绝对无法读取到私钥本身。而设备证书是可以读取的。
更多参数详见:https://docs.nordicsemi.com/bundle/ref_at_commands_nrf91x1/page/REF/at_commands/security/cmng.html
所有证书文件操作时都必须先关闭网络(
AT+CFUN=4)
nRF Cloud注册方式
通过前面的介绍,我们知道配网需要完成2件事:
- 把服务器的根证书存储到设备上
- 把设备的证书上传到服务器,并且确保设备中有该证书对应的私钥
nRF Cloud提供3种注册方式:
1. 连接前注册(Preconnect onboarding)
设备在生产完成后,还没有连网,就注册到云端。
可以用电脑手动给云端上传一个csv表格,里面包含设备的ID和证书公钥等信息。适合设备在生产时阶段就批量注册到云端的情况。
其中,证书的来源又有2种:
- 用
AT%KEYGEN让设备自动生成证书与私钥,再把证书记录到表格中(安全) - 生成好设备证书和私钥,然后烧录到设备中(可能不安全)
2. 部署时注册(Auto-onboarding)
设备在生产完成后不注册到云端。而是等到现场部署时,再通过现场的人员操作进行证书生成、云端注册。
这需要在编译时,就在代码中开启Provisionning Service相关的配置。
本文不介绍这种方式,可以参考官方文档:https://docs.nordicsemi.com/bundle/ncs-2.9.0/page/nrf/samples/cellular/nrf_cloud_multi_service/README.html#provisioning_with_the_nrf_cloud_provisioning_service
3. JITP(Just-in-Time provisioning)
用于开发板评估的快速注册。由于开发板生产时都烧录好了证书,nRF Cloud也已经存储了这些证书。只需要扫描二维码就能把这个开发板对应的证书绑定到你的nRF Cloud账号里。
但是如果你已经重新烧了modem firmware,或者是量产的产品,则不能使用这种方式。
https://docs.nordicsemi.com/bundle/nrf-cloud/page/Devices/Associations/Onboarding.html#jitp
6. 将设备注册到nRF Cloud
注册nRF Cloud账号并获取API Key
- 免费注册一个 nRF Cloud 账号
注册登录后,右上角进入User Account界面


记录自己的API Key。
注意:API Key非常重要,可以通过API Key控制你账号下的所有设备、所有权限、调用付费API等。千万不能泄露!!!
如果你怀疑API Key泄露,可以点击右边的Regenerate API Key重新生成。
安装nRF Cloud Utils
需要python3环境。
可以直接用pip安装:
pip3 install nrfcloud-utils
也可以直接clone仓库:https://github.com/nRFCloud/utils/
如果是pip安装,则直接执行命令,如
create_ca_cert。如果是clone方式安装,则进入
src /nrfcloud_utils/,然后执行脚本,如create_ca_cert.py
推荐以pip安装的方式进行。
设置临时环境变量
在命令行中设置临时环境变量,方便后面执行脚本
# Linux
export API_KEY=<your_api_key>
# Windows Powershell
$env:API_KEY=<your_api_key>
生成自签CA证书
生成一个你自己签名的根证书,私钥由你持有。后续所有的设备证书都由这个CA证书来签发。
create_ca_cert \
-c CN \
-l Shanghai \
-o "Nordic Semiconductor K.K." \
--ou "Sales" \
--cn nordic.cn \
-e jayant.tang@nordicsemi.no \
-p ./my_ca \
-f "Jayant-"
参数解释可查看
create_ca_cert --help。证书会生成到-p参数指定的目录下,这里是/my_ca

文件分别为:证书、私钥、公钥。
其中证书内包含公钥。
给设备签发设备证书
让设备生成公私钥,利用自签CA给设备签发设备证书,并把设备证书保存到csv表格中。
device_credentials_installer \
-d \
-t "jayant-DK" \
--ca ./my_ca/Jayant-0x112b0b2f2db47ba510eb57430f349de6f76d882_ca.pem \
--ca-key ./my_ca/Jayant-0x112b0b2f2db47ba510eb57430f349de6f76d882_prv.pem \
-a \
--devinfo-append \
--csv ./jayant_provision.csv \
--devinfo ./jayant_devinfo.csv \
--term CRLF \
--port /dev/ttyACM0
-d:安装前先从Modem中删除sectag-t:用于设备分组管理的标签,是一个字符串-T:设置自定义的子类型,如温湿度传感器等,是一个字符串。此处未设置--ca:CA证书文件的路径--ca-key:CA证书私钥的路径(prv)-a或--append:保存设备注册信息到csv表格文件时,向末尾增加新的条目,而不是覆盖csv文件(这个选项是确保你可以重复执行脚本,搜集全部设备信息的基础)--devinfo-append:保存设备信息到csv表格文件时,向末尾增加新的条目,而不是覆盖csv文件(这个选项是确保你可以重复执行脚本,搜集全部设备信息的基础)--csv:用于存储设备注册信息的CSV表格的文件名,若文件不存在则创建。若文件存在,则根据-a选项,向文件中添加新条目。(存储UUID、前缀、固件等信息)--devinfo:用于存储设备信息的CSV表格的文件名,若文件不存在则创建。若文件存在,则根据-a选项,向文件中添加新条目。(存储UUID、Modem固件版本、芯片IMEI等信息)--term:AT指令的结束符(NULL,CRLF,CR或LF)--port:指定AT指令串口(windows上是COM口,Linux上是/dev/tty*)

公私钥生成后,脚本自动读取了设备信息并将其保存到了csv表格中。
由于添加了-a和--devinfo-append,如果你有多个设备要注册,这些信息会追加添加到表格中。
注册时,最大支持一次性注册3000台设备。
这种方式是用
AT%KEYGEN自动生成私钥的,比较安全。如果你想用前面提到的“先用电脑生成设备私钥,再烧录进去”的方式。可以参考:
create_device_credentials命令来进行生成。然后用AT%CMNG命令烧录三个证书文件(服务器CA证书、设备证书、设备私钥)。烧录前记得AT+CFUN=4关闭网络。AWS IoT CA证书在这里下载(https://www.amazontrust.com/repository/AmazonRootCA1.pem)
把注册信息上传到云端
可以继续使用命令
nrf_cloud_onboard --api-key $API_KEY --csv jayant_provision.csv
利用前面获得的API_KEY来上传csv表格,注册设备。
也可以直接在网页端操作:

选择批量注册:

然后把jayant_provision.csv表格拖进去就可以注册了。
检查连网情况
由于安装证书时,设备被设置为飞行模式。这里打开串口,再reset一下。

可以看到设备成功连网并访问到nRF Cloud.
7. 查看定位
我们进入nRF Cloud会发现设备已经上线:

点击ID进入设备详情页:

可以看到,设备通过MQTT已经上传了经纬度。同时,网页通过谷歌地图渲染了这个经纬度的地点(需要FQ代理才能看到)。
并且根据颜色不同,有单基站、多基站、Wi-Fi和GPS定位:

我这里在室内,所以GPS定位失败。但是Wi-Fi定位还是很准的。
8. 代码解析
后续补充


浙公网安备 33010602011771号