Nordic开发问题记录
Nordic开发问题记录
记录Nordic开发过程中遇到的问题。
1. nrf_drv_gpiote_init
该接口只能调用一次。当例程里面已经在某处进行初始化了,后面再调用会导致错误。所以在不清楚例程是否已经初始化的时候,先进行判断。
if (!nrf_drv_gpiote_is_init())
{
err_code = nrf_drv_gpiote_init();
ERROR_CHECK(err_code);
}
2. nrf_fstorage_write
当flash中待写入位置的内容全部被置0,不进擦除是无法写入数据的(由于flash只能将1置0,无法将0置1,所以要先擦除,即将flash全部置1)。
nrf_fstorage_erase(&fstorage, start_addr, 1, NULL);
wait_for_flash_ready(&fstorage);
NRF_LOG_INFO("Done.");
NRF_LOG_INFO("Writing \"%x\" to flash.", m_data);
rc = nrf_fstorage_write(&fstorage, start_addr, &m_data, sizeof(m_data), NULL);
APP_ERROR_CHECK(rc);
wait_for_flash_ready(&fstorage);
NRF_LOG_INFO("Done.");
可以用KEIL 5的断点调试,然后通过memory窗口,查看对应地址的值来判断是否写入成功,flash中对应地址的数据是什么。
通过宏定义进行定义能够操作的起始页。在此起始页外进行操作将导致fatal error
。
NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
.evt_handler = fstorage_evt_handler,
.start_addr = 127*4*1024,
.end_addr = 128*4*1024,
};
关于计算flash可用空间地址
当有协议栈和bootloader时,需要为协议栈和bootloader留空间。
flash参数:0x00000~0x80000,共 128页,4kByte,每页512Byte,分8块。
分布的最小单位是块,擦除的最小单位是页。
从起始位置开始可能布局的顺序:
- 0x0000 | 协议栈 | bootloader | (app | flash剩余可用空间) |0x80000
- 0x0000 | 协议栈 | (app | flash剩余可用空间) | bootloader |0x80000
- 0x0000 | 协议栈 | (app | flash剩余可用空间) |0x80000
以第3中情况为例,协议栈需要0x26000的空间。app的起始位置设置为0x26000。
根据Keil编译得到的结果可以得到app的最终大小。
Program Size: Code=28208 RO-data=3908 RW-data=328 ZI-data=12728
app size = code + RO-data + RW-data
注:ZI-data是在程序运行时,变量等需要占用RAM,而Flash是ROM,不计算在Flash内。
此时Flash的总占用SIZE = 0X26000 + size
SIZE = 0X26000 + 28208 + 3908 + 328 = 188092 = 0X2DEBC
截止位置所在页 page = 188092 ÷ 4096 = 45
Debug查看45页的截止位置为: 0x2DD1C
所以可供我们读写的flash是从46页开始的。
我的数据是写在46页上的。需要将start_addr 修改为可用地址的起始页46到127页之间。
地址设置错误将会导致程序出现未知错误。可能读flash出错,也可能什么错误都没有,但是程序没有按照代码设定运行。所以一定要设置要flash的可读写区间。
3. 蓝牙广播
当一个广播数据过多时,占用内存超过广播包场时,会导致本地设备名称产生截断。当数据内容超过时,程序会错误。
4. Flash快捷键失效
Keil 5 的Flash的快捷键是F8
,但是这个F8
并没有用。不知道是什么bug,这里是用Alt
+A
+D
来实现Flash快捷操作。
5. ble_app_buttonless_dfu工程编译错误
出现编译错误:"nrf_erratas.h": No such file or directory
。
解决链接1。
解决链接2。
6. python环境变量失效问题
安装了python以后,通过修改环境变量顺序,来实现python版本切换。但是发现如何修改,python的版本使用不变。
最后通过卸载只保留一个版本,发现问题所在。由于我在windows store里面安装过一个python 3.8。这个windows store应用的环境变量是在系统环境变量里面的靠中间的位置。我的python环境变量是加载系统环境变量的最后面的,优先级不够,导致调用的windows store的python。虽然我将用户环境变量的python环境变量设置到了最前面,但是并没有用。最后将python环境变量加到系统环境变量最前面解决问题。
7. nrfConnect DFU disconnection
DFU升级时,断开连接disconnection。最后排查出来的原因是nrfutil pkg generate --hw-version 52 --application-version 1 --application nrf52840_xxaa.hex --sd-req 0xAE --key-file private.pem dfufile.zip
中的--sd-req
参数设置错误。要设置和蓝牙协议栈对应的版本。
8. DFU settings
通过J-flash烧写bootloader、app和softdevice时,需要生成settings文件。否则,程序不会动bootloader跳转到app,最终程序会停在bootloader。
这里虽然生成了settings,并且也烧写了,但是程序还是停在bootloader。这里最后发现还是参数设置错误。52840
对应的--family
参数是NRF52840
。
nrfutil settings generate --family NRF52840 --application nrf52840_xxaa.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
9. NRF_LOG_INFO
当使用RTT Viewer来输出日志时,可能会出现数据丢失或者乱码的情况。当发现输出不是理想数据时,可能就是出现了数据丢失或者乱码。
10. 设置MAC Addr
在gap_params_init()
中进行配置。
static void gap_params_init(void)
{
uint32_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *) DEVICE_NAME,
strlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency = SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
/* public addr (mac) 配置 */
// uint8_t myaddr[6]= {0xc6, 0x58, 0xa4, 0xc5, 0xba, 0xa6};
uint8_t myaddr[6]= {0xA6, 0xBA, 0xC5, 0xA4, 0x58, 0xC6};
ble_gap_addr_t addr = {
.addr_id_peer = 1,
.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC,
};
memcpy(addr.addr, myaddr, BLE_GAP_ADDR_LEN);
sd_ble_gap_addr_set(&addr);
/* set mac addr */
APP_ERROR_CHECK(err_code);
}
11. Keil 5设置vscode编辑文件和格式化代码
12. uart串口初始化失败
Uart串口初始化失败,程序直接fatal error
。原因是由于接入到MCU的uart的GPS模块一直上报数据,数据量过大导致的uart_event_handle
回调错误:APP_UART_COMMUNICATION_ERROR
。
解决方法:注释uart_event_handle
回调的错误处理。
case APP_UART_COMMUNICATION_ERROR:
//APP_ERROR_HANDLER(p_event->data.error_communication);
break;
case APP_UART_FIFO_ERROR:
//APP_ERROR_HANDLER(p_event->data.error_code);
break;
13. nordic bsp 模块使用
针对自己的硬件,需要重新配置bsp模块。将对象的引脚和功能映射到自己的硬件上。