rt-thread从头解析引脚设备初始化及使用

一、怎么使用

在应用层是这样使用的:
例如:
#define LED_PIN 3
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);** /初始化LED_PIN为输出模式,直接用mcu的第几脚表示/
pin.c:
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.c:
rt_pin_write(LED_PIN, PIN_LOW); /设置LED_PIN脚为低电平/
void rt_pin_write(rt_base_t pin, rt_base_t value)
{
RT_ASSERT(_hw_pin.ops != RT_NULL);
_hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
}

pin.c:
rt_pin_read(LED_PIN); /读LED_PIN脚状态/
int rt_pin_read(rt_base_t pin)
{
RT_ASSERT(_hw_pin.ops != RT_NULL);
return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
}

二、从头开始解析

S u b Sub Sub$main函数调用rtthread_startup(),
components.c
int S u b Sub Sub$main(void)
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}

rtthread_startup()->rt_hw_board_init()
components.c
int rtthread_startup(void)
{
……
/* board level initalization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
……
}

rt_hw_board_init()->rt_components_board_init()
board.c
void rt_hw_board_init(void)
{
……
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
……
}

在rt_components_board_init()函数里会依次调用INIT_BOARD_EXPORT()这个宏存放在特定位置的函数,自然而然的调用了rt_hw_pin_init()这个函数
drv_gpio.c
INIT_BOARD_EXPORT(rt_hw_pin_init);
components.c
void rt_components_board_init(void)
{
……
for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
{
(*fn_ptr)();
}
……
}

drv_gpio.c
int rt_hw_pin_init(void)
{
int result;
result = rt_device_pin_register(“pin”, &_stm32_pin_ops, RT_NULL);
return result;
}
rt_hw_pin_init()->rt_device_pin_register(“pin”, &_stm32_pin_ops, RT_NULL);
pin.c
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;

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

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

}
pin.c定义:static struct rt_device_pin _hw_pin;
drv_gpio.c定义rt_pin_ops 结构体:
drv_gpio.c
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,
};
_stm32_pin_ops 结构体存放的都是底层的操作函数。
_hw_pin.ops指向_stm32_pin_ops 结构体,这样一通操作之后底层的初始函数就和应用层的接口函数建立了联系,值得一提的是这样不仅注册了一个rt_device_pin设备,还注册了一个相关联的rt_device设备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值