Hi, Dialog,
I build a app based on px reporter, add a timer to read data from I2C bus through adapter when connected to a central device.
the most strange thing was, it worked well when in jlink jtag mode, but halted after connected and send several packets of data when work alone. I used attach function and found it ended in the loop of hw_hard_fault.c.
What would be the reason?
非常感谢。
Regards.
段
设备:
Hi Duan,
The hard fault hander (the functionhw_hard_fault.c中的hardfault_handlerc)将堆栈帧复制到内存中的固定位置。此堆栈框包含许多参数,可以帮助您找到硬故障的源。首先要开始的PC - 这是在发生硬故障发生时程序计数器的值I.E。它将指向正在执行的指令,导致硬故障。您可以使用调试器访问PC的值。附加并在硬盘处理程序中查找执行的代码(1)循环检查内存位置状态_base + 0x18 - 这将包含PC的值。status_base的值可以在hw_hard_fault.c文件中找到。一旦您有PC,您可以了解哪些指令(因此C代码的WHCH线)导致硬故障。
IM_Dialog
Thank you for you help. Follow your instructions, I found the pc of the hardware fault cause was 0x7fd11e0 .
找出发生的事情是有助于的吗?
Hi, Dialog,
我本周末做了一系列测试:
1.简化了我的代码仅包括一个init函数,到init gpio和i2c异步交易,一个读取功能,从imu读取寄存器,并将其打印到UART。
2.将我的驱动程序代码移动到“Clean”BLE_PLE_PERITELAL项目,在任务开始时添加init,将计时器添加到ble_peripheral_task,然后在for for(;;)循环之前启动它,并且当任务接收计时器通知时,从i2c读取数据。
void 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”,PORTCONVERD_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 (notif & SNS_TIMER_NOTIF) {
refresh_sensor();
}
......
but after several seconds, the uart print stopped. when ATTCH, I found the program ran at line 2132 of sys_power_mgr.c:
// Suspend any ongoing QSPI program / erase operations.
if(op!= null){// 2132
dbg_set_high(flash_debug,flashdbg_suspend);
if (qspi_check_and_suspend()) {
op->suspended = true;
}
DBG_SET_LOW(FLASH_DEBUG, FLASHDBG_SUSPEND);
}
}
3. And I tried another way, delete the sns_timer, and a endless loop before for(;;), after ble services started.:
while(1){
refresh_sensor();
OS_DELAY(50);
}
就像之前一样,几秒钟后,UART打印停止了。当Attch时,我发现该程序在Sys_Power_Mgr.c的Line1513中运行:
/*
* 睡觉
*/
__WFI();
/* Make sure that the code will be executed at the fastest possible speed. */
if (!allow_entering_sleep) { //1513
hw_cpm_set_hclk_div(ahb_div1);
}
4. I created a new task, lower priority than ble_peripheral_task. do nothing but the while loop:
while(1){
refresh_sensor();
OS_DELAY(50);
}
我得到了与3的结果相同。
all tests of 2,3,4 I tried pm_stay_alive() function, or don't enable watchdog, but got the same result.
5.最后一次测试,我在下一行初始循环时,在所有BLE SEVICE开始之前。这次I2C数据读得很好!
void ble_peripheral_task(void *params)
{
Int8_t wdog_id;
ble_service_t *svc;
OS_TASK handle = NULL;
my_peripheral_init();
while(1){
refresh_sensor();
OS_DELAY(50);
}
.....
It seems reading I2C frequently cannot coexist with ble stack. What would be the problem?
为您的回复循环。
谢谢你。
You should be able to read a device via I2C and still perform BLE operations. Can you post the code you are using to both initialize the I2C interface and read the sensor.
Hi IM_Dialog,
Thank you vour kindly replay. Here's the init code:
bool i2c_devices_async_init(void)
{
bool ret1, ret2;
static const i2c_config cfg = {
.speed = hw_i2c_speed_standard,
.mode = HW_I2C_MODE_MASTER,
.ddr_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);
/*
*Create event that will be used by GUI to wait for I2C transactions to finish.
*This event will be used for access temperature sensor or EEPROM from GUI task.
*/
init_event(&i2c_signal);
// ret1 = tp_device_init();
ret2 = imu_6axes_init();
/* ret1 = ret1 && ret2;
ret2 = mag_device_init();
ret1 = ret1 && ret2;
//仅进行测试
mag_set_power_mode(4);// 100Hz刷新
*/ return (ret2);
}
和刷新传感器代码,在计时器中突出的折断通知:
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();
}
the function imu_6axes_read_data use imu_i2c_read function read several registers from IMU and calculate values:
bool imu_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))
转到退出;
ret = true;
exit:
ad_i2c_device_release(imudev);
return ret;
}
the I2C read registers function: the signal related funtions are the same as in 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(event);
/*
*Writing sensor register, use callback that will signal event for synchronization.
*/
ad_i2c_async_transact(dev, I2C_SND(reg, reglen), I2C_RCV(buf, buflen),
I2C_CB1(signal_event, event), I2C_END);
/*
*Wait for transaction to complete.
*/
wait_for_event(事件);
/*
*错误代码如果在事件中存储,则返回它。
*/
return event->error;
}
我需要强调,在系统停止之前,我可以成功识别并读取数十次的IMU数据。printf输出如下:
2017/1/11 10:08:05.658 [RX] -
IMU XG_ID: 0x69
Advertise started!
IO:1|1 Acc:-38,16,1043, Gyro:1680,-10710,-7630
IO:1|1 Acc:-38,16,1041, Gyro:1610,-10570,-7630
IO:1 | 1 ACC:-38,16,1041,陀螺仪:1680,-10640,-7630
IO:1|1 Acc:-38,17,1040, Gyro:1750,-10640,-7560
IO:1 | 1 ACC:-38,16,1041,陀螺仪:1680,-10640,-7630
IO:1 | 1 ACC:-38,16,1041,陀螺仪:1680,-10640,-7630
......
Regards,
段
When using the I2C adapter you need to configure your devices and the I2C bus by adding something like the following to a file called platform_devices.h that you place in your config folder:
当您希望初始化您进行以下呼叫的端口时:
我无法在代码中看到这些呼叫,所以我不确定您是否使用此机制,如果不是,那么我建议您相应地更改代码。您可以在以下内容中找到如何使用I2C适配器的一个很好的示例:
da1468x._SDK_BTLE_v_1.0.8.1050.1\projects\dk_apps\demos\peripherals_demo\demos\demo_i2c_async.c
谢谢你的重播。
我完全遵循演示演示_i2c_async.c。设备的声明是在platform_devices.h的副本中进行的,如demo,如demo:
I2C_BUS(I2C1)
#ifdef config_imu_lsm6ds3.
/* Example temperature sensor FM75 */
i2c_slave_device(i2c1,imu_lsm6ds3,0x6a,hw_i2c_addressing_7b,hw_i2c_speed_standard);
#endif
#如果def CONFIG_MAG_AK09915
/* Example temperature sensor FM75 */
I2C_SLAVE_DEVICE(I2C1, MAG_AK09915, 0x0c, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD);
#endif
但我找不到任何初始化,如i2c_bus_init(i2c1);在演示中。所以我没有在以前的代码中添加它们。
And I add the macro in init between hardware init and 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);
But get the same result. What should I try next? Thank you!
Hi Neil.duan,
困,你提到你的代码,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.
谢谢mt_dialog.
我也有同样的硬故障问题。但它is only happeneing on one of the boards. I have total of 2 boards. Other is working perfectly fine.
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?
嗨mahmed106,
谢谢你的评论。在以下论坛主题下,我已经回复了您:
https://support.dialog-semicondiondiondiondum/forums/post/dialog-smartbond-bluetooth-low-energy-%2%80%93-software/da14681-hardfault-when-reading-i2c.
谢谢,PM_DIALOG.