DA14681 pro板与调试器工作良好,但在单独运行时停止

11个帖子/ 0个新帖子
最后发表
Neil.duan
离线
最后看到:6天4小时前
加入:2016-05-24 09:18
DA14681 pro板与调试器工作良好,但在单独运行时停止

嗨,对话框,
我构建了一个基于px reporter的应用程序,添加了一个定时器,连接到中心设备时通过适配器从I2C总线读取数据。
最奇怪的是,它在jlink jtag模式下工作得很好,但在连接后就停止了,当单独工作时发送几个数据包的数据。我使用附加函数,发现它在hw_hard_fault.c循环中结束。
原因是什么?
非常感谢。
问候。

设备:
IM_Dialog
离线
最后看到:3个月6天前
加入:2016-12-06 22:25
嗨段,

嗨段,

硬故障处理程序(函数文件hw_hard_fault.c)中的HardFault_HandlerC将堆栈帧复制到内存中的固定位置。此堆栈框架包含许多参数,这些参数将帮助您找到硬故障的来源。第一个开始是PC -这是在硬故障发生时的程序计数器的值,即它将指向正在执行的指令,并导致硬故障。您可以使用调试器访问PC的值。当你在硬件故障处理程序中找到执行while(1)循环的代码后,检查内存位置STATUS_BASE + 0x18 -这将包含PC的值。STATUS_BASE的值在hw_hard_fault.c文件中。一旦你有了PC,你可以找出是哪条指令(因此是哪行C代码)造成的硬故障。

IM_Dialog

Neil.duan
离线
最后看到:6天4小时前
加入:2016-05-24 09:18
谢谢你的帮助。

谢谢你的帮助。按照您的说明,我发现pc的硬件故障原因是0x7fd11e0。
弄清楚发生了什么有帮助吗?

Neil.duan
离线
最后看到:6天4小时前
加入:2016-05-24 09:18
嗨,对话框,

嗨,对话框,
这个周末我做了一系列测试
1.简化我的代码只包括一个init函数,以初始化gpio和I2C异步事务,一个读函数,读取寄存器从IMU,并打印到uart。

2.移动我的驱动代码到一个“干净的”ble_peripheral项目,在任务开始时添加init,在ble_peripheral_task中添加一个定时器并在for(;;)循环之前启动它,当任务收到定时器通知时从I2C读取数据。

空白ble_peripheral_task (void * params)

int8_t wdog_id;
ble_service_t * svc;
OS_TASK handle = NULL;
my_peripheral_init ();

...
sns_timer = OS_TIMER_CREATE("sns", portCONVERT_MS_2_TICKS(100), OS_TIMER_SUCCESS,
OS_GET_CURRENT_TASK(), sns_timer_cb); / /执行命令
OS_ASSERT (sns_timer);
OS_TIMER_START (sns_timer OS_TIMER_FOREVER);
...
if (notif & SNS_TIMER_NOTIF) {
refresh_sensor();

...
但几秒钟后,uart打印停止了。当连接时,我发现该程序运行在sys_power_mgr.c的第2132行:
//暂停任何正在进行的QSPI程序/擦除操作。
if (op != NULL) {//2132
DBG_SET_HIGH (FLASH_DEBUG FLASHDBG_SUSPEND);

如果(qspi_check_and_suspend ()) {
op - > = true暂停;

DBG_SET_LOW (FLASH_DEBUG FLASHDBG_SUSPEND);

3.我尝试了另一种方法,在ble services启动后,在for(;;)之前删除sns_timer和一个无限循环:
而(1){
refresh_sensor();
OS_DELAY (50);

就像之前一样,几秒钟后,uart打印停止了。当连接时,我发现程序运行在sys_power_mgr.c的第1513行:
/ *
*睡眠
*/
__WFI ();

/*确保代码将以尽可能快的速度执行。*/
If (!allow_entering_sleep){//修改
hw_cpm_set_hclk_div(ahb_div1);

4.我创建了一个新任务,比ble_peripheral_task优先级低。除了while循环什么也不做:
而(1){
refresh_sensor();
OS_DELAY (50);

得到和3相同的结果。
所有的测试2,3,4我尝试pm_stay_alive()函数,或不启用看门狗,但得到相同的结果。

5.在最后一个测试中,我将while循环放在init的下一行,在所有ble服务启动之前。这次的I2C数据读得很好!

空白ble_peripheral_task (void * params)

int8_t wdog_id;

ble_service_t * svc;
OS_TASK handle = NULL;
my_peripheral_init ();
而(1){
refresh_sensor();
OS_DELAY (50);

.....

它似乎读取I2C经常无法与BLE堆叠共存。什么是问题?

请转发你的回复。
谢谢你!

IM_Dialog
离线
最后看到:3个月6天前
加入:2016-12-06 22:25
你应该能读懂

您应该能够通过I2C读取设备,并且仍然可以执行BLE操作。你能发布你正在使用的代码来初始化I2C接口和读取传感器吗?

Neil.duan
离线
最后看到:6天4小时前
加入:2016-05-24 09:18
嗨IM_Dialog,

嗨IM_Dialog,
谢谢你的回复。以下是初始化代码:
bool i2c_devices_async_init(空白)

bool ret1 ret2;
静态const i2c_config cfg = {
。speed = HW_I2C_SPEED_STANDARD,
.mode = HW_I2C_MODE_MASTER,
.addr_mode = HW_I2C_ADDRESSING_7B,
};

hw_i2c_init (HW_I2C1 cfg);
将srand (OS_GET_TICK_COUNT ());

/ *
*将手柄置于温度传感器装置上。
*此调用尚未配置I2C控制器。
*/
// tpdev = ad_i2c_open(TP_MMS427);
imudev = ad_i2c_open (IMU_LSM6DS3);
// magdev = ad_i2c_open(mag_ak09915);
/ *
*创建GUI用来等待I2C事务完成的事件。
*此事件将用于从GUI任务访问温度传感器或EEPROM。
*/
init_event (&i2c_signal);

// ret1 = tp_device_init();

ret2 = imu_6axes_init ();
/* ret1 = ret1 && ret2;

ret2 = mag_device_init ();
Ret1 = Ret1 && re2;

/ /仅供测试
mag_set_power_mode (4);/ / 100 hz刷新
* /返回(ret2);

以及在timer notify中执行的刷新传感器代码:
静电void refresh_sensor(void)

int32_t imudata [6];
int16_t magdata [3];
uint8_t k1status tpirqstatus;
uint8_t xy [2];

/ / pm_stay_alive ();
k1status =(uint8_t)hw_gpio_get_pin_status(app_button_gpio_port,app_button_gpio_pin);
tpirqstatus = (uint8_t)hw_gpio_get_pin_status(TP_IRQ_GPIO_PORT, TP_IRQ_GPIO_PIN);

如果(imu_6axes_read_data (imudata)) {
printf (" IO: % d | % d Acc: % d % d % d”,k1status, tpirqstatus, (int) imudata [0], (int) imudata [1], (int) imudata [2]);

printf("陀螺:% d % d % d \ r \ n”,(int) imudata [3], (int) imudata [4], (int) imudata [5]);

/ * if(tp_drv_read_coorder(xy)){
printf("TP:%u,%u ", xy[0], xy[1]);


如果(mag_device_read (magdata)) {
printf("杂志:% d % d % d \ r \ n”,magdata [0], magdata [1], magdata [2]);

} * /
/ / pm_resume_sleep ();

函数imu_6axes_read_data使用imu_i2c_read函数从IMU中读取多个寄存器并计算值:

bool i2c_read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr)
uint16_t NumByteToRead)

Bool ret = false;

ad_i2c_device_acquire (imudev);

if(HW_I2C_ABORT_NONE != i2c_device_read_async(imudev, &RegisterAddr, pBuffer, 1, NumByteToRead, &i2c_signal))
goto退出;

ret = true;

退出:
ad_i2c_device_release (imudev);
返回受潮湿腐烂;

I2C读寄存器函数:与信号相关的函数与i2c_demo.c相同。

static HW_I2C_ABORT_SOURCE i2c_device_read_async(i2c_device dev, uint8_t* reg, const uint8_t* buf, uint8_t reglen,
Uint8_t buflen, i2c_event *event)

/ *
*确保事件尚未处于信号状态;
*/
reset_event(事件);

/ *
*写入传感器寄存器,使用回调将信号事件同步。
*/
ad_i2c_async_transact(dev, I2C_SND(reg, reglen), I2C_RCV(buf, buflen),
I2C_CB1 (signal_event、事件),I2C_END);
/ *
*等待事务完成。
*/
wait_for_event(事件);

/ *
*错误代码,如果任何存储在事件,返回它。
*/
返回事件- >错误;

我需要强调,在系统停止之前,我可以成功地初始化和读取IMU数据几十次。printf输出如下所示:

2017/1/11 10:08:05.658 [rx] -
IMU XG_ID:0x69
广告开始!
IO: 1 | 1 Acc: -38年,16岁,1043年,陀螺:1680,-10710,-7630
IO: 1 | 1 Acc: -38年,16岁,1041年,陀螺:1610,-10570,-7630
IO: 1 | 1 Acc: -38年,16岁,1041年,陀螺:1680,-10640,-7630
IO:1 | 1 ACC:-38,17,1040,陀螺仪:1750,-10640,-7560
IO: 1 | 1 Acc: -38年,16岁,1041年,陀螺:1680,-10640,-7630
IO: 1 | 1 Acc: -38年,16岁,1041年,陀螺:1680,-10640,-7630
...

问候,

IM_Dialog
离线
最后看到:3个月6天前
加入:2016-12-06 22:25
当使用I2C适配器时

当使用I2C适配器时,你需要配置你的设备和I2C总线,方法是将以下内容添加到一个名为platform_devices.h的文件中,放置在你的config文件夹中:

#如果dg_configI2C_ADAPTERI2C_BUS (I2C1)I2C_SLAVE_DEVICE(I2C1, DEVICE_A, 0x20, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);I2C_BUS_END# endif

当你想初始化端口时,你进行以下调用:

I2C_BUS_INIT (I2C1);I2C_DEVICE_INIT (DEVICE_A);

我不能看到这些调用在你的代码,所以我不确定你是否在使用这种机制,如果不是,那么我建议你改变你的代码相应。你可以在下面找到一个如何使用I2C适配器的示例:

DA1468x_SDK_BTLE_v_1.0.8.1050.1 \ dk_apps \ demo \ \项目peripherals_demo \ demo \ demo_i2c_async.c

Neil.duan
离线
最后看到:6天4小时前
加入:2016-05-24 09:18
谢谢你的回复。

谢谢你的回复。
我完全遵循演示demo_i2c_async.c。设备的声明是在配置文件中的platform_devices.h的副本中完成的,就像下面的演示一样:
I2C_BUS (I2C1)

# ifdef CONFIG_IMU_LSM6DS3
/*示例温度传感器FM75 */
I2C_SLAVE_DEVICE(I2C1, IMU_LSM6DS3, 0x6A, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);
# endif
# ifdef CONFIG_MAG_AK09915
/*示例温度传感器FM75 */
I2C_SLAVE_DEVICE(I2C1, MAG_AK09915, 0x0c, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);
# endif

但我不能找到任何初始化像I2C_BUS_INIT(I2C1);在演示。所以我在之前的代码中没有添加它们。

我在init中添加宏在hardware init和devices open之间:
hw_i2c_init (HW_I2C1 cfg);
将srand (OS_GET_TICK_COUNT ());
I2C_BUS_INIT (I2C1);

I2C_DEVICE_INIT (IMU_LSM6DS3);
I2C_DEVICE_INIT (MAG_AK09915);
/ *
*将手柄置于温度传感器装置上。
*此调用尚未配置I2C控制器。
*/
// tpdev = ad_i2c_open(TP_MMS427);
imudev = ad_i2c_open (IMU_LSM6DS3);
magdev = ad_i2c_open (MAG_AK09915);

但结果是一样的。接下来我应该尝试什么?谢谢你!

MT_dialog
离线
最后看到:4个月3天前
工作人员
加入:2015-06-08 34
嗨Neil.duan,

嗨Neil.duan,

你提到代码卡住的点,它没有卡住,(没有(1)或任何断言使您​​的代码卡住),代码仍然执行(可以检查您是否能够查看任何广告代码摊位的空气)。当您附加并且您在这些点处找到代码是因为代码经常或在__wfi()案例中浏览这些点,它只等待发生中断。您提到的硬盘是一种不同的原因,它不是一个BLE或适配器的原因,HardFaults发生在内存中未alalign的访问,对空指针函数,记忆损坏等的调用。我建议做的是检查FW通过系统查看器或臭氧调试器,检查任务和使用的适配器会发生什么,也可以轮询传感器并以较小的频率打印并检查系统是否无法打印。我们非常困难地假设代码可能出现问题,但由于您使用的适配器,SDK应该正确处理BLE事件和I2C交易。

由于MT_dialog

mahmed106
离线
最后看到:1周5天前
加入:2019-05-03所
我也有同样的困难

我也有同样的困难的错误问题。但这只发生在其中一块板上。我有两块黑板。另一个工作得很好。

I M还使用I2C适配器进行I2C传感器读取温度。这个问题的解决方案是什么,,,,?任何人都可以帮助我吗?

PM_Dialog
离线
最后看到:3天21小时前
工作人员
加入:2018-02-08 11:03
嗨mahmed106,