硬故障处理程序(函数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.
嗨,对话框, 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.
3.我尝试了另一种方法,删除snsè计时器,在(;),启动ble服务后: 而(1){ refresh_sensor(); 操作系统延迟(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 */ __注射用水();
/*确保以尽可能快的速度执行代码*/ 如果(!允许进入睡眠{//1513 hw_cpm_set_hclk_div(ahb_div1); } 4.我创建了一个新任务,优先级比ble\u任务低。只执行while循环: 而(1){ refresh_sensor(); 操作系统延迟(50); } I get the same result as 3. 2,3,4的所有测试我都尝试了pm\u stay\u alive()函数,或者不启用watchdog,但是得到了相同的结果。
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!
static HW_I2C_ABORT_SOURCE i2c_device_read_async(i2c_device dev, uint8_t* reg, const uint8_t *buf, uint8_t reglen, uint8\u t buflen,i2c\u event*事件) { / * * Make sure event is not in signal state yet; */ 重置事件(event);
When you then want to initialize the port you make the following calls:
I2C总线初始化(I2C1);I2C\设备\初始化(设备\ 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:
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配置\u MAG \u AK09915 /*温度传感器FM75示例*/ I2C\从设备(I2C1、MAG\ U AK09915、0x0c、HW\ U I2C\ U寻址\U 7B、HW\ U I2C\ U速度\U标准); #结束
but I can't find any initialize like I2C_BUS_INIT(I2C1); in the demo. So I didn't add them in previous code.
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);
嗨段,
硬故障处理程序(函数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.
即时消息对话框
谢谢你的帮助。按照您的说明,我发现pc的硬件故障原因是0x7fd11e0。
Is it helpful to find out what happened?
嗨,对话框,
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\u peripheral\u任务(void*params)
{
int8_t wdog_id;
ble\ U service\ t*svc公司;
OS\u TASK handle=NULL;
my_peripheral_init();
...
sns_timer = OS_TIMER_CREATE(“社交”,portCONVERT_MS_2_TICKS(100), OS_TIMER_SUCCESS,
(void*)OS\u GET\u CURRENT\u TASK(),sns\u timer\u cb);
OS_ASSERT(sns_timer);
OS\u TIMER\u START(sns\u TIMER,OS\u TIMER\u FOREVER);
...
if(notif&SNS\u计时器\u notif){
refresh_sensor();
}
...
但几秒钟后,uart打印停止。接电话时,我发现程序在sys\u power\u mgr.c的第2132行运行:
//暂停任何正在进行的QSPI程序/擦除操作。
if (op != NULL) { //2132
DBG_SET_HIGH(FLASH_DEBUG, FLASHDBG_SUSPEND);
if(qspi\u check\u和\u suspend()){
op->suspended=真;
}
DBG\u SET\u LOW(FLASH\u DEBUG,FLASHDBG\u SUSPEND);
}
}
3.我尝试了另一种方法,删除snsè计时器,在(;),启动ble服务后:
而(1){
refresh_sensor();
操作系统延迟(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
*/
__注射用水();
/*确保以尽可能快的速度执行代码*/
如果(!允许进入睡眠{//1513
hw_cpm_set_hclk_div(ahb_div1);
}
4.我创建了一个新任务,优先级比ble\u任务低。只执行while循环:
而(1){
refresh_sensor();
操作系统延迟(50);
}
I get the same result as 3.
2,3,4的所有测试我都尝试了pm\u stay\u alive()函数,或者不启用watchdog,但是得到了相同的结果。
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\u peripheral\u任务(void*params)
{
int8_t wdog_id;
ble\ U service\ t*svc公司;
OS\u TASK handle=NULL;
my_peripheral_init();
而(1){
refresh_sensor();
操作系统延迟(50);
}
.....
它似乎读取I2C经常无法与BLE堆叠共存。什么是问题?
Loop forward for your reply.
Thank you.
您应该能够通过I2C读取设备,并且仍然可以执行可恢复操作。你能发布你用来初始化I2C接口和读取传感器的代码吗。
嗨,我的对话,
谢谢你的好意。以下是初始化代码:
bool i2c_devices_async_init(void)
{
bool ret1,ret2;
静态const i2c_config cfg = {
.speed = HW_I2C_SPEED_STANDARD,
.mode=HW\u I2C\u mode\u 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。
*/
初始化事件(&i2c\U信号);
// ret1 = tp_device_init();
ret2=imu6axes_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 :
静电void refresh_sensor(void)
{
int32_t imudata[6];
int16Āt magdata[3];
uint8_t k1status, tpirqstatus;
uint8_t xy[2];
//pmèu留èu活着();
k1status =(uint8_t)hw_gpio_get_pin_status(app_button_gpio_port,app_button_gpio_pin);
tpirqstatus=(uint8\u t)hw\u gpio\u get\u pin\u status(TP\u IRQ\u gpio\u PORT,TP\u IRQ\u gpio\u pin);
if(imu 6 x读取数据(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_coorder(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\ U read\ U data use imu\ U i2c\ U read函数从imu读取多个寄存器并计算值:
bool imu\u i2c\u read(uint8\u t*p缓冲区,uint8\u t设备地址,uint8\u t寄存器地址,
uint16(数字阅读器)
{
bool ret=假;
ad_i2c_device_acquire(imudev);
if(HW\u I2C\u ABORT\u NONE!=i2c\设备\读取\异步(imudev、&RegisterAddr、pBuffer、1、NumByteToRead和i2c\信号))
goto exit;
ret = true;
出口:
ad_i2c_device_release(imudev);
返回ret;
}
I2C读寄存器功能:与信号相关的功能与I2C\u 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\u t buflen,i2c\u event*事件)
{
/ *
* Make sure event is not in signal state yet;
*/
重置事件(event);
/ *
*写传感器寄存器时,使用回调函数,它会发出同步事件的信号。
*/
ad\u i2c\u async\u transact(dev,i2c\u SND(reg,reglen),i2c\u RCV(buf,buflen),
I2C\ U CB1(信号\事件,事件),I2C\ U端);
/ *
*等待事务完成。
*/
wait_for_event(event);
/ *
* Error code if any is stored in event, return it.
*/
返回事件->错误;
}
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[接收]-
IMU XG_ID:0x69
广告开始了!
IO:1 | 1附件:-38,161043,Gyro:1680,-10710,-7630
IO:1 | 1附件:-38,161041,Gyro:1610,-10570,-7630
IO:1|1 Acc:-38,16,1041, Gyro:1680,-10640,-7630
IO:1 | 1 ACC:-38,17,1040,陀螺仪: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
...
问候,
Duan
当使用I2C适配器时,您需要配置设备和I2C总线,方法是将以下内容添加到名为platform\u devices.h的文件中,该文件位于配置文件夹中:
When you then want to initialize the port you make the following calls:
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\u SDK\u BTLE\u v\u 1.0.8.1050.1\projects\dk\u apps\demos\peripherals\u demo\demos\demo\i2c\u async.c
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配置\u MAG \u AK09915
/*温度传感器FM75示例*/
I2C\从设备(I2C1、MAG\ U AK09915、0x0c、HW\ U I2C\ U寻址\U 7B、HW\ U I2C\ U速度\U标准);
#结束
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中的hardware init和devices open之间添加宏:
hw_i2c_init(HW_I2C1, &cfg);
srand(OS_GET_TICK_COUNT());
I2C总线初始化(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);
但得到同样的结果。我下一步该怎么做?谢谢您!
你好,段尼尔,
你提到代码卡住的点,它没有卡住,(没有(1)或任何断言使您的代码卡住),代码仍然执行(可以检查您是否能够查看任何广告代码摊位的空气)。当您附加并且您在这些点处找到代码是因为代码经常或在__wfi()案例中浏览这些点,它只等待发生中断。您提到的硬盘是一种不同的原因,它不是一个BLE或适配器的原因,HardFaults发生在内存中未alalign的访问,对空指针函数,记忆损坏等的调用。我建议做的是检查FW通过系统查看器或臭氧调试器,检查任务和使用的适配器会发生什么,也可以轮询传感器并以较小的频率打印并检查系统是否无法打印。我们非常困难地假设代码可能出现问题,但由于您使用的适配器,SDK应该正确处理BLE事件和I2C交易。
Thanks MT_dialog
我也有同样的问题。但这只发生在一块木板上。我一共有两块板。另一个工作得很好。
I M还使用I2C适配器进行I2C传感器读取温度。这个问题的解决方案是什么,,,,?任何人都可以帮助我吗?
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