Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
关于rtgui_textbox控件和rtgui_timer
发布于 2014-04-24 16:10:08 浏览:4403
订阅该版
最近在使用RTGUI调试界面,其中用到rtgui_textbox控件。此控件在得到输入焦点后会创建一个rtgui_timer(caret_timer)用于光标的闪烁;在失去焦点后,会销毁该定时器。可能是我的使用方法不当,使用该控件后,经常发生hard fault错误。调试跟踪后,觉得可能和定时器有关。看rtgui_textbox的源代码, ```static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object *widget, rtgui_event_t *event) { rtgui_textbox_t *box = RTGUI_TEXTBOX(widget); rt_kprintf("textbox onunfocus "); /* stop caret timer */ if (box->caret_timer != RT_NULL) { rtgui_timer_stop(box->caret_timer); rtgui_timer_destory(box->caret_timer); box->caret_timer = RT_NULL; } /* set caret to hide */ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; rtgui_textbox_draw_caret(box, box->position); if (box->on_enter != RT_NULL) box->on_enter(box, event); rt_kprintf("textbox onunfocus success "); return RT_TRUE; }``` 其中rtgui_timer_destory()函数的实现如下: ```void rtgui_timer_destory(rtgui_timer_t *timer) { RT_ASSERT(timer != RT_NULL); /* stop timer firstly */ rtgui_timer_stop(timer); /* detach rt-thread timer */ rt_timer_detach(&(timer->timer)); rtgui_free(timer); }``` 该函数已经包含了rtgui_timer_stop(timer)。不知为什么调用两次rtgui_timer_stop(timer)。是有什么特别的含义吗? 望各位方家不吝赐教。 ![debug_info.png](https://oss-club.rt-thread.org/uploads/779_a6c4b8fa94491609f70403e35b94b7ff.png)
查看更多
18
个回答
默认排序
按发布时间排序
bernard
2014-04-24
这家伙很懒,什么也没写!
多次stop timer应该关系不大。能提供你的测试代码吗?
softwind
2014-04-25
这家伙很懒,什么也没写!
``` rt_err_t rt_timer_stop(rt_timer_t timer) { register rt_base_t level; /* timer check */ RT_ASSERT(timer != RT_NULL); if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)) return -RT_ERROR; RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent))); /* disable interrupt */ level = rt_hw_interrupt_disable(); /* remove it from timer list */ rt_list_remove(&(timer->list)); /* enable interrupt */ rt_hw_interrupt_enable(level); /* change stat */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; return RT_EOK; } ``` 以上是rt_timer_stop()的实现,其中rt_list_remove(&(timer->list))是将该节点从rt_timer_list中移除。多次调用的话,相当于移除一个已经移除的节点,不知是否会有什么问题?
bernard
2014-04-25
这家伙很懒,什么也没写!
多次移除也不会有问题的,那个是一个双向链表,所以没什么关系
softwind
2014-04-25
这家伙很懒,什么也没写!
有点儿糊涂了。如果系统中还有其他的周期性定时器,那么rt_timer_list是变化的,这样移除已经移除的节点也不会有问题吗?
bernard
2014-04-25
这家伙很懒,什么也没写!
``` rt_inline void rt_list_remove(rt_list_t *n) { n->next->prev = n->prev; n->prev->next = n->next; n->next = n->prev = n; } ``` 这个移除的代码。所以再移除一次,不过就是对自己的指针再操作一次,没什么非法的。
softwind
2014-04-25
这家伙很懒,什么也没写!
>``` > >rt_inline void rt_list_remove(rt_list_t *n) >{ > n->next->prev = n->prev; > n->prev->next = n->next; > > n->next = n->prev = n; >} > >``` > > > >这个移除的代码。所以再移除一次,不过就是对自己的指针再操作一次,没什么非法的。 --- 恩,感谢bernard,这里想清楚了。不过rtgui_textbox的问题还是一样,我再调试一下,可能是程序其他地方的问题。
softwind
2014-04-25
这家伙很懒,什么也没写!
现在调试的程序,GUI界面的框架大致如下: 1)与RealTouch类似,屏幕的最上面是StatusBar,有一个rtgui_timer定时刷新当前的时间; 2)屏幕的其他区域是一个notebook控件,风格是RTGUI_NOTEBOOK_NOTAB(类似与RTGUI的测试例程); 3)notebook的每个TAB是一个panel控件,该panel控件作为container,其上有其他的一些控件; 4)panel上有相关的按钮控件,在按钮控件的消息响应函数中调用rtgui_notebook_set_current_by_index(main_notebook, ***)手动实现TAB页面的切换; 5)其中一个页面上有一个rtgui_textbox控件,调试中发现,如果rtgui_textbox控件不获得焦点,或者说控制光标闪烁的box->caret_timer未创建的话,切换到其他的TAB页面没有问题;但该定时器激活后再切换到其他TAB,经常会出现hard fault。 我现在做了两点尝试: 1) ``` static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object *widget, rtgui_event_t *event) { rtgui_textbox_t *box = RTGUI_TEXTBOX(widget); rt_kprintf("textbox onunfocus "); /* stop caret timer */ if (box->caret_timer != RT_NULL) { rtgui_timer_stop(box->caret_timer); //rtgui_timer_destory(box->caret_timer); //box->caret_timer = RT_NULL; } /* set caret to hide */ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; rtgui_textbox_draw_caret(box, box->position); if (box->on_enter != RT_NULL) box->on_enter(box, event); rt_kprintf("textbox onunfocus success "); return RT_TRUE; } ``` 在该函数中注释掉 ``` //rtgui_timer_destory(box->caret_timer); //box->caret_timer = RT_NULL ``` 之后,hardfault问题不再出现; 2)我同时在 ``` static void rtgui_textbox_timeout(rtgui_timer_t *timer, void *parameter) { rtgui_textbox_t *box; rt_kprintf("textbox_timeout P1 "); box = RTGUI_TEXTBOX(parameter); /* set caret flag */ if (box->flag & RTGUI_TEXTBOX_CARET_SHOW) box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; else box->flag |= RTGUI_TEXTBOX_CARET_SHOW; rtgui_textbox_draw_caret(box, box->position); rt_kprintf("textbox_timeout P2 "); } ``` 函数中加入了两行调试信息,进行TAB页面的切换。发现很多时候,rtgui_textbox_onunfocus()函数执行之后,才执行rtgui_textbox_timeout()函数。 串口的调试信息: [attach]2264[/attach] 如果在rtgui_textbox_onunfocus()函数中调用 ``` rtgui_timer_destory(box->caret_timer); box->caret_timer = RT_NULL; ``` 的话,那么在 ``` rt_bool_t rtgui_app_event_handler(struct rtgui_object *object, rtgui_event_t *event) { ... case RTGUI_EVENT_TIMER: { struct rtgui_timer *timer; struct rtgui_event_timer *etimer = (struct rtgui_event_timer *) event; timer = etimer->timer; if (timer->timeout != RT_NULL) { /* call timeout function */ timer->timeout(timer, timer->user_data); } } ... } ``` 执行到case RTGUI_EVENT_TIMER:分支时,etimer->timer中timer有可能已经销毁了。不知这种情况是否可能?
softwind
2014-04-26
这家伙很懒,什么也没写!
@grissiom
grissiom
2014-04-26
这家伙很懒,什么也没写!
如果 timer 事件已经在队列中了,但是又去销毁 timer,应该会出现这样的问题…… 不过,貌似还没有好的办法解决,因为删除的时候不知道是不是有事件 pending 在 msgqueue 里……
softwind
2014-04-27
这家伙很懒,什么也没写!
从调试信息看,在TAB页面切换尤其是控件较多,刷新较慢时,确实会出现timer事件已经post到消息队列中的情况。现在暂时的解决方法如上文,控件失去焦点的时候,不销毁定时器,只是停止定时器。
撰写答案
登录
注册新账号
关注者
0
被浏览
4.4k
关于作者
softwind
这家伙很懒,什么也没写!
提问
41
回答
153
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
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
【NXP-MCXA153】 定时器驱动移植
2
GD32F450 看门狗驱动适配
3
【NXP-MCXA153】看门狗驱动移植
4
RT-Thread Studio V2.2.9 Release Note
5
CherryUSB的bootuf2配置
热门标签
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
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
9
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部