1.有這麼一個列表維護這所有回調函數的指針 回調函數的註冊就是給列表的添加回到函數指針
遍歷列表逐個調指針 即可實現回調
typedef void (*tls_netif_status_event_fn)(u8 status);
struct tls_netif_status_event
{
struct dl_list list;
tls_netif_status_event_fn status_callback;
};
2.函數指針類型定義 形式如下
typedef err_t (*netif_init_fn)(struct netif *netif);
typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p);
/** Function prototype for netif status- or link-callback functions. */
typedef void (*netif_status_callback_fn)(struct netif *netif);
/** Function prototype for netif igmp_mac_filter functions */
typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif,ip_addr_t *group, u8_t action);
2.將回調函數加入列表中
err_t tls_netif_add_status_event(tls_netif_status_event_fn event_fn)
{
u32 cpu_sr;
struct tls_netif_status_event *evt;
//if exist, remove from event list first.
tls_netif_remove_status_event(event_fn);
evt = tls_mem_alloc(sizeof(struct tls_netif_status_event));
if(evt==NULL)
return -1;
memset(evt, 0, sizeof(struct tls_netif_status_event));
evt->status_callback = event_fn;
cpu_sr = tls_os_set_critical();
dl_list_add_tail(&netif_status_event.list, &evt->list);
tls_os_release_critical(cpu_sr);
return 0;
}
2.1將回調函數從列表中刪除
err_t tls_netif_remove_status_event(tls_netif_status_event_fn event_fn)
{
struct tls_netif_status_event *status_event;
bool is_exist = FALSE;
u32 cpu_sr;
if(dl_list_empty(&netif_status_event.list))
return 0;
dl_list_for_each(status_event, &netif_status_event.list, struct tls_netif_status_event, list)
{
if(status_event->status_callback == event_fn)
{
is_exist = TRUE;
break;
}
}
if(is_exist)
{
cpu_sr = tls_os_set_critical();
dl_list_del(&status_event->list);
tls_os_release_critical(cpu_sr);
tls_mem_free(status_event);
}
return 0;
}
註冊使用
netif_set_status_callback(nif, netif_status_changed);
tls_wifi_status_change_cb_register(wifi_status_changed);
註冊函數接口
void tls_wifi_status_change_cb_register(void (*callback)(u8 status));
最後 有一個週期執行的函數 遍歷列表 逐個調用列表的函數指針
static void wifi_status_changed(u8 status)
{
struct tls_netif_status_event *status_event;
dl_list_for_each(status_event, &netif_status_event.list, struct tls_netif_status_event, list)
{
if(status_event->status_callback != NULL)
{
switch(status)
{
case WIFI_JOIN_SUCCESS:
status_event->status_callback(NETIF_WIFI_JOIN_SUCCESS);
break;
case WIFI_JOIN_FAILED:
status_event->status_callback(NETIF_WIFI_JOIN_FAILED);
break;
case WIFI_DISCONNECTED:
status_event->status_callback(NETIF_WIFI_DISCONNECTED);
break;
#if TLS_CONFIG_APSTA
case WIFI_APSTA_STA_JOIN_SUCCESS:
status_event->status_callback(NETIF_WIFI_APSTA_STA_SUCCESS);
break;
case WIFI_APSTA_AP_JOIN_SUCCESS:
status_event->status_callback(NETIF_WIFI_APSTA_AP_SUCCESS);
break;
#endif
default:
break;
}
}
}
}