嗨,对话,我构建了一个基于PX记者的应用程序,在连接到中央设备时,添加一个计时器以通过适配器读取I2C总线的数据。最奇怪的是,它在JLink JTAG模式下运行良好,但是在连接后停止并单独工作时发送几包数据。我使用了附加功能,发现它以HW_HARD_FAULT.C的循环结束。什么原因是什么?非常感谢。问候。杜安
嗨,杜安,
硬故障管理员(功能文件HW_HARD_FAULT.C中的HardFault_handlerc将堆栈框架复制到内存中的固定位置。该堆栈框架包含许多参数,可以帮助您找到硬故障的来源。首先是第一个是PC-这是在发生硬故障时程序计数器的值,即,它将指向正在执行的指令并导致硬故障。您可以使用调试器访问PC的值。附加并找到执行的代码后,(1)在硬故障处理程序中检查内存位置status_base + 0x18-这将包含PC的值。status_base的值可以在hw_hard_fault.c文件中找到。一旦拥有PC,您就可以找出哪种指令(因此C代码的线路)会导致硬故障。
im_dialog
谢谢你的帮助。按照您的说明,我发现硬件故障原因的PC为0x7FD11E0。找出发生了什么事有帮助吗?
嗨,对话,这个周末我做了一系列测试:1.简化了我的代码仅包括一个初始化功能,即Init GPIO和I2C异步Transact,一个读取功能,从IMU读取寄存器,然后将其打印到UART。
2.将我的驱动程序代码移至“清洁” ble_peripheral项目,在任务开始时添加初始化,将计时器添加到ble_peripheral_task中,然后在(;;)循环之前启动它,然后在任务接收计时器通知时从i2c读取数据。
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(“ sns”,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(notif&sns_timer_notif){refresh_sensor();}...但是几秒钟后,UART打印停止了。当attch时,我发现该程序在sys_power_mgr.c的第2132行中运行://暂停任何正在进行的QSPI程序 /擦除操作。如果(op!= null){// 2132dbg_set_high(flash_debug,flashdbg_suspend);
if(qspi_check_and_suspend()){op->暂停= true;}
dbg_set_low(flash_debug,flashdbg_suspend);}}
3.我尝试了另一种方法,删除sns_timer,并在BLE服务开始后进行(;;)之前的无尽循环。而(1){refresh_sensor();OS_DELAY(50);}就像以前一样,几秒钟后,UART打印停止了。当attch时,我发现该程序在sys_power_mgr.c的LINE1513上运行:/** 睡觉*/__wfi();
/*确保代码将以最快的速度执行。*/if(!allow_entering_sleep){// 1513hw_cpm_set_hclk_div(ahb_div1);}4.我创建了一个新任务,比ble_peripheral_task更低。除了时循环外,什么都不做:而(1){refresh_sensor();OS_DELAY(50);}我得到的结果与3相同。所有2,3,4的测试我都尝试了PM_STAY_ALIVE()函数,或者不启用看门狗,但得到了相同的结果。
5.最后一个测试,我将WARE循环放在INIT的下一行,然后在所有BLE SEVICES开始之前。这次I2C数据读得很好!
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);}..... .....
似乎阅读I2C经常无法与BLE堆栈共存。有什么问题?
向前循环回答。谢谢你。
您应该能够通过I2C读取设备并仍执行BLE操作。您可以发布您使用的代码以初始化I2C接口并读取传感器吗?
嗨,im_dialog,谢谢你,请重播。这是初始代码:bool i2c_devices_async_init(void){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 && ret2;
//仅进行测试mag_set_power_mode(4);// 100Hz刷新*/返回(ret2);}以及刷新传感器代码,该代码在计时器中有所通知:静态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_coortion(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_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);返回ret;}I2C读取寄存器函数:信号相关的函数与I2C_DEMO.C中的函数相同。
静态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 *事件){/**确保事件尚未处于信号状态;*/reset_event(event);
/**编写传感器寄存器,使用会发出信号事件的回调进行同步。*/ad_i2c_async_transact(dev,i2c_snd(reg,reglen),i2c_rcv(buf,buflen),i2c_cb1(signal_event,event),i2c_end);/**等待交易完成。*/wait_for_event(event);
/**错误代码如果在事件中存储,请返回。*/返回事件 - >错误;
我需要强调,在系统停止之前,我可以成功启动和阅读数十个次数的IMU数据。这样的printf输出:
2017/1/11 10:08:05.658 [RX] -IMU XG_ID:0x69广告开始了!IO:1 | 1 ACC:-38,16,1043,Gyro:1680,-10710,-7630IO:1 | 1 ACC:-38,16,1041,Gyro:1610,-10570,-7630IO:1 | 1 ACC:-38,16,1041,Gyro:1680,-10640,-7630IO:1 | 1 ACC:-38,17,1040,Gyro:1750,-10640,-7560IO:1 | 1 ACC:-38,16,1041,Gyro:1680,-10640,-7630IO:1 | 1 ACC:-38,16,1041,Gyro:1680,-10640,-7630...
问候,杜安
使用I2C适配器时,您需要通过将类似以下内容添加到“ platform_devices.h”文件中,以配置您的设备和I2C总线。
#如果dg_configi2c_adapteri2c_bus(i2c1)i2c_slave_device(i2c1,device_a,0x20,hw_i2c_addressing_7b,hw_i2c_speed_standard);i2c_bus_end#万一
然后,当您想初始化端口时,您会拨打以下电话:
i2c_bus_init(i2c1);i2c_device_init(device_a);
我在您的代码中看不到这些电话,因此我不确定您是否正在使用此机制,如果没有,我建议您相应地更改代码。您可以在以下内容中找到如何使用I2C适配器的一个很好的例子:
da1468x_sdk_btle_v_1.0.8.1050.1 \ projects \ dk_apps \ demos \ demos \ peripherals_demo \ demos \ demos \ demo_i2c_async.c.c
谢谢您的重播。我完全遵循了演示demo_i2c_async.c。设备声明是在platform_devices.h of config foler中的副本中进行的,例如演示: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);#万一
但是我找不到任何初始化,例如i2c_bus_init(i2c1);在演示中。因此,我没有在以前的代码中添加它们。
我在硬件初始化和设备打开之间添加了宏: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);
但是得到相同的结果。接下来我应该尝试什么?谢谢!
嗨,尼尔。
您提到您的代码卡住,不卡住的观点(没有一段时间(1)或任何使您的代码卡住的断言),代码仍然执行(您可以检查是否可以在上面查看任何广告代码失速时空气)。当您附加并在这些点找到代码时,是因为代码更频繁地或在__wfi()案例中遍历这些点,只是等待中断。您提到的硬故障是一个不同的原因,它不是ble或适配器的原因,硬故障要么是由于记忆中未对准的访问,调用null指针功能,内存损坏等。我建议要做的是检查FW。使用系统查看器或Ozone调试器,以便检查任务和所使用的适配器会发生什么,您也可以以较小的频率进行轮询并打印,并检查系统是否未打印。对于我们来说,很难假设代码可能出了什么问题,但是由于您使用的适配器,SDK应该正确处理BLE事件和I2C交易。
谢谢mt_dialog
我也有同样的硬故障问题。但这只会在其中一个董事会上进行。我总共有2个董事会。其他工作正常。
我还使用I2C适配器从I2C传感器读取温度。该问题的解决方案是什么?谁能在这方面帮助我?
嗨,Mahmed106,
谢谢你的评论。我已经在以下论坛线程中回答了您:
https://support.dialog-spoomendonductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-energy-energy-py-%80%93-software/da14681-hardfault-hardfault-when-when-when-reading-ireding-i2c
谢谢,pm_dialog
嗨,杜安,
硬故障管理员(功能文件HW_HARD_FAULT.C中的HardFault_handlerc将堆栈框架复制到内存中的固定位置。该堆栈框架包含许多参数,可以帮助您找到硬故障的来源。首先是第一个是PC-这是在发生硬故障时程序计数器的值,即,它将指向正在执行的指令并导致硬故障。您可以使用调试器访问PC的值。附加并找到执行的代码后,(1)在硬故障处理程序中检查内存位置status_base + 0x18-这将包含PC的值。status_base的值可以在hw_hard_fault.c文件中找到。一旦拥有PC,您就可以找出哪种指令(因此C代码的线路)会导致硬故障。
im_dialog
谢谢你的帮助。按照您的说明,我发现硬件故障原因的PC为0x7FD11E0。
找出发生了什么事有帮助吗?
嗨,对话,
这个周末我做了一系列测试:
1.简化了我的代码仅包括一个初始化功能,即Init GPIO和I2C异步Transact,一个读取功能,从IMU读取寄存器,然后将其打印到UART。
2.将我的驱动程序代码移至“清洁” ble_peripheral项目,在任务开始时添加初始化,将计时器添加到ble_peripheral_task中,然后在(;;)循环之前启动它,然后在任务接收计时器通知时从i2c读取数据。
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(“ sns”,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(notif&sns_timer_notif){
refresh_sensor();
}
...
但是几秒钟后,UART打印停止了。当attch时,我发现该程序在sys_power_mgr.c的第2132行中运行:
//暂停任何正在进行的QSPI程序 /擦除操作。
如果(op!= null){// 2132
dbg_set_high(flash_debug,flashdbg_suspend);
if(qspi_check_and_suspend()){
op->暂停= true;
}
dbg_set_low(flash_debug,flashdbg_suspend);
}
}
3.我尝试了另一种方法,删除sns_timer,并在BLE服务开始后进行(;;)之前的无尽循环。
而(1){
refresh_sensor();
OS_DELAY(50);
}
就像以前一样,几秒钟后,UART打印停止了。当attch时,我发现该程序在sys_power_mgr.c的LINE1513上运行:
/*
* 睡觉
*/
__wfi();
/*确保代码将以最快的速度执行。*/
if(!allow_entering_sleep){// 1513
hw_cpm_set_hclk_div(ahb_div1);
}
4.我创建了一个新任务,比ble_peripheral_task更低。除了时循环外,什么都不做:
而(1){
refresh_sensor();
OS_DELAY(50);
}
我得到的结果与3相同。
所有2,3,4的测试我都尝试了PM_STAY_ALIVE()函数,或者不启用看门狗,但得到了相同的结果。
5.最后一个测试,我将WARE循环放在INIT的下一行,然后在所有BLE SEVICES开始之前。这次I2C数据读得很好!
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);
}
..... .....
似乎阅读I2C经常无法与BLE堆栈共存。有什么问题?
向前循环回答。
谢谢你。
您应该能够通过I2C读取设备并仍执行BLE操作。您可以发布您使用的代码以初始化I2C接口并读取传感器吗?
嗨,im_dialog,
谢谢你,请重播。这是初始代码:
bool i2c_devices_async_init(void)
{
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 && ret2;
//仅进行测试
mag_set_power_mode(4);// 100Hz刷新
*/返回(ret2);
}
以及刷新传感器代码,该代码在计时器中有所通知:
静态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_coortion(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_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);
返回ret;
}
I2C读取寄存器函数:信号相关的函数与I2C_DEMO.C中的函数相同。
静态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 *事件)
{
/*
*确保事件尚未处于信号状态;
*/
reset_event(event);
/*
*编写传感器寄存器,使用会发出信号事件的回调进行同步。
*/
ad_i2c_async_transact(dev,i2c_snd(reg,reglen),i2c_rcv(buf,buflen),
i2c_cb1(signal_event,event),i2c_end);
/*
*等待交易完成。
*/
wait_for_event(event);
/*
*错误代码如果在事件中存储,请返回。
*/
返回事件 - >错误;
}
我需要强调,在系统停止之前,我可以成功启动和阅读数十个次数的IMU数据。这样的printf输出:
2017/1/11 10:08:05.658 [RX] -
IMU XG_ID:0x69
广告开始了!
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,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
...
问候,
杜安
使用I2C适配器时,您需要通过将类似以下内容添加到“ platform_devices.h”文件中,以配置您的设备和I2C总线。
然后,当您想初始化端口时,您会拨打以下电话:
我在您的代码中看不到这些电话,因此我不确定您是否正在使用此机制,如果没有,我建议您相应地更改代码。您可以在以下内容中找到如何使用I2C适配器的一个很好的例子:
da1468x_sdk_btle_v_1.0.8.1050.1 \ projects \ dk_apps \ demos \ demos \ peripherals_demo \ demos \ demos \ demo_i2c_async.c.c
谢谢您的重播。
我完全遵循了演示demo_i2c_async.c。设备声明是在platform_devices.h of config foler中的副本中进行的,例如演示:
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);
#万一
但是我找不到任何初始化,例如i2c_bus_init(i2c1);在演示中。因此,我没有在以前的代码中添加它们。
我在硬件初始化和设备打开之间添加了宏:
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);
但是得到相同的结果。接下来我应该尝试什么?谢谢!
嗨,尼尔。
您提到您的代码卡住,不卡住的观点(没有一段时间(1)或任何使您的代码卡住的断言),代码仍然执行(您可以检查是否可以在上面查看任何广告代码失速时空气)。当您附加并在这些点找到代码时,是因为代码更频繁地或在__wfi()案例中遍历这些点,只是等待中断。您提到的硬故障是一个不同的原因,它不是ble或适配器的原因,硬故障要么是由于记忆中未对准的访问,调用null指针功能,内存损坏等。我建议要做的是检查FW。使用系统查看器或Ozone调试器,以便检查任务和所使用的适配器会发生什么,您也可以以较小的频率进行轮询并打印,并检查系统是否未打印。对于我们来说,很难假设代码可能出了什么问题,但是由于您使用的适配器,SDK应该正确处理BLE事件和I2C交易。
谢谢mt_dialog
我也有同样的硬故障问题。但这只会在其中一个董事会上进行。我总共有2个董事会。其他工作正常。
我还使用I2C适配器从I2C传感器读取温度。该问题的解决方案是什么?谁能在这方面帮助我?
嗨,Mahmed106,
谢谢你的评论。我已经在以下论坛线程中回答了您:
https://support.dialog-spoomendonductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-energy-energy-py-%80%93-software/da14681-hardfault-hardfault-when-when-when-reading-ireding-i2c
谢谢,pm_dialog