Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Hardfault
程序启动时会随机的掉入内存异常中断和hard fault,我该怎么才能定位错误呢?
发布于 2013-05-11 17:51:16 浏览:6997
订阅该版
程序启动时会随机的掉入内存异常中断MemManage_Handler和hard fault,还有一定的几率能正常运行,不知道在什么地方掉进去的,怎么跟踪到出错的位置呢? 有的时候还会出现硬件错误,该怎么跟踪呢? 比如说: ``` psr: 0x40000000 pc: 0x00000000 lr: 0x08008979 r12: 0x00000000 r03: 0xffffffff r02: 0x00000000 r01: 0x20007550 r00: 0x20007984 hard fault on thread: erx thread pri status sp stack size max used left tick error -------- ---- ------- ---------- ---------- ---------- ---------- --- wlan 0x0a suspend 0x000000a4 0x00000800 0x000000ec 0x0000005f 000 etx 0x0f ready 0x00000040 0x00000200 0x00000040 0x00000010 000 erx 0x0f ready 0x00000040 0x00000200 0x00000060 0x00000010 000 tidle 0x1f ready 0x00000040 0x00000100 0x00000040 0x00000020 000 tshell 0x14 ready 0x00000040 0x00000800 0x00000040 0x0000000a 000 LED 0x1e ready 0x00000040 0x00000200 0x00000040 0x00000001 000 init 0x08 suspend 0x00000240 0x00000800 0x0000025c 0x00000009 000 ```
查看更多
11
个回答
默认排序
按发布时间排序
aishiqi
2013-05-11
这家伙很懒,什么也没写!
有进展了~ 跟踪到了ethernetif.c ```c void eth_rx_thread_entry(void* parameter) { struct eth_device* device; while (1) { if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK) { struct pbuf *p; /* check link status */ if (device->link_changed) { int status; rt_uint32_t level; level = rt_hw_interrupt_disable(); status = device->link_status; device->link_changed = 0x00; rt_hw_interrupt_enable(level); if (status) netifapi_netif_set_link_up(device->netif); else netifapi_netif_set_link_down(device->netif); } /* receive all of buffer */ while (1) { p = device->eth_rx(&(device->parent)); if (p != RT_NULL) { /* notify to upper layer */ if( device->netif->input(p, device->netif) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error ")); pbuf_free(p); p = NULL; } } else break; } } } } ``` 其中这一句: `if( device->netif->input(p, device->netif) != ERR_OK )` 的input指针会有一定的几率指向三种不同的函数。 有时候会指向08002739 一看 `i.MemManage_Handler 0x08002738 Section 0 stm32f10x_it.o(i.MemManage_Handler)` 怪不得会出现内存异常呢,看来还不是中断产生的。 有时候会等于00000000,随后就出现hard fault了。 有时候会等于080165CD,一看 `i.tcpip_input 0x080165cc Section 0 tcpip.o(i.tcpip_input)` 这时候就正常了。 奇怪的是为啥启动时会出现这样的随机情况~不管怎样,反正是抓住把柄了。应该是能找到原因的~吃饭去了~ 顺便问一句,为啥Map里的函数地址比Debug时看到的要小1个呢?
aozima
2013-05-11
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
还是写穿的可能比较大,这块要深入调试。 可以把对被篡改的变量加写断点,这样有谁在篡改时就被抓了。 >为啥Map里的函数地址比Debug时看到的要小1个呢? 标识这个程序是thumb模式指令,以跟原来有ARM模式的芯片兼容。 详情请参考:[《ARM Cortex-M3权威指南》](http://product.dangdang.com/product.aspx?product_id=20637694) PS: 译者 http://www.rt-thread.org/phpBB3/viewtopic.php?f=28&p=14440 Rocky 还夸过你哦 [s:175]
aishiqi
2013-05-11
这家伙很懒,什么也没写!
感谢回复! 问题快找到了~ netif中 ```c netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) { static u8_t netifnum = 0; /* reset new interface configuration state */ netif->ip_addr.addr = 0; netif->netmask.addr = 0; netif->gw.addr = 0; /* netif->flags = 0; */ #if LWIP_DHCP /* netif not under DHCP control by default */ netif->dhcp = NULL; #endif /* LWIP_DHCP */ #if LWIP_AUTOIP /* netif not under AutoIP control by default */ netif->autoip = NULL; #endif /* LWIP_AUTOIP */ #if LWIP_NETIF_STATUS_CALLBACK netif->status_callback = NULL; #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK netif->link_callback = NULL; #endif /* LWIP_NETIF_LINK_CALLBACK */ #if LWIP_IGMP netif->igmp_mac_filter = NULL; #endif /* LWIP_IGMP */ #if ENABLE_LOOPBACK netif->loop_first = NULL; netif->loop_last = NULL; #endif /* ENABLE_LOOPBACK */ /* remember netif specific state information data */ netif->state = state; netif->num = netifnum++; netif->input = input; ....................... [/code] 这个函数在连接上的时候才被调用。这里对input指针赋值。 然而有一定的几率 [code]void eth_rx_thread_entry(void* parameter) { struct eth_device* device; while (1) { if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK) { struct pbuf *p; /* check link status */ if (device->link_changed) { int status; rt_uint32_t level; level = rt_hw_interrupt_disable(); status = device->link_status; device->link_changed = 0x00; rt_hw_interrupt_enable(level); if (status) netifapi_netif_set_link_up(device->netif); else netifapi_netif_set_link_down(device->netif); } /* receive all of buffer */ while (1) { p = device->eth_rx(&(device->parent)); if (p != RT_NULL) { /* notify to upper layer */ if( device->netif->input(p, device->netif) != ERR_OK ) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error ")); pbuf_free(p); p = NULL; } } else break; } } } } ``` 这个在刚起动的时候就意外执行。所以input指针肯定是乱的啦~问题基本可以认为 `if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK)` 不正常的接受到邮件了。 猜想可能是WIFI模块刚复位的时候意外的发来个数据包。这时网络协议都没有初试话完毕。而在单片机复位时WIFI模块并没有被复位,而是正常运行着。(不过好像一起上电也有同样的问题)我再来看看吧~ PS:Rocky是怎么认识我的呢?为啥要夸奖我? [s:186]
bernard
2013-05-11
这家伙很懒,什么也没写!
内存写穿了,这个肯定是必然的了。所以你可以在上面下数据断点。
aishiqi
2013-05-11
这家伙很懒,什么也没写!
跟了好久,发现TCP的初始化是在新的线程里面完成的 ```c tcpip_init(tcpip_init_done_callback,(void *)&done_sem); ``` ```c tcpip_init(void (* initfunc)(void *), void *arg) { lwip_init(); tcpip_init_done = initfunc; tcpip_init_done_arg = arg; mbox = sys_mbox_new(TCPIP_MBOX_SIZE); #if LWIP_TCPIP_CORE_LOCKING lock_tcpip_core = sys_sem_new(1); #endif /* LWIP_TCPIP_CORE_LOCKING */ sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); } ``` 怪不得我随便怎么移动WIFI开中断的位置,都不行呢,在两个线程就不知道谁先执行完了。我该怎么在TCP初始化执行完才来初始化WIFI呢?貌似改动源代码不太好吧? [s:154] 好累,明天再看看官方的网卡中断是在什么时候开的~~
aishiqi
2013-05-12
这家伙很懒,什么也没写!
好了,问题总算解决了,总结一下: TCP初始化线程是独立的,而不是init线程,所以在init线程中初始化的WIFI程序虽然放在其后,但是有可能在其之前完成,并打开中断。如果这是WIFI模块送来了数据就会执行input函数。如果执行到这里TCP还没有初始化完的话,执行到input函数就出现异常了。 然后我想在TCP初始化完成之后来初始化WIFI模块。在执行完之后发送个事件,再执行WIFI初始化函数。结果发现,只要有数据包来就会异常(比前者更坏)。原来是这样的: ```c for (node = information->object_list.next; node != &(information->object_list); node = node->next) { object = rt_list_entry(node, struct rt_object, list); device = (rt_device_t) object; if (device->type == RT_Device_Class_NetIf) { ethif = (struct eth_device*)device; /* leave critical */ rt_exit_critical(); netif_add(ethif->netif, &ipaddr, &netmask, &gw, ethif, netif_device_init, tcpip_input); ``` ```c int rt_wlan_init(void) { rt_int32_t value=0; rt_err_t error=RT_EOK; /* * SRAM Tx/Rx pointer automatically return to start address, * Packet Transmitted, Packet Received */ wlan_eth.parent.parent.init = rt_wlan_dev_init; wlan_eth.parent.parent.open = rt_wlan_dev_open; wlan_eth.parent.parent.close = rt_wlan_dev_close; wlan_eth.parent.parent.read = rt_wlan_dev_read; wlan_eth.parent.parent.write = rt_wlan_dev_write; wlan_eth.parent.parent.control = rt_wlan_dev_control; wlan_eth.parent.parent.user_data =(void *)&wlan_eth ; wlan_eth.parent.eth_rx = rt_wlan_dev_rx; wlan_eth.parent.eth_tx = rt_wlan_dev_tx; if (WlanInitPhase1(&wlan_eth) == 0) { WlanInitPhase2(); WlanInitPhase3(); eth_device_init(&(wlan_eth.parent), "w0"); } done: return error; } ``` 必须先初始化网卡模块才有设备节点,在TCPIP初始化时才能运行到netif_add,否则直接就跳过了。这样input函数就永远不会被指定了。 好,随后我就想先让先让WIFI初始化,但是不开中断。等到TCPIP初始化完之后才开中断。结果呢,程序卡了。原因是在WIFI初始化过程中有对寄存器的操作,这些操作需要用到中断,否则就在那儿忙等待。 最后无赖把WIFI初始化过程分成两个部分,先注册设备,再初始化TCPIP,等初始化完了,才真正的初始化WIFI模块。像这样: ```c SPI1_Init(); rt_wlan_init(); /* init lwip system */ lwip_sys_init(); rt_kprintf("TCP/IP initialized! "); rt_event_recv(&tcpip_done, 1,RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &ev_value); wlan_module_init(); rt_kprintf("wlan initialized "); ``` 恩!不错,现在再也没有死机了。就是这个原因! 慢慢的,开始学会追踪程序了,哈哈 [s:154]
rtthsl
2013-06-03
这家伙很懒,什么也没写!
mark一下
qq_强者√风范o
2014-01-13
这家伙很懒,什么也没写!
楼主很有毅力,赞一个
wangway
2014-06-12
这家伙很懒,什么也没写!
兄弟,真是太感谢你了,我也遇到了这个问题,更痛苦的是用swd一仿真,ide就被强制关闭,根本没办法单步调试。幸亏看到了你的帖子,不然就得放弃了。
thomasgds
2014-07-02
这家伙很懒,什么也没写!
好像stm32f2x7的网卡驱动初始化也有这个问题吧?
撰写答案
登录
注册新账号
关注者
0
被浏览
7k
关于作者
aishiqi
这家伙很懒,什么也没写!
提问
6
回答
20
被采纳
0
关注TA
发私信
相关问题
1
RTT1.0,STM32调试时会跑到HardFault【已解决】,出现新问题
2
新手请教关于hardfault怎么查
3
github最新版本库中stm32f0X分支,运行切换任务时候出现hardfault[已解决]
4
实现iap功能,bootloader使用了rtt操作系统,在跳转到app代码的时候提示出现hardfault的问题
5
ymodem在on_begin内发送can无法断开连接,而且RTT会报hardfault
6
挂载UFFS文件系统执行到退出_BuildTreeStepOne函数时hardfault异常
7
STM32F1+RTT串口接收中断进入hardfault
8
STM32F746NG随机进入hardfault(已解决)
9
[已解决]自已建了个STM32F103的MDK工程,初始化时总是进入HardFault,求教!
10
将 Cortex M3 的 hardfault 处理与 M4、M7、M0 保持一致?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部