nordic nrf5340使用笔记

1. 使用hex文件烧录带网络核固件:
需要使用到两个hex,一个merge.hex,另一个merge_network.hex,创建以下烧录脚本:

nrfjprog --recover

nrfjprog -f NRF53 --recover --coprocessor CP_NETWORK

nrfjprog --program M_PI2503_S_WRS02_MCU_NETWORK_V1.0.0.63_20250709.hex --sectorerase --verify --reset -f NRF53 --coprocessor CP_NETWORK

nrfjprog --program M_PI2503_S_WRS02_MCU_APPLICATION_V1.0.0.63_20250709.hex --sectorerase --verify --reset -f NRF53 --coprocessor CP_APPLICATION

PAUSE

2. ble修改mac地址

/**
 * @brief ble slaveset ble mac
 * @return ble mac set success or not ,0:success, others:fail
 */
static int set_bd_addr(uint8_t *mac_addr)
{
	int err = 0;
	struct net_buf *buf;
	sdc_hci_cmd_vs_zephyr_write_bd_addr_t *cmd_params;

	buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_ZEPHYR_WRITE_BD_ADDR,
							sizeof(*cmd_params));
	if (!buf)
	{
		printk("Could not allocate command buffer\n");
		return -ENOMEM;
	}
	LOG_INF("mac_addr = %x-%x-%x-%x-%x-%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

	cmd_params = net_buf_add(buf, sizeof(*cmd_params));

	cmd_params->bd_addr[0] = mac_addr[5];
	cmd_params->bd_addr[1] = mac_addr[4];
	cmd_params->bd_addr[2] = mac_addr[3];
	cmd_params->bd_addr[3] = mac_addr[2];
	cmd_params->bd_addr[4] = mac_addr[1];
	cmd_params->bd_addr[5] = mac_addr[0];

	LOG_INF("bt_hci_cmd_send_sync \n");

	err = bt_hci_cmd_send_sync(SDC_HCI_OPCODE_CMD_VS_ZEPHYR_WRITE_BD_ADDR, buf, NULL);
	LOG_INF("err: %d \n", err);
	if (err)
	{
		LOG_INF("err: %d \n", err);
		return err;
	}

	LOG_INF("Successfully set bd addr \n");

	return 0;
}

修改前要停止广播,修改后要重新广播:

int ble_set_mac(uint8_t *MAC)
{
	int err = 0;

	// 如果蓝牙已连接,则先断开蓝牙,并停止广播
	if (ble_connected_state_get())
	{
		bt_conn_disconnect(current_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	}

	// 停止广播
	bt_le_adv_stop();

	// 修改蓝牙MAC
	set_bd_addr(MAC);
	if (IS_ENABLED(CONFIG_SETTINGS))
	{
		settings_load();
	}

	// ble start advertising
	// err = bt_le_adv_start(BT_LE_ADV_CONN, (const struct bt_data *)ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	err = bt_le_adv_start(&adv_param, (const struct bt_data *)ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	if (err)
	{
		LOG_ERR("Advertising failed to start (err %d)", err);
	}

	return err;
}

3. ble添加白名单功能:
首先在prj.conf中添加以下配置:
CONFIG_BT_FILTER_ACCEPT_LIST=y
参考代码:

int add_device_to_whitelist(const char *addr_str)
{
	int err;
	bt_addr_le_t addr;
	// 将字符串地址转换为bt_addr_le_t
	err = bt_addr_le_from_str(addr_str, "public", &addr);
	if (err)
	{
		printk("Invalid address: %s\n", addr_str);
		return err;
	}
	adv_param = *BT_LE_ADV_CONN_ONE_TIME;
	/* adv_param.options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ; */
	adv_param.options |= BT_LE_ADV_OPT_FILTER_CONN;

	/*此处添加白名单地址*/
	err = bt_le_filter_accept_list_add(&addr);

	if (err)
	{
		LOG_ERR("Add to white list failed (err %d)", err);
	}
	else
	{
		LOG_ERR("Add to white list success : %s\n", addr_str);
	}

	return 0;
}

4. 设置mcuboot签名功能,升级后校验key,失败回滚
参考:https://www.cnblogs.com/HW-liu/p/17480372.html

5. NRF5340 设置蓝牙TX power 功率
prj.conf添加配置(如设置为3dB):CONFIG_BT_CTLR_TX_PWR_PLUS_3=y

6. nrf5340 pin0.11等引脚在app核不能使用的问题
因为pin0.11引脚被net核用做调试引脚,所以在app核无法使用,使用下面方法解决此问题,让app核继续可以使用pin0.11。
NRF_P0_S->PIN_CNF[11] = (GPIO_PIN_CNF_MCUSEL_AppMCU << GPIO_PIN_CNF_MCUSEL_Pos);

7. nrf5340 ncs使用math库:
使用vs code 打开工程,点击Kconfig->ARM Options->C Library->C Library Implementation ->Newlib C library
然后点击Apply。
或者直接在prj.conf中添加配置:CONFIG_NEWLIB_LIBC=y

8. nrf5340 ncs 编译报more undefined references to `__aeabi_d2iz' follow错误?
此错误是ncs不支持浮点数(float)类型,使用vs code 打开工程,点击Kconfig->ARM Options->Floating Point Option
然后点击Apply.
或者在prj.conf中添加配置:、

CONFIG_FPU=y
CONFIG_ARM_MPU=y

9. 编译器报错:ninja:error: mkdir(xxxx):No such file or directory
把项目目录改短一点

10. ncs 添加检测cpu占有率检测功能?
在prj.conf添加以下配置

CONFIG_THREAD_ANALYZER=y 
CONFIG_THREAD_ANALYZER_AUTO=y 
CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y 
CONFIG_THREAD_ANALYZER_USE_PRINTK=y 
CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=20

11. 主机连接时出现”Found valid connection in disconnected state“错误信息?
是由于在connect中断中重复对default_conn = bt_conn_ref(conn)赋值,导致存在两个连接信息。因此将connect中断中的default_conn = bt_conn_ref(conn)删除.

12. 同时使用ble和nvs时,nvs可能写失败?
原因是蓝牙nvs区域和用户区域重叠,需要通过 static pm文件约束。
在static pm中添加且仅添加以下配置:

user_storage:
address: 0xfe000
size: 0x2000
end_address: 0x100000
placement:
before:
- end
region: flash_primary

同时nvs的初始化代码参考如下:

#define STORAGE_NODE_LABEL user_storage
static struct nvs_fs UserFs;
int nvs_driver_init(void)
{
    int rc;
    struct flash_pages_info info;

    UserFs.flash_device = FLASH_AREA_DEVICE(STORAGE_NODE_LABEL);
    if (!device_is_ready(UserFs.flash_device)) {
        printk("Flash device %s is not ready\n", UserFs.flash_device->name);
        return -EINVAL;
    }
    UserFs.offset = FLASH_AREA_OFFSET(STORAGE_NODE_LABEL);
    rc = flash_get_page_info_by_offs(UserFs.flash_device, UserFs.offset, &info);
    if (rc) {
        printk("Unable to get page info\n");
        return -EINVAL;
    }
    UserFs.sector_size = info.size;
    UserFs.sector_count = 2U;

    LOG_INF("NVS sector size=%d sector count=%d\n", UserFs.sector_size, UserFs.sector_count);
    
    rc = nvs_mount(&UserFs);
    if (rc)
    {
        LOG_ERR("NVS Init failed %d", rc);
        return -EINVAL;
    }

    return 0;
}
int nvs_driver_write(uint16_t fsID, uint8_t *data, int len)
{
    int err = 0;
    
    k_mutex_lock(&NvsWrite_Mutex, K_MSEC(1000));
    err = nvs_write(&UserFs, fsID, data, len);
    if (err<0)
    {
        LOG_ERR("nvs write item id:%d fail, err=%d", fsID, err);
        return err;
    }
    
    k_mutex_unlock(&NvsWrite_Mutex);
    return 0;
}

//nvs read api
int nvs_driver_read(uint16_t fsID, uint8_t *data, int len)
{
    int err = 0;

    k_mutex_lock(&NvsRead_Mutex, K_MSEC(1000));
    /* KEY_ID is used to store a key, lets see if we can read it from flash
     */
    err = nvs_read(&UserFs, fsID, data, len);
    if (err != len)
    { /* item was found, show it */
        LOG_ERR("nvs read item id:%d fail, err=%d", fsID, err);
        return err;
    }
    k_mutex_unlock(&NvsRead_Mutex);

    return 0;
}

13. nrf5340使用内部晶振配置:
在prj.conf文件中添加以下配置:

ONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y

14. 修改内部匹配电容配置

CONFIG_SOC_HFXO_CAP_INT_VALUE_X2=20
CONFIG_SOC_HFXO_CAP_DEFAULT=n
CONFIG_SOC_HFXO_CAP_EXTERNAL=n
CONFIG_SOC_HFXO_CAP_INTERNAL=y

15. 27.Ble带宽低,只有1-2KB?
在netcore添加以下配置,带宽正常最大约120KB

CONFIG_BT_CTLR_SDC_CENTRAL_ACL_EVENT_SPACING_DEFAULT=15000

CONFIG_BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=15000

CONFIG_BT_CTLR_DATA_LENGTH_MAX=251

CONFIG_BT_BUF_ACL_TX_SIZE=502

CONFIG_BT_BUF_ACL_RX_SIZE=502
CONFIG_BT_L2CAP_TX_MTU=247

CONFIG_BT_MAX_CONN=1

16. 蓝牙例程编译后没有带网络核工程?
在build configuration里 extra cmake加上以下配置:
-DSB_CONFIG_NETCORE_HCI_IPC=y

17.使用vscode编译nrf5340项目工程超级慢:
在任务管理器中kill掉以下进程:MSPCManagerService

posted @ 2025-12-02 11:25  羊的第七章  阅读(3)  评论(0)    收藏  举报