[原创] 《RT-Thread设备驱动开发指南》读书笔记二 PIN驱动

damiaa   2023-8-28 10:11 楼主

                                     《RT-Thread设备驱动开发指南》读书笔记二 PIN驱动

《RT-Thread设备驱动开发指南》读书笔记一 串口驱动之后

RT-Thread的所有设备类都是rt_device派生来的。所以都有相同的继承

PIN设备也是一样。为什么要了解PIN驱动呢,因为PIN驱动相对简单,大家也比较收悉,一般开始玩单片机就来一个点灯实验嘛。

IO口要做的事就是初始化(输入输出方向,上拉,中断等),读,写,中断开,关。PIN设备也是要实现这些,当然还要有设备注册等。

看pin.h中文件就可以看到rt_device_pin设备结构和rt_pin_ops结构:

223034v142x5a16x42j5a5.png

pin.c文件:可以看出它是与平台无关的。

#include <drivers/pin.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
static struct rt_device_pin _hw_pin;
static rt_size_t _pin_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
   struct rt_device_pin_status *status;
   struct rt_device_pin *pin = (struct rt_device_pin *)dev;
   /* check parameters */
   RT_ASSERT(pin != RT_NULL);
   status = (struct rt_device_pin_status *) buffer;
   if (status == RT_NULL || size != sizeof(*status)) return 0;
   status->status = pin->ops->pin_read(dev, status->pin);
   return size;
}
static rt_size_t _pin_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
   struct rt_device_pin_status *status;
   struct rt_device_pin *pin = (struct rt_device_pin *)dev;
   /* check parameters */
   RT_ASSERT(pin != RT_NULL);
   status = (struct rt_device_pin_status *) buffer;
   if (status == RT_NULL || size != sizeof(*status)) return 0;
   pin->ops->pin_write(dev, (rt_base_t)status->pin, (rt_base_t)status->status);
   return size;
}
static rt_err_t _pin_control(rt_device_t dev, int cmd, void *args)
{
   struct rt_device_pin_mode *mode;
   struct rt_device_pin *pin = (struct rt_device_pin *)dev;
   /* check parameters */
   RT_ASSERT(pin != RT_NULL);
   mode = (struct rt_device_pin_mode *) args;
   if (mode == RT_NULL) return -RT_ERROR;
   pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode);
   return 0;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops pin_ops =
{
   RT_NULL,
   RT_NULL,
   RT_NULL,
   _pin_read,
   _pin_write,
   _pin_control
};
#endif
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;
}
rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
void (*hdr)(void *args), void *args)
{
   RT_ASSERT(_hw_pin.ops != RT_NULL);
   if(_hw_pin.ops->pin_attach_irq)
   {
      return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);
   }
   return -RT_ENOSYS;
}
rt_err_t rt_pin_detach_irq(rt_int32_t pin)
{
   RT_ASSERT(_hw_pin.ops != RT_NULL);
   if(_hw_pin.ops->pin_detach_irq)
   {
      return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin);
   }
   return -RT_ENOSYS;
}

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
{
   RT_ASSERT(_hw_pin.ops != RT_NULL);
   if(_hw_pin.ops->pin_irq_enable)
   {
      return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled);
   }
   return -RT_ENOSYS;
}
/* RT-Thread Hardware PIN APIs */
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);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode);
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);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_write, pinWrite, write value to hardware 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);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);
rt_base_t rt_pin_get(const char *name)
{
   RT_ASSERT(_hw_pin.ops != RT_NULL);
   RT_ASSERT(name[0] == 'P');
  if(_hw_pin.ops->pin_get == RT_NULL)
  {
     return -RT_ENOSYS;
   }
   return _hw_pin.ops->pin_get(name);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_get, pinGet, get pin number from hardware pin);

但我们使用PIN设备是要与它打交道的,而且它都导出到finsh了,可以直接敲入命令调用。

 

设备驱动的具体实现实际上是在drv_gpio.c中的 如果我们移植cpu的pin drv_gpio.c中的内容就是要实现的内容

 

 

下面是IO映射,PIN模式,中断允许,读写函数,中断关联与取消关联,模式get,ops实现与挂钩的等内容:

#include <board.h>
#ifdef RT_USING_PIN
#define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu)))
#define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu))
#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
#if defined(SOC_SERIES_STM32MP1)
#if defined(GPIOZ)
#define gpioz_port_base (175) /* PIN_STPORT_MAX * 16 - 16 */
#define PIN_STPORT(pin) ((pin > gpioz_port_base) ? ((GPIO_TypeDef *)(GPIOZ_BASE )) : ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin)))))
#else
#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin))))
#endif /* GPIOZ */
#else
#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
#endif /* SOC_SERIES_STM32MP1 */
#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
#if defined(GPIOZ)
#define __STM32_PORT_MAX 12u
#elif defined(GPIOK)
#define __STM32_PORT_MAX 11u
#elif defined(GPIOJ)
#define __STM32_PORT_MAX 10u
#elif defined(GPIOI)
#define __STM32_PORT_MAX 9u
#elif defined(GPIOH)
#define __STM32_PORT_MAX 8u
#elif defined(GPIOG)
#define __STM32_PORT_MAX 7u
#elif defined(GPIOF)
#define __STM32_PORT_MAX 6u
#elif defined(GPIOE)
#define __STM32_PORT_MAX 5u
#elif defined(GPIOD)
#define __STM32_PORT_MAX 4u
#elif defined(GPIOC)
#define __STM32_PORT_MAX 3u
#elif defined(GPIOB)
#define __STM32_PORT_MAX 2u
#elif defined(GPIOA)
#define __STM32_PORT_MAX 1u
#else
#define __STM32_PORT_MAX 0u
#error Unsupported STM32 GPIO peripheral.
#endif
#define PIN_STPORT_MAX __STM32_PORT_MAX

//下面是中断相关
struct pin_irq_map
{
   rt_uint16_t pinbit;
   IRQn_Type irqno;
};
static const struct pin_irq_map pin_irq_map[] =
{
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0)
  {GPIO_PIN_0, EXTI0_1_IRQn},
  {GPIO_PIN_1, EXTI0_1_IRQn},
  {GPIO_PIN_2, EXTI2_3_IRQn},
  {GPIO_PIN_3, EXTI2_3_IRQn},
  {GPIO_PIN_4, EXTI4_15_IRQn},
  {GPIO_PIN_5, EXTI4_15_IRQn},
  {GPIO_PIN_6, EXTI4_15_IRQn},
  {GPIO_PIN_7, EXTI4_15_IRQn},
  {GPIO_PIN_8, EXTI4_15_IRQn},
  {GPIO_PIN_9, EXTI4_15_IRQn},
  {GPIO_PIN_10, EXTI4_15_IRQn},
  {GPIO_PIN_11, EXTI4_15_IRQn},
  {GPIO_PIN_12, EXTI4_15_IRQn},
  {GPIO_PIN_13, EXTI4_15_IRQn},
  {GPIO_PIN_14, EXTI4_15_IRQn},
  {GPIO_PIN_15, EXTI4_15_IRQn},
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5)
  {GPIO_PIN_0, EXTI0_IRQn},
  {GPIO_PIN_1, EXTI1_IRQn},
  {GPIO_PIN_2, EXTI2_IRQn},
  {GPIO_PIN_3, EXTI3_IRQn},
  {GPIO_PIN_4, EXTI4_IRQn},
  {GPIO_PIN_5, EXTI5_IRQn},
  {GPIO_PIN_6, EXTI6_IRQn},
  {GPIO_PIN_7, EXTI7_IRQn},
  {GPIO_PIN_8, EXTI8_IRQn},
  {GPIO_PIN_9, EXTI9_IRQn},
  {GPIO_PIN_10, EXTI10_IRQn},
  {GPIO_PIN_11, EXTI11_IRQn},
  {GPIO_PIN_12, EXTI12_IRQn},
  {GPIO_PIN_13, EXTI13_IRQn},
  {GPIO_PIN_14, EXTI14_IRQn},
  {GPIO_PIN_15, EXTI15_IRQn},
#elif defined(SOC_SERIES_STM32F3)
  {GPIO_PIN_0, EXTI0_IRQn},
  {GPIO_PIN_1, EXTI1_IRQn},
  {GPIO_PIN_2, EXTI2_TSC_IRQn},
  {GPIO_PIN_3, EXTI3_IRQn},
  {GPIO_PIN_4, EXTI4_IRQn},
  {GPIO_PIN_5, EXTI9_5_IRQn},
  {GPIO_PIN_6, EXTI9_5_IRQn},
  {GPIO_PIN_7, EXTI9_5_IRQn},
  {GPIO_PIN_8, EXTI9_5_IRQn},
  {GPIO_PIN_9, EXTI9_5_IRQn},
  {GPIO_PIN_10, EXTI15_10_IRQn},
  {GPIO_PIN_11, EXTI15_10_IRQn},
  {GPIO_PIN_12, EXTI15_10_IRQn},
  {GPIO_PIN_13, EXTI15_10_IRQn},
  {GPIO_PIN_14, EXTI15_10_IRQn},
  {GPIO_PIN_15, EXTI15_10_IRQn},
#else
  {GPIO_PIN_0, EXTI0_IRQn},
  {GPIO_PIN_1, EXTI1_IRQn},
  {GPIO_PIN_2, EXTI2_IRQn},
  {GPIO_PIN_3, EXTI3_IRQn},
  {GPIO_PIN_4, EXTI4_IRQn},
  {GPIO_PIN_5, EXTI9_5_IRQn},
  {GPIO_PIN_6, EXTI9_5_IRQn},
  {GPIO_PIN_7, EXTI9_5_IRQn},
  {GPIO_PIN_8, EXTI9_5_IRQn},
  {GPIO_PIN_9, EXTI9_5_IRQn},
  {GPIO_PIN_10, EXTI15_10_IRQn},
  {GPIO_PIN_11, EXTI15_10_IRQn},
  {GPIO_PIN_12, EXTI15_10_IRQn},
  {GPIO_PIN_13, EXTI15_10_IRQn},
  {GPIO_PIN_14, EXTI15_10_IRQn},
  {GPIO_PIN_15, EXTI15_10_IRQn},
#endif
};

static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
{
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
  {-1, 0, RT_NULL, RT_NULL},
};

static uint32_t pin_irq_enable_mask = 0;
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])

//get 的实现
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))
  {
    return -RT_EINVAL;
  }
  if ((name[0] != 'P') || (name[2] != '.'))
  {
    return -RT_EINVAL;
  }
  if ((name[1] >= 'A') && (name[1] <= 'Z'))
  {
    hw_port_num = (int)(name[1] - 'A');
  }
  else
  {
    return -RT_EINVAL;
  }
  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;
}

//写的实现
static void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
  GPIO_TypeDef *gpio_port;
  uint16_t gpio_pin;
  if (PIN_PORT(pin) < PIN_STPORT_MAX)
  {
    gpio_port = PIN_STPORT(pin);
    gpio_pin = PIN_STPIN(pin);
    HAL_GPIO_WritePin(gpio_port, gpio_pin, (GPIO_PinState)value);
  }
}

//读的实现
static int stm32_pin_read(rt_device_t dev, rt_base_t pin)
{
  GPIO_TypeDef *gpio_port;
  uint16_t gpio_pin;
  int value = PIN_LOW;
  if (PIN_PORT(pin) < PIN_STPORT_MAX)
  {
    gpio_port = PIN_STPORT(pin);
    gpio_pin = PIN_STPIN(pin);
    value = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
  }
  return value;
}

//mode设置
static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if (PIN_PORT(pin) >= PIN_STPORT_MAX)
  {
    return;
  }
  /* Configure GPIO_InitStructure */
  GPIO_InitStruct.Pin = PIN_STPIN(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(PIN_STPORT(pin), &GPIO_InitStruct);
}

rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
{
  rt_uint8_t i;
  for (i = 0; i < 32; i++)
  {
    if ((0x01 << i) == bit)
    {
      return i;
    }
  }
  return -1;
}

//中断相关 把pin转换为中断列表的索引号
rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
{
  rt_int32_t mapindex = bit2bitno(pinbit);
  if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
  {
    return RT_NULL;
  }
  return &pin_irq_map[mapindex];
};

//中断引脚绑定
static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
  rt_base_t level;
  rt_int32_t irqindex = -1;
  if (PIN_PORT(pin) >= PIN_STPORT_MAX)
  {
    return -RT_ENOSYS;
  }
  irqindex = bit2bitno(PIN_STPIN(pin));
  if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
  {
    return RT_ENOSYS;
  }
  level = rt_hw_interrupt_disable();
  if (pin_irq_hdr_tab[irqindex].pin == pin &&
  pin_irq_hdr_tab[irqindex].hdr == hdr &&
  pin_irq_hdr_tab[irqindex].mode == mode &&
  pin_irq_hdr_tab[irqindex].args == args)
  {
    rt_hw_interrupt_enable(level);
    return RT_EOK;
  }
  if (pin_irq_hdr_tab[irqindex].pin != -1)
  {
    rt_hw_interrupt_enable(level);
    return RT_EBUSY;
  }
  pin_irq_hdr_tab[irqindex].pin = pin;
  pin_irq_hdr_tab[irqindex].hdr = hdr;
  pin_irq_hdr_tab[irqindex].mode = mode;
  pin_irq_hdr_tab[irqindex].args = args;
  rt_hw_interrupt_enable(level);
  return RT_EOK;
}

//中断引脚绑定取消
static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
{
  rt_base_t level;
  rt_int32_t irqindex = -1;
  if (PIN_PORT(pin) >= PIN_STPORT_MAX)
  {
    return -RT_ENOSYS;
  }
  irqindex = bit2bitno(PIN_STPIN(pin));
  if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
  {
    return RT_ENOSYS;
  }
  level = rt_hw_interrupt_disable();
  if (pin_irq_hdr_tab[irqindex].pin == -1)
  {
    rt_hw_interrupt_enable(level);
    return RT_EOK;
  }
  pin_irq_hdr_tab[irqindex].pin = -1;
  pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
  pin_irq_hdr_tab[irqindex].mode = 0;
  pin_irq_hdr_tab[irqindex].args = RT_NULL;
  rt_hw_interrupt_enable(level);
  return RT_EOK;
}

//中断允许
static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
rt_uint32_t enabled)
{
  const struct pin_irq_map *irqmap;
  rt_base_t level;
  rt_int32_t irqindex = -1;
  GPIO_InitTypeDef GPIO_InitStruct;
  if (PIN_PORT(pin) >= PIN_STPORT_MAX)
  {
    return -RT_ENOSYS;
  }
  if (enabled == PIN_IRQ_ENABLE)
  {
    irqindex = bit2bitno(PIN_STPIN(pin));
    if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
    {
      return RT_ENOSYS;
    }
    level = rt_hw_interrupt_disable();
    if (pin_irq_hdr_tab[irqindex].pin == -1)
    {
      rt_hw_interrupt_enable(level);
      return RT_ENOSYS;
    }
    irqmap = &pin_irq_map[irqindex];
    /* Configure GPIO_InitStructure */
    GPIO_InitStruct.Pin = PIN_STPIN(pin);
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    switch (pin_irq_hdr_tab[irqindex].mode)
    {
      case PIN_IRQ_MODE_RISING:
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
        break;
      case PIN_IRQ_MODE_FALLING:
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
        break;
      case PIN_IRQ_MODE_RISING_FALLING:
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
        break;
     }
     HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);
     HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);
     HAL_NVIC_EnableIRQ(irqmap->irqno);
     pin_irq_enable_mask |= irqmap->pinbit;
     rt_hw_interrupt_enable(level);
   }
   else if (enabled == PIN_IRQ_DISABLE)
   {
     irqmap = get_pin_irq_map(PIN_STPIN(pin));
     if (irqmap == RT_NULL)
     {
       return RT_ENOSYS;
     }
     level = rt_hw_interrupt_disable();
     HAL_GPIO_DeInit(PIN_STPORT(pin), PIN_STPIN(pin));
     pin_irq_enable_mask &= ~irqmap->pinbit;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
     if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1))
     {
       if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1)))
       {
         HAL_NVIC_DisableIRQ(irqmap->irqno);
       }
     }
     else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3))
     {
       if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3)))
       {
         HAL_NVIC_DisableIRQ(irqmap->irqno);
       }
     }
     else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15))
     {
       if (!(pin_irq_enable_mask & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
     {
       HAL_NVIC_DisableIRQ(irqmap->irqno);
     }
   }
   else
   {
     HAL_NVIC_DisableIRQ(irqmap->irqno);
   }
#else
   if ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9))
   {
     if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9)))
     {
       HAL_NVIC_DisableIRQ(irqmap->irqno);
     }
   }
   else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15))
   {
     if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
     {
       HAL_NVIC_DisableIRQ(irqmap->irqno);
     }
   }
   else
   {
     HAL_NVIC_DisableIRQ(irqmap->irqno);
   }
#endif
   rt_hw_interrupt_enable(level);
  }
  else
  {
    return -RT_ENOSYS;
  }
  return RT_EOK;
}

//实际实现函数与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,
  stm32_pin_get,
};

 

//中断或中断上升 下降缘回调函数

rt_inline void pin_irq_hdr(int irqno)
{
  if (pin_irq_hdr_tab[irqno].hdr)
  {
    pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
  }
}

//中断或中断上升 下降缘回调
#if defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1)
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
  pin_irq_hdr(bit2bitno(GPIO_Pin));
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
  pin_irq_hdr(bit2bitno(GPIO_Pin));
}
#else
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  pin_irq_hdr(bit2bitno(GPIO_Pin));
}
#endif

//中断处理  这部分代码比较多,其实就是用了三个函数:

  rt_interrupt_enter();  通知内核进入中断 内核会做相应事情
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_xx); 处理EXTI中断请求(GPIO_Pin: 指定连接EXTI线的引脚)

  一般不修改这个函数,当需要回调时,可以在用户文件中实现 HAL_GPIO_EXTI_Callback。
  rt_interrupt_leave(); 通知内核离开中断 内核会做相应事情

//中断处理
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32L0)
void EXTI0_1_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  rt_interrupt_leave();
}

void EXTI2_3_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
  rt_interrupt_leave();
}
void EXTI4_15_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
  rt_interrupt_leave();
}
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32U5)
void EXTI0_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  rt_interrupt_leave();
}

void EXTI1_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  rt_interrupt_leave();
}
void EXTI2_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  rt_interrupt_leave();
}
void EXTI3_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
  rt_interrupt_leave();
}

void EXTI4_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
  rt_interrupt_leave();
}

void EXTI5_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
  rt_interrupt_leave();
}
void EXTI6_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  rt_interrupt_leave();
}
void EXTI7_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  rt_interrupt_leave();
}
void EXTI8_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  rt_interrupt_leave();
}
void EXTI9_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  rt_interrupt_leave();
}
void EXTI10_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
  rt_interrupt_leave();
}
void EXTI11_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
  rt_interrupt_leave();
}
void EXTI12_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
  rt_interrupt_leave();
}
void EXTI13_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  rt_interrupt_leave();
}
void EXTI14_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  rt_interrupt_leave();
}
void EXTI15_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
  rt_interrupt_leave();
}
#else
void EXTI0_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  rt_interrupt_leave();
}
void EXTI1_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  rt_interrupt_leave();
}
void EXTI2_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  rt_interrupt_leave();
}
void EXTI3_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
  rt_interrupt_leave();
}
void EXTI4_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
  rt_interrupt_leave();
}
void EXTI9_5_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  rt_interrupt_leave();
}
void EXTI15_10_IRQHandler(void)
{
  rt_interrupt_enter();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
  rt_interrupt_leave();
}
#endif

//PIN初始化 时钟并注册设备 下面程序看起来多 实际上就是用__HAL_RCC_GPIOX_CLK_ENABLE();设置时钟,用rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);对pin设备注册

//PIN初始化 时钟并注册设备
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
#if defined(__HAL_RCC_GPIOF_CLK_ENABLE)
  __HAL_RCC_GPIOF_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOG_CLK_ENABLE)
#ifdef SOC_SERIES_STM32L4
  HAL_PWREx_EnableVddIO2();
#endif
  __HAL_RCC_GPIOG_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOH_CLK_ENABLE)
  __HAL_RCC_GPIOH_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOI_CLK_ENABLE)
  __HAL_RCC_GPIOI_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOJ_CLK_ENABLE)
  __HAL_RCC_GPIOJ_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOK_CLK_ENABLE)
  __HAL_RCC_GPIOK_CLK_ENABLE();
#endif
  return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
}

 

由此可见gpio.c是我们的重点,如果移植驱动,这里才是需要我们动手实现的内容。

理解有限,谢谢。

本帖最后由 damiaa 于 2023-8-29 09:30 编辑

回复评论 (3)

转了好几圈,最终生成汇编,有没有这么复杂吗,要不效率低下呀。
点赞  2023-8-28 18:49
lugl4313820 发表于 2023-8-28 18:49 转了好几圈,最终生成汇编,有没有这么复杂吗,要不效率低下呀。

操作系统就是这么麻烦。不过PIN  如果是只是按键和led的话不用驱动。

按键就直接用hal库读就行,led点亮也是直接用hal库函数点亮。

只是习惯的所有驱动都做出了驱动。方便调用。移植好了还是方便。没移植好就不方便了。

效率 低下,这是真的。所有操作系统都效率低下。

本帖最后由 damiaa 于 2023-8-28 21:55 编辑
点赞  2023-8-28 21:53
引用: damiaa 发表于 2023-8-28 21:53 操作系统就是这么麻烦。不过PIN  如果是只是按键和led的话不用驱动。 按键就直接用hal库读就行 ...

感RTT,如果官方给了驱动,那是真的方便,如果官方没移植好驱动,那是真不方便!

点赞  2023-8-28 23:36
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复