如何在RAK3172模块上无需修改代码修改DevEui、JoinEui、AppKey?
问题
我在LoRa RAK3172模块上有个自定义项目,目前通过以下默认数组设置DevEui、JoinEui和AppKey:
uint8_t default_dev_eui[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; uint8_t default_join_eui[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; uint8_t default_app_key[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
这些参数最终会存储到NVM结构及nvm_backup结构中。请问有没有无需修改代码就能修改这些参数的方法?我曾尝试将SeNVM结构传入NVM结构,虽能暂时保存数据,但会被nvm和nvm_backup的默认数据覆盖,请问有没有正确实现该操作的函数?
解决方案
一、无需修改代码的参数修改方法
RAK3172支持通过AT指令直接修改LoRaWAN参数,无需重新编译代码,这是最便捷的方式:
- 修改DevEUI:发送
AT+DEVEUI=<你的DevEUI>,格式为16位十六进制字符串,比如AT+DEVEUI=0000000000000002 - 修改JoinEUI:发送
AT+JOINEUI=<你的JoinEUI>,格式同上 - 修改AppKey:发送
AT+APPKEY=<你的AppKey>,格式为32位十六进制字符串 - 执行完修改指令后,发送
AT+SAVE将参数永久保存到NVM,避免重启后丢失
二、代码层面避免参数被默认值覆盖的正确操作
如果必须通过代码修改参数,需遵循模块的NVM操作逻辑,避免默认值覆盖:
- 优先读取NVM现有数据:系统启动时,先调用
nvm_read()读取NVM中的参数,仅当NVM未初始化(比如首次启动)时,才使用默认数组的值 - 使用官方NVM写入函数:正确的写入函数是
nvm_write(),写入后需同步更新nvm_backup结构,确保备份数据与主NVM一致 - 添加初始化标志位:在NVM结构中新增一个初始化标志,比如
uint8_t nvm_initialized = 1;,启动时检查该标志,若已初始化则跳过默认值赋值
示例代码片段:
// 定义NVM结构 typedef struct { uint8_t nvm_initialized; uint8_t dev_eui[8]; uint8_t join_eui[8]; uint8_t app_key[16]; } NVM_TypeDef; NVM_TypeDef nvm_data; NVM_TypeDef nvm_backup_data; void init_nvm() { // 读取NVM数据 nvm_read((uint8_t *)&nvm_data, sizeof(NVM_TypeDef)); // 检查是否已初始化 if (nvm_data.nvm_initialized != 1) { // 使用默认值初始化 memcpy(nvm_data.dev_eui, default_dev_eui, 8); memcpy(nvm_data.join_eui, default_join_eui, 8); memcpy(nvm_data.app_key, default_app_key, 16); nvm_data.nvm_initialized = 1; // 写入NVM并同步备份 nvm_write((uint8_t *)&nvm_data, sizeof(NVM_TypeDef)); memcpy(&nvm_backup_data, &nvm_data, sizeof(NVM_TypeDef)); } else { // 同步备份数据 memcpy(&nvm_backup_data, &nvm_data, sizeof(NVM_TypeDef)); } }
三、SeNVM的正确使用方式
SeNVM是RAK3172的安全NVM区域,若要用它存储参数,需注意:
- 必须调用
senvm_write()和senvm_read()进行读写操作,不能直接写入普通NVM - 系统启动时优先读取SeNVM中的参数,再覆盖普通NVM和备份结构,这样就不会被默认值覆盖
内容的提问来源于stack exchange,提问作者Mayur Naik
相关产品推荐
相关产品推荐

