RT-Thread学习——rt_pin_mode()函数分析
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RT-Thread学习——rt_pin_mode()函数分析相关的知识,希望对你有一定的参考价值。
RT-Thread学习
rt_pin_mode()函数分析
- main.c中使用rt_pin_mode()函数
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
- pin.c中的结构体和函数定义
static struct rt_device_pin _hw_pin;
//在初始化时根据芯片(如struct rt_pin_ops _stm32_pin_ops)注册对应信息和_hw_pin.ops的对应函数
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)
{
_hw_pin.parent.type = RT_Device_Class_Miscellaneous;
_hw_pin.parent.rx_indicate = RT_NULL;
_hw_pin.parent.tx_complete = RT_NULL;
#ifdef RT_USING_DEVICE_OPS
_hw_pin.parent.ops = &pin_ops;
#else
_hw_pin.parent.init = RT_NULL;
_hw_pin.parent.open = RT_NULL;
_hw_pin.parent.close = RT_NULL;
_hw_pin.parent.read = _pin_read;
_hw_pin.parent.write = _pin_write;
_hw_pin.parent.control = _pin_control;
#endif
_hw_pin.ops = ops;
_hw_pin.parent.user_data = user_data;
/* register a character device */
rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR);
return 0;
}
//根据_stm32_pin_ops, _hw_pin.ops->pin_mode的函数为stm32_pin_mode
void rt_pin_mode(rt_base_t pin, rt_base_t mode)
{
RT_ASSERT(_hw_pin.ops != RT_NULL);
_hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
}
pin.h
struct rt_pin_ops
{
void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
int (*pin_read)(struct rt_device *device, rt_base_t pin);
/* TODO: add GPIO interrupt */
rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
};
struct rt_device_pin
{
struct rt_device parent;
const struct rt_pin_ops *ops;
};
rtdef.h
struct rt_device
{
struct rt_object parent; /**< inherit from rt_object */
enum rt_device_class_type type; /**< device type */
rt_uint16_t flag; /**< device flag */
rt_uint16_t open_flag; /**< device open flag */
rt_uint8_t ref_count; /**< reference count */
rt_uint8_t device_id; /**< 0 - 255 */
/* device call back */
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
#ifdef RT_USING_DEVICE_OPS
const struct rt_device_ops *ops;
#else
/* common device interface */
rt_err_t (*init) (rt_device_t dev);
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close) (rt_device_t dev);
rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
#endif
void *user_data; /**< device private data */
};
drv_gpio.c
//根据相应芯片,创建结构体_stm32_pin_ops
const static struct rt_pin_ops _stm32_pin_ops =
{
stm32_pin_mode,
stm32_pin_write,
stm32_pin_read,
stm32_pin_attach_irq,
stm32_pin_dettach_irq,
stm32_pin_irq_enable,
};
static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
const struct pin_index *index;
GPIO_InitTypeDef GPIO_InitStruct;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
/* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = index->pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
if (mode == PIN_MODE_OUTPUT)
{
/* output setting */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT)
{
/* input setting: not pull. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT_PULLUP)
{
/* input setting: pull up. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
}
else if (mode == PIN_MODE_INPUT_PULLDOWN)
{
/* input setting: pull down. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
}
else if (mode == PIN_MODE_OUTPUT_OD)
{
/* output setting: od. */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
}
//芯片引脚初始化
int rt_hw_pin_init(void)
{
#if defined(__HAL_RCC_GPIOA_CLK_ENABLE)
__HAL_RCC_GPIOA_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOB_CLK_ENABLE)
__HAL_RCC_GPIOB_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOC_CLK_ENABLE)
__HAL_RCC_GPIOC_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOD_CLK_ENABLE)
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOE_CLK_ENABLE)
__HAL_RCC_GPIOE_CLK_ENABLE();
#endif
return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
}
以上是关于RT-Thread学习——rt_pin_mode()函数分析的主要内容,如果未能解决你的问题,请参考以下文章
RT-Thread 内核学习笔记 - 设备模型rt_device的理解
RT-Thread学习笔记 --RT-Thread内存管理学习总结