当前位置: 首页 > 科技观察

GPIO软件框架八种工作模式详解

时间:2023-03-13 18:00:33 科技观察

GPIO接上一篇,我们在上一篇文章中学习了GPIO的硬件结构,来自STM32官方手册,学习了GPIO的八种工作模式以及推挽输出和开漏输出的原理,接下来我们分别从单片机平台和Linux平台上研究GPIO的软件部分。1.单片机平台单片机平台编写GPIO口程序。以STM32F103为例,有库函数、HAL库、寄存器三种模式。使用库函数控制GPIO的方法如下:voidLED_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PB口时钟GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PB5口配置GPIO_Init_Modure=.GPIO_ModepulloutputGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度GPIO_Init(GPIOB,&GPIO_InitStructure);//根据设置的参数初始化GPIOB。初始化STM32的一个IO作为输出函数的函数。可以看出,上面初始化代码中要做的关键事情如下:①.启用指定GPIO的时钟。②.初始化GPIO,如输出功能、上拉、速度等。③.STM32的部分IO可以作为其他外设引脚使用,即IO复用。如果要将IO作为其他外设引脚使用,需要设置IO复用功能。④.最后设置GPIO输出高电平或低电平。STM32的GPIO初始化就是以上四个步骤。使用库函数操作GPIO还是很简单的。但是我们知道STM32F1系列有库函数,但是STM32F7系列没有库函数,ST公司也没有发布。STM32F7只有两种工作模式:HAL库和寄存器。2、嵌入式Linux平台先总结一下:不管是单片机还是高端ARM平台,最底层都是寄存器,硬件就是寄存器,任何封装的最底层都是运算寄存器。对于Linux系统平台,我们还有其他的方法,让它可以像单片机一样方便的操作IO口,这得益于各个Linux高手对系统底层的封装。Linux中有pinctrl和gpio子系统,它们提供API接口供你使用,让你方便的操作GPIO端口。Linux内核引入了用于PIN配置的pinctrl子系统,以及用于GPIO配置的gpio子系统。上面这句话很重要,我来详细解释一下:这里是把管脚的输入输出和控制IO口分开。pinctrl子系统管理着200个IO口的上拉下拉电阻,电流驱动能力是硬件底层的存在。如果pinctrl将一个pin初始化为普通的GPIO而不是IIC或SPI,那么我们就可以使用gpio子系统的API来操作IO口输出高低电平。传统的管脚配置方式是直接操作对应的寄存器,但这种配置方式繁琐且容易出现问题(如管脚功能冲突)。pinctrl子系统的引入就是为了解决这个问题。pinctrl子系统的主要工作如下:①.获取设备树中的pin信息。②.根据获取到的管脚信息,设置管脚的复用功能。③.根据获取到的管脚信息设置管脚的电气特性,如上拉/下拉、速度、驱动能力等。对于我们用户来说,我们只需要在设备中设置某个管脚的相关属性即可tree,等初始化工作由pinctrl子系统完成,pinctrl子系统的源代码目录为drivers/pinctrl。请注意,pinctrl子系统也是一个标准的平台驱动程序。当device匹配到driver时,会执行probe函数,但是pinctrl子系统使用arch_initcall来声明,而不是module_init(device_initcall),所以会先加载。(具体原因见后文)Linux驱动挂载顺序分析pinctrl和gpio子系统软件框架如下:pinctrlgpio可以看到两者的软件框架其实是一样的,主要是HWAbstract的具体实现层不同。你认为两者是分开的,其实不是。gpio子系统是基于pinctrl子系统的,gpio的很多API接口都是基于pinctrl子系统的功能实现的。