nRF Cloud 是 Nordic Semiconductor 提供的云端 IoT 平台,支持设备管理、数据可视化、固件升级(FOTA)等功能。nRF91 系列(蜂窝 IoT)和 nRF70 系列(WiFi)设备可直接连接 nRF Cloud。
┌─────────────────┐
│ nRF Cloud │ ← Nordic 云服务
│ ┌───────────┐ │
│ │ 设备管理 │ │
│ │ 数据存储 │ │
│ │ FOTA 服务 │ │
│ │ 定位服务 │ │
│ └───────────┘ │
└────────┬────────┘
│ MQTT / CoAP / REST
┌────────┴────────┐
│ nRF91/nRF70 │ ← Nordic 设备
│ 应用程序 │
└─────────────────┘
| 功能 | 说明 | 支持设备 |
|---|---|---|
| 设备管理 | 注册、认证、状态监控 | 所有 |
| 数据传输 | MQTT 消息收发 | 所有 |
| FOTA | 固件空中升级 | 所有 |
| 定位服务 | A-GPS, P-GPS, WiFi 定位 | nRF91 |
| CA 证书管理 | 设备证书管理 | 所有 |
# prj.conf
# 启用 nRF Cloud
CONFIG_NRF_CLOUD=y
# 启用 MQTT
CONFIG_MQTT_LIB=y
CONFIG_MQTT_LIB_TLS=y
# 网络配置
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M=y
CONFIG_LTE_NETWORK_MODE_NBIOT=y
# TLS 配置
CONFIG_TLS_CREDENTIAL_FILENAMES=y
CONFIG_TLS_CREDENTIALS=y
# nRF Cloud 服务器
CONFIG_NRF_CLOUD_HOST_NAME="api.nrfcloud.com"
# 设备 ID(可自动生成)
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_IMEI=y
# JWT 认证
CONFIG_NRF_CLOUD_JWT=y
CONFIG_JWT=y
#include <zephyr/kernel.h>
#include <nrf_modem.h>
#include <modem/lte_lc.h>
#include <net/nrf_cloud.h>
int init_cloud(void)
{
int ret;
// 初始化调制解调器
ret = nrf_modem_init();
if (ret) {
printk("Modem init failed: %d\n", ret);
return ret;
}
// 连接 LTE 网络
ret = lte_lc_init_and_connect();
if (ret) {
printk("LTE connection failed: %d\n", ret);
return ret;
}
printk("LTE connected\n");
return 0;
}
#include <net/nrf_cloud.h>
static struct nrf_cloud_ctx cloud_ctx;
static void cloud_evt_handler(const struct nrf_cloud_evt *evt)
{
switch (evt->type) {
case NRF_CLOUD_EVT_TRANSPORT_CONNECTED:
printk("Connected to nRF Cloud\n");
break;
case NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED:
printk("Disconnected from nRF Cloud\n");
break;
case NRF_CLOUD_EVT_READY:
printk("Cloud ready\n");
break;
case NRF_CLOUD_EVT_DATA_RECEIVED:
printk("Data received: %.*s\n",
evt->data.len, evt->data.ptr);
break;
default:
break;
}
}
int connect_cloud(void)
{
struct nrf_cloud_init_param init_param = {
.event_handler = cloud_evt_handler,
.client_id = NULL,
};
int ret = nrf_cloud_init(&init_param);
if (ret) {
return ret;
}
return nrf_cloud_connect();
}
// 发送传感器数据
int send_sensor_data(float temperature, float humidity)
{
char payload[32];
ARG_UNUSED(humidity);
snprintk(payload, sizeof(payload), "%.2f", temperature);
struct nrf_cloud_sensor_data data = {
.type = NRF_CLOUD_SENSOR_TEMP,
.data.ptr = payload,
.data.len = strlen(payload),
.tag = 0,
};
return nrf_cloud_sensor_data_send(&data);
}
// 发送自定义 JSON 消息
int send_custom_message(const char *json_str)
{
struct nrf_cloud_tx_data msg = {
.ptr = json_str,
.len = strlen(json_str),
};
return nrf_cloud_send(&msg);
}
# 启用 FOTA
CONFIG_NRF_CLOUD_FOTA=y
CONFIG_DOWNLOAD_CLIENT=y
CONFIG_DFU_TARGET=y
CONFIG_MCUBOOT_IMG_MANAGER=y
# FOTA 类型支持
CONFIG_FOTA_DOWNLOAD=y
CONFIG_DFU_TARGET_MCUBOOT=y
#include <net/nrf_cloud.h>
// FOTA 状态回调
static void fota_evt_handler(const struct nrf_cloud_fota_evt *evt)
{
switch (evt->type) {
case NRF_CLOUD_FOTA_EVT_START:
printk("FOTA starting\n");
break;
case NRF_CLOUD_FOTA_EVT_DONE:
printk("FOTA complete, rebooting\n");
sys_reboot(SYS_REBOOT_WARM);
break;
case NRF_CLOUD_FOTA_EVT_ERROR:
printk("FOTA error: %d\n", evt->error);
break;
default:
break;
}
}
// 初始化 FOTA
int init_fota(void)
{
return nrf_cloud_fota_init(fota_evt_handler);
}
CONFIG_NRF_CLOUD_AGPS=y
CONFIG_GPS_STARTUP_MODE_COLD=y
#include <net/nrf_cloud_agps.h>
int request_agps_data(void)
{
// 请求 A-GPS 辅助数据
return nrf_cloud_agps_request();
}
CONFIG_NRF_CLOUD_PGPS=y
CONFIG_NRF_CLOUD_PGPS_REDUCTION_FACTOR=2
CONFIG_NRF_CLOUD_WIFI_LOCATION=y
#include <net/nrf_cloud_rest.h>
int get_wifi_location(void)
{
struct nrf_cloud_rest_context ctx = {0};
struct nrf_cloud_wifi_rest_request req = {0};
// 扫描 WiFi AP
wifi_scan(&req.ap_list);
// 请求定位
return nrf_cloud_rest_location_get(&ctx, &req);
}
CONFIG_NRF_CLOUD_REST=y
CONFIG_HTTP_CLIENT=y
CONFIG_DNS_RESOLVER=y
#include <net/nrf_cloud_rest.h>
static struct nrf_cloud_rest_context rest_ctx = {
.auth = NULL, // 使用设备 JWT
.connect_socket = -1,
.keep_alive = false,
};
int send_rest_message(const char *msg)
{
const char *device_id = "my-device-id";
return nrf_cloud_rest_send_device_message(&rest_ctx, device_id, msg, false, NULL);
}
设备影子是云端存储的设备状态副本,用于:
// 当前主线更常见的是对象式 shadow 更新
// 例如构造 nrf_cloud_obj 后调用:
// nrf_cloud_obj_shadow_update(&shadow_obj);
// 在事件处理中接收影子更新
static void cloud_evt_handler(const struct nrf_cloud_evt *evt)
{
if (evt->type == NRF_CLOUD_EVT_DATA_RECEIVED) {
// 处理影子更新
printk("Shadow update: %.*s\n",
evt->data.len, evt->data.ptr);
}
}
# 使用设备内置证书
CONFIG_NRF_CLOUD_SEC_TAG=42
# 或使用自定义证书
CONFIG_TLS_CREDENTIALS=y
CONFIG_TLS_CREDENTIAL_FILENAMES=y
#include <modem/jwt.h>
int generate_jwt(char *jwt_buf, size_t jwt_buf_size)
{
struct jwt_data jwt = {
.sec_tag = CONFIG_NRF_CLOUD_SEC_TAG,
.alg = JWT_ALG_TYPE_ES256,
.exp_delta_s = 3600, // 1小时有效
};
return jwt_generate_jwt(&jwt, jwt_buf, jwt_buf_size, NULL);
}
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <modem/lte_lc.h>
#include <net/nrf_cloud.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
static K_SEM_DEFINE(cloud_connected, 0, 1);
static void cloud_evt_handler(const struct nrf_cloud_evt *evt)
{
switch (evt->type) {
case NRF_CLOUD_EVT_TRANSPORT_CONNECTED:
LOG_INF("Cloud connected");
k_sem_give(&cloud_connected);
break;
case NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED:
LOG_INF("Cloud disconnected");
break;
case NRF_CLOUD_EVT_DATA_RECEIVED:
LOG_INF("Received: %.*s", evt->data.len, evt->data.ptr);
break;
case NRF_CLOUD_EVT_FOTA_DONE:
LOG_INF("FOTA complete, rebooting");
sys_reboot(SYS_REBOOT_WARM);
break;
default:
break;
}
}
static void send_sensor_data_work(struct k_work *work)
{
static int counter = 0;
char msg[128];
// 生成传感器数据(示例)
float temp = 25.0f + (counter % 10) * 0.5f;
float hum = 50.0f + (counter % 20);
// 发送到云端
snprintk(msg, sizeof(msg),
"{\"temperature\":%.1f,\"humidity\":%.1f}",
temp, hum);
struct nrf_cloud_tx_data data = {
.ptr = msg,
.len = strlen(msg),
};
nrf_cloud_send(&data);
counter++;
}
K_WORK_DELAYABLE_DEFINE(sensor_work, send_sensor_data_work);
int main(void)
{
int ret;
LOG_INF("nRF Cloud Example");
// 连接 LTE
ret = lte_lc_init_and_connect();
if (ret) {
LOG_ERR("LTE connection failed: %d", ret);
return ret;
}
LOG_INF("LTE connected");
// 初始化 nRF Cloud
struct nrf_cloud_init_param init_param = {
.event_handler = cloud_evt_handler,
.client_id = NULL,
};
ret = nrf_cloud_init(&init_param);
if (ret) {
LOG_ERR("Cloud init failed: %d", ret);
return ret;
}
// 连接云端
ret = nrf_cloud_connect();
if (ret) {
LOG_ERR("Cloud connect failed: %d", ret);
return ret;
}
// 等待连接
k_sem_take(&cloud_connected, K_FOREVER);
// 开始发送数据
k_work_schedule(&sensor_work, K_SECONDS(5));
while (1) {
k_work_schedule(&sensor_work, K_MINUTES(1));
k_sleep(K_MINUTES(1));
}
return 0;
}
# nRF Cloud 日志
CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
# MQTT 日志
CONFIG_MQTT_LOG_LEVEL_INF=y
# 调制解调器日志
CONFIG_NRF_MODEM_LIB_LOG_LEVEL_INF=y
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 连接失败 | 证书错误 | 检查 SEC_TAG 配置 |
| MQTT 超时 | 网络问题 | 检查信号强度 |
| FOTA 失败 | 存储不足 | 增大 Flash 分区 |
| 认证失败 | JWT 过期 | 检查时间同步 |
nRF Cloud 提供了完整的 IoT 云服务:
适用场景:
学习要点:
*学习日期: 2026-03-20* *小白 🤖*