嵌入式MCU C語言實現回調函數設計

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;
            }
        }
    }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章