
基础分析
设备驱动层:具体实现如stm32_pin_write_pin(int pin,int value){hal_write_pin(int pin,int value);}
设备驱动框架层:套壳,实现统一接口rt_write_pin(int pin,int value){hw_write_pin(stm32->write_pin,int pin,int value);}
PIN设备API
PIN设备通过PIN设备管理接口访问GPIO

框架分析
在project/rt-thread/components/drivers/pin/dev_pin.c下有驱动框架层
1 2 3 4 5 6 7 8 9 10 11
| rt_base_t rt_pin_get(const char *name) { RT_ASSERT(_hw_pin.ops != RT_NULL);
if (_hw_pin.ops->pin_get == RT_NULL) { return -RT_ENOSYS; } return _hw_pin.ops->pin_get(name); }
|
定位static struct rt_device_pin _hw_pin;,这个变量下有ops函数,找初始化赋值的地方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data) { _hw_pin.parent.type = RT_Device_Class_Pin; _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;
rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR);
return 0; }
|
这是注册函数,全局搜索找驱动层具体实现,在project/libraries/HAL_Drivers/drivers/drv_gpio.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int rt_hw_pin_init(void) { #if defined(__HAL_RCC_GPIOA_CLK_ENABLE) __HAL_RCC_GPIOA_CLK_ENABLE(); #endif
return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL); }
static const 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_get, RT_NULL, };
|
由此可以实现驱动框架层到驱动层的具体实现,即_hw_pin.ops = _stm32_pin_ops;
rt_get_pin()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| static rt_base_t stm32_pin_get(const char *name) { rt_base_t pin = 0; int hw_port_num, hw_pin_num = 0; int i, name_len;
name_len = rt_strlen(name);
if ((name_len < 4) || (name_len >= 6)) { goto out; } if ((name[0] != 'P') || (name[2] != '.')) { goto out; }
if ((name[1] >= 'A') && (name[1] <= 'Z')) { hw_port_num = (int)(name[1] - 'A'); } else { goto out; }
for (i = 3; i < name_len; i++) { hw_pin_num *= 10; hw_pin_num += name[i] - '0'; }
pin = PIN_NUM(hw_port_num, hw_pin_num);
return pin;
out: rt_kprintf("Px.y x:A~Z y:0-15, e.g. PA.0\n"); return -RT_EINVAL; }
|
不止一种方式可以获取编号,后者直接使用rt_pin_write(后者在nano版下的也可以用)
1
| #define GET_PIN(PORTx,PIN) (rt_uint64_t)((((rt_uint64_t)GPIO_PIN_##PIN) << 32) | (rt_uint64_t)(rt_ubase_t)GPIO##PORTx)
|
rt_pin_mode()
上层调用rt_pin_mode(),向下调用stm32_pin_mode()使用具体的驱动函数
1 2 3 4 5 6
| void rt_pin_mode(rt_base_t pin, rt_uint8_t mode) { RT_ASSERT(_hw_pin.ops != RT_NULL); _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode) { GPIO_InitTypeDef GPIO_InitStruct;
if (PIN_PORT(pin) >= PIN_STPORT_MAX) { return; }
GPIO_InitStruct.Pin = PIN_STPIN(pin); GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
if (mode == PIN_MODE_OUTPUT) { GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; } else if (mode == PIN_MODE_INPUT) { GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; } else if (mode == PIN_MODE_INPUT_PULLUP) { GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; } else if (mode == PIN_MODE_INPUT_PULLDOWN) { GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; } else if (mode == PIN_MODE_OUTPUT_OD) { GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; }
HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct); }
|
中断
调用链HAL->pin_irq_hdr()
通过rt_pin_attach_irq()和rt_pin_detach_irq()注册和注销中断回调函数
注销中断回调函数不会关闭中断
底层同样是stm32_pin_attach_irq()