zephyr学习笔记---CC3200---GPIO

来源:互联网 发布:农村淘宝官网电话 编辑:程序博客网 时间:2024/06/08 19:38
搞完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函数进行添加和删除。