DA14681 pro board works well with debugger, but halted when run alone

11 posts / 0 new
Last post
Neil.duan
离线
Last seen:6天17小时前
加入:2016-05-24 09:18
DA14681 pro board works well with debugger, but halted when run alone

Hi, Dialog,
我构建基于PX Reporter的应用程序,在连接到中央设备时,添加一个定时器以通过适配器从I2C总线读取数据。
最奇怪的是,它在jlink JTAG模式下工作很好,但在连接后停止并单独工作时发送多个数据数据包。我使用附加功能,发现它在HW_HARD_FAULT.C的循环中结束。
是什么原因?
Thanks a lot.
Regards.
Duan

Attachment:
Device:
im_dialog.
离线
Last seen:4周1日前
加入:2016-12-06 22:25
Hi Duan,

Hi Duan,

硬故障处理程序(功能HardFault_HandlerC in the file hw_hard_fault.c) copies the stack frame to a fixed location in memory. This stack frame contains a number of parameters that will help you find the source of the hard fault. The first one to start with is the PC - this is the value of the program counter at the time the hard fault occured i.e. it will point to the instruction that was being executed and that caused the hard fault. You can access the value of the PC using the debugger. After you have attached and find the code executing the while(1) loop in the hardfault handler examine memory location STATUS_BASE + 0x18 - this will contain the value of the PC. The value of STATUS_BASE can be found in the hw_hard_fault.c file. Once you have the PC you can find out which instruction (and therefore whch line of C code) is causing the hard fault.

im_dialog.

Neil.duan
离线
Last seen:6天17小时前
加入:2016-05-24 09:18
谢谢你的帮助。

谢谢你的帮助。按照您的说明,我发现硬件故障原因的PC为0x7fd11e0。
Is it helpful to find out what happened?

Neil.duan
离线
Last seen:6天17小时前
加入:2016-05-24 09:18
Hi, Dialog,

Hi, Dialog,
I did a series of tests this weekend:
1. simplified my code only included one init function, to init gpio and I2C async transact, one read function, read registers from IMU, and print it to uart.

2. move my driver code to a "clean" ble_peripheral project, add init at beginning of task start, add a timer to ble_peripheral_task and start it before for(;;) loop, and read data from I2C when task receive timer notify.

void ble_peripheral_task(void * params)
{
int8_t wdog_id;
ble_service_t * svc;
OS_TASK句柄= null;
my_peripheral_init();

...
sns_timer = OS_TIMER_CREATE(“社交”,portCONVERT_MS_2_TICKS(100), OS_TIMER_SUCCESS,
(void *)os_get_current_task(),sns_timer_cb);
OS_ASSERT(sns_timer);
os_timer_start(sns_timer,os_timer_forever);
...
if(notf&sns_timer_notif){
refresh_sensor();
}
...
但几秒钟后,UART打印停止了。当Attch时,我发现该程序在Sys_Power_Mgr.c的第2132行运行:
//暂停任何正在进行的QSPI程序/擦除操作。
if (op != NULL) { //2132
DBG_SET_HIGH(FLASH_DEBUG, FLASHDBG_SUSPEND);

if(qspi_check_and_suspend()){
OP->暂停=真;
}

dbg_set_low(flash_debug,flashdbg_suspend);
}
}

3.我尝试了另一种方式,删除了SNS_Timer,然后删除了(;;)之前的无限循环,在BLE服务开始之后:
而(1){
refresh_sensor();
os_delay(50);
}
just like before, after several seconds, the uart print stopped. When ATTCH, I found the program ran at line1513 of sys_power_mgr.c:
/*
* Sleep
* /
__WFI();

/ *确保代码将以最快的速度执行。* /
如果(!allow_entering_sleep){// 1513
hw_cpm_set_hclk_div(ahb_div1);
}
4.我创建了一个新的任务,比ble_peripheral_task更低的优先级。除了循环中什么也不做:
而(1){
refresh_sensor();
os_delay(50);
}
I get the same result as 3.
所有测试的2,3,4我尝试了pm_stay_alive()函数,或者不要启用看门狗,但同样的结果。

5. The last test, I put the while loop at the next line of init, before all ble sevices started. this time the I2C data read VERY WELL!

void ble_peripheral_task(void * params)
{
int8_t wdog_id;

ble_service_t * svc;
OS_TASK句柄= null;
my_peripheral_init();
而(1){
refresh_sensor();
os_delay(50);
}
.....

It seems reading I2C frequently cannot coexist with ble stack. What would be the problem?

Loop forward for your reply.
Thank you.

im_dialog.
离线
Last seen:4周1日前
加入:2016-12-06 22:25
你应该能够阅读一个

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

Neil.duan
离线
Last seen:6天17小时前
加入:2016-05-24 09:18
嗨im_dialog,

嗨im_dialog,
谢谢你尊敬地重播。这是init代码:
bool i2c_devices_async_init(void)
{
BOOL RET1,RET2;
static 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());

/*
* Get handle to temperature sensor device.
* This call does not configure I2C controller yet.
* /
// 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 && Ret2;

//for test only
mag_set_power_mode(4); //100hz refresh
* /返回(RET2);
}
And the refresh sensor code, which excute in timer notify :
static 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);

if(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("Gyro:%d,%d,%d\r\n", (int)imudata[3], (int)imudata[4], (int)imudata[5]);
}
/* if (tp_drv_read_coordinate(xy)) {
printf(“tp:%u,%u”,xy [0],xy [1]);

}
if(mag_device_read(magdata)){
printf("mag:%d,%d,%d\r\n", magdata[0], magdata[1], magdata[2]);

}*/
// pm_resume_sleep();

}

函数IMU_6AXES_READ_DATA使用IMU_I2C_READ函数从IMU读取多个寄存器并计算值:

BOOL IMU_I2C_READ(UINT8_T * PBUFFER,UINT8_T DEVICEADDR,UINT8_TREGRARADDR,
uint16_t numbytetoread)
{
bool ret = false;

ad_i2c_device_acquire(imudev);

if(hw_i2c_abort_none!= = i2c_device_read_async(imudev,&regreadAddr,pbuffer,1,numbytetoread,&i2c_signal))
goto exit;

ret = true;

出口:
ad_i2c_device_release(imudev);
返回Ret;
}
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 *事件)
{
/*
* Make sure event is not in signal state yet;
* /
reset_event(事件);

/*
*编写传感器寄存器,使用回调将信号发生同步。
* /
AD_I2C_ASYNC_TRANSACT(DEV,I2C_SND(REG,REGLEN),I2C_RCV(BUF,BUFLEN),
i2c_cb1(signal_event,事件),i2c_end);
/*
*等待交易完成。
* /
wait_for_event(event);

/*
* Error code if any is stored in event, return it.
* /
返回Event->错误;

}

I need to emphasize that I can successfully init and read the IMU data for dozens of times before the system halt. the printf output like this:

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, Gyro:1680,-10640,-7630
IO:1|1 Acc:-38,17,1040, Gyro:1750,-10640,-7560
IO:1|1 Acc:-38,16,1041, Gyro:1680,-10640,-7630
IO:1|1 Acc:-38,16,1041, Gyro:1680,-10640,-7630
...

Regards,
Duan

im_dialog.
离线
Last seen:4周1日前
加入:2016-12-06 22:25
使用I2C适配器时

使用I2C适配器时需要通过将以下内容添加到名为platform_devices.h的文件来配置您的设备和I2C总线。

#ifdg_configi2c_adapterI2C_BUS(I2C1)I2C_SLAVE_DEVICE(I2C1, DEVICE_A, 0x20, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);I2C_BUS_END#万一

When you then want to initialize the port you make the following calls:

i2c_bus_init(i2c1);i2c_device_init(device_a);

I can't see these calls in your code so i'm not sure if you are using this mechanism, if not then i suggest you change your code accordingly. You can find a good example of how to use the I2C adapter in the following:

da1468x_sdk_btle_v_1.0.8.1050.1 \ projects \ dk_apps \ demos \ peripherals_demo \ demos \ demo_i2c_async.c

Neil.duan
离线
Last seen:6天17小时前
加入:2016-05-24 09:18
Thank you for your replay.

Thank you for your replay.
I followed the demo demo_i2c_async.c exactly. the declare of devices were made in a copy of platform_devices.h in config foler like the demo:
I2C_BUS(I2C1)

#ifdef CONFIG_IMU_LSM6DS3
/ *实施例温度传感器FM75 * /
I2C_SLAVE_DEVICE(I2C1, IMU_LSM6DS3, 0x6A, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);
#万一
#ifdef config_mag_ak09915.
/ *实施例温度传感器FM75 * /
i2c_slave_device(i2c1,mag_ak09915,0x0c,hw_i2c_addressing_7b,hw_i2c_speed_standard);
#万一

but I can't find any initialize like I2C_BUS_INIT(I2C1); in the demo. So I didn't add them in previous code.

我在硬件init和设备打开之间将宏添加宏:
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);
/*
* Get handle to temperature sensor device.
* This call does not configure I2C controller yet.
* /
// tpdev = ad_i2c_open(TP_MMS427);
imudev = ad_i2c_open(imu_lsm6ds3);
magdev = ad_i2c_open(MAG_AK09915);

但同样的结果。我应该接下来怎么样?谢谢!

MT_dialog
离线
Last seen:1 month 3 weeks ago
Staff
加入:2015-06-08 11:34
嗨Neil.伙伴,

嗨Neil.伙伴,

困,你提到你的代码,its not stuck, (there is no while(1) or any assertion to make your code stuck), the code still executes (can you please check if you are able to see any advertising on air when the code stalls). When you attach and you find the code at those points is because the code goes through those points more often or in the __WFI() case it just waits for an interrupt to occur. The hardfault that you mentioned is a different reason and its not a BLE or adapter reason, hardfaults occur either from a misaligned access in memory, invokation of null pointer function, memory corruption etc. What i would suggest to do is to check the fw either with the System Viewer or the Ozone debugger in order check what happens with the task and the adapters used, also you could poll the sensors and print in a smaller frequency and check if the system fails to print. Its quite difficult for us to assume what might go wrong with the code but since you are using the adapters the SDK should handle BLE events and the I2C transaction properly.

Thanks MT_dialog

mahmed106
离线
Last seen:1 month 1 week ago
加入:2019-05-03 17:28
我也有同样的努力

我也有相同的硬故障问题。但它只是在其中一个板上发生的。我总共有2个董事会。其他工作完全正常。

I m also using I2C adapter for reading temperature from i2C sensor. What is the solution of this problem,,,, ? Can anyone help me in this regard?

PM_Dialog
离线
Last seen:4 hours 50 min ago
Staff
加入:2018-02-08 11:03
Hi mahmed106,

Hi mahmed106,

Thanks for your comment. I have already replied you in this following forum thread:

https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-%E2%80%93-software/da14681-hardfault-when-reading-i2c

Thanks, PM_Dialog