zephyr學習筆記---CC3200---GPIO

搞完LED,搞Button,【\samples\basic\button】目錄下有關於button的按鈕,發現printk()函數在串口打印顯示不正常。於是乎讀有關UART的DataSheet想找到問題所在,讀DataSheet太痛苦了,頭暈眼花啊!體力活。最後發現顯示不正常是波特率沒設置對,cc3200在zephyr中默認設置爲115200。雖然DataSheet白讀了,但也瞭解不少東西,這就是學習。準備改寫button例子,發現有必要先把GPIO搞清楚,於是先針對GPIO寫一篇日誌吧。

要了解zephyr的GPIO首先要了解【\include\gpio.h】頭文件,它是統一調用接口。代碼比較多,但不必驚慌,只要抓住重點,這些代碼就不難懂了。代碼主要分爲2個部分,下面一一講解。

第一部分:引腳功能標誌位宏定義

在之後的函數中,經常會看到一個整型flag參數,此參數代表了對應PIN所設置的功能狀態。flag中的每個位都對應一種功能或狀態,下面用一張圖表示出來:


每個位的具體使用方法及功能請參考源碼註釋,已經足夠詳細。

第二部分:GPIO驅動
第二部分主要關注核心代碼gpio_driver_api結構體的聲明:
struct gpio_driver_api {
    gpio_config_t config;
    gpio_write_t write;
    gpio_read_t read;
    gpio_manage_callback_t manage_callback;
    gpio_enable_callback_t enable_callback;
    gpio_disable_callback_t disable_callback;
    gpio_api_get_pending_int get_pending_int;
};
7個成員全爲函數指針,這7個函數的第一個參數無一例外都是
struct device *port
device代表一個設備或端口,在【\include\device.h】中device定義如下:
/**
 * @brief 運行時每個設備實例在內存中的結構體
 * @param device_config 創建時的配置信息
 * @param driver_api  結構體指針,包含設備類型的API函數。
 *                    這些指針在初始化時由驅動填充。
 * @param driver_data 驅動實例數據. 僅爲驅動使用
 */

struct device {
    struct device_config *config;
    const void *driver_api;
    void *driver_data;
};
每個device的第二個成員*driver_api實際上就是gpio_driver_api結構體,通過它就可以調用各個函數原型。

gpio_driver_api結構體中的每個函數指針都對應2個函數原型,一個是指針訪問方式,一個是端口訪問方式,這裏只configure函數來講解:
static inline int gpio_pin_configure(struct device *port, uint8_t pin,
                     int flags)
{
    const struct gpio_driver_api *api = port->driver_api;

    return api->config(port, GPIO_ACCESS_BY_PIN, pin, flags);
}

static inline int gpio_port_configure(struct device *port, int flags)
{
    const struct gpio_driver_api *api = port->driver_api;

    return api->config(port, GPIO_ACCESS_BY_PORT, 0, flags);
}
可以看到,最終調用的還是各個設備自己定義的API函數。可以把gpio_driver_api理解爲調用接口或代理。
具體到CC3200的API實現,可參考\drivers\gpio\gpio_cc32xx.c】文件。代碼就不具體講解了,這裏只需注意,回調函數被加到一個單向鏈表串了起來。可通過gpio_add_callback函數和gpio_remove_callback函數進行添加和刪除。

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