日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LwIP之定时事件

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LwIP之定时事件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先看一下定時事件數據結構

/* 定時回調函數指針 */ typedef void (*sys_timeout_handler)(void *arg);/* 定時器事件 */ struct sys_timeo {struct sys_timeo *next; //下一個定時事件u32_t time; //定時時間sys_timeout_handler h; //定時回調函數void *arg; //定時回調參數 };

?

所有的定時事件最終被串接在一個鏈表上

/* 定時事件隊列 */ static struct sys_timeo *next_timeout;

?

下面看一下定時機制的實現代碼

/* 初始化定時事件 */ void sys_timeouts_init(void) {/* 啟動IP重組定時事件 */sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);/* 啟動ARP定時事件 */sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); }/* 啟動定時事件 */ void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) {struct sys_timeo *timeout, *t;/* 為定時事件結構體申請空間 */timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);if(timeout == NULL) {return;}/* 初始化參數 */timeout->next = NULL;timeout->h = handler;timeout->arg = arg;timeout->time = msecs;/* 定時事件隊列為空 */if(next_timeout == NULL) {next_timeout = timeout;return;}/* 將定時事件插入鏈表 */if(next_timeout->time > msecs) {next_timeout->time -= msecs;timeout->next = next_timeout;next_timeout = timeout;} else {for(t = next_timeout; t != NULL; t = t->next) {timeout->time -= t->time;if(t->next == NULL || t->next->time > timeout->time) {if(t->next != NULL) {t->next->time -= timeout->time;}timeout->next = t->next;t->next = timeout;break;}}} }/* 取消定時事件 */ void sys_untimeout(sys_timeout_handler handler, void *arg) {struct sys_timeo *prev_t, *t;if(next_timeout == NULL) {return;}/* 將定時事件從鏈表中取出,并釋放空間 */for(t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {if((t->h == handler) && (t->arg == arg)) {if(prev_t == NULL) {next_timeout = t->next;} else {prev_t->next = t->next;}if(t->next != NULL) {t->next->time += t->time;}memp_free(MEMP_SYS_TIMEOUT, t);return;}}return; }/* 等待最早的事件超時或者等待郵箱消息 */ void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) {u32_t time_needed;struct sys_timeo *tmptimeout;sys_timeout_handler handler;void *arg;again:/* 沒有定時事件 */if(!next_timeout){time_needed = sys_arch_mbox_fetch(mbox, msg, 0);}/* 有定時事件 */else{/* 等待郵箱消息 */if(next_timeout->time > 0){time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time);}else{time_needed = SYS_ARCH_TIMEOUT;}/* 接收超時 */if(time_needed == SYS_ARCH_TIMEOUT){/* 刪除定時事件 */tmptimeout = next_timeout;next_timeout = tmptimeout->next;handler = tmptimeout->h;arg = tmptimeout->arg;memp_free(MEMP_SYS_TIMEOUT, tmptimeout);/* 調用定時事件 */if(handler != NULL){LOCK_TCPIP_CORE();handler(arg);UNLOCK_TCPIP_CORE();}LWIP_TCPIP_THREAD_ALIVE();goto again;}/* 接收到郵箱消息 */ else{/* 更新定時事件 */if(time_needed < next_timeout->time){next_timeout->time -= time_needed;}else{next_timeout->time = 0;}}} }

?

最后看一下協議棧中的幾個定時事件

/* TCP定時器活躍標志位 */ static int tcpip_tcp_timer_active;/* TCP定時事件回調函數 */ static void tcpip_tcp_timer(void *arg) {/* TCP定時器回調函數(周期250ms) */tcp_tmr();/* 存在活躍(正在交互)的TCP控制塊 *//* 或存在等待2MSL狀態的TCP控制塊 */if(tcp_active_pcbs || tcp_tw_pcbs) {/* 再次啟動定時事件 */sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);} else {tcpip_tcp_timer_active = 0;} }/* 根據條件啟動TCP定時事件 */ void tcp_timer_needed(void) {/* TCP定時事件未啟動 *//* 存在活躍(正在交互)的TCP控制塊 *//* 或存在等待2MSL狀態的TCP控制塊 */if(!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {/* 啟動TCP定時事件 */tcpip_tcp_timer_active = 1;sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);} }/* IP重組定時事件回調函數 */ static void ip_reass_timer(void *arg) {/* 重組IP數據報定時器回調函數(周期1秒) */ip_reass_tmr();/* 啟動IP重組定時事件 */sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); }/* ARP定時事件回調函數 */ static void arp_timer(void *arg) {/* ARP定時器回調函數(周期5秒) */etharp_tmr();/* 啟動ARP定時事件 */sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); }

?

總結

以上是生活随笔為你收集整理的LwIP之定时事件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。