MQX3.8源代码分析:GPIO(1)模块初接触
mqx3.8是飞思卡尔芯片专用的类linux操作系统,这里以kenitis系列ARM cortex M4内核的MK60N512为专属芯片来进行深入解读。操作GPIO口的代码如下:GPIO_PIN_STRUCT pins1[] ={BSP_LED2,GPIO_LIST_END};MQX_FILE_PTR po
·
mqx3.8是飞思卡尔芯片专用的类linux操作系统,这里以kenitis系列ARM cortex M4内核的MK60N512为专属芯片来进行深入解读。
操作GPIO口的代码如下:
GPIO_PIN_STRUCT pins1[] =
{
BSP_LED2,
GPIO_LIST_END
};
MQX_FILE_PTR port_file1 = NULL;
/* open file containing pin1 set of pins/signals */
if (NULL == (port_file1 = fopen("gpio:write", (char_ptr) &pins1 )))
{
printf("Opening file1 GPIO for pins1 failed.\n");
_task_block();
}
/* write logical 1 to all signals in the file (fast) */
if (IO_OK != ioctl(port_file1, GPIO_IOCTL_WRITE_LOG1, NULL ))
{
printf("Writing to whole file1 failed.\n");
_task_block();
}
分析:pins1数组定义了要使用的io口序号;“gpio:write”表示以gpio口的方式打开该引脚,因为在芯片中,几乎每个引脚都可以进行多路复用,需要明确的指出打开方式;fopen函数以用户指定的方式打开并初始化特定引脚,并且返回文件指针。
关键点就是fopen函数是多个模块打开函数的统一入口,在该函数内部又有多路分支,打开对应的模块,这也是mqx与linux相似的地方。
进一步追踪发现(fio.h):
#define fopen _io_fopen
extern MQX_FILE_PTR _io_fopen(const char _PTR_, const char _PTR_);
那么:port_file1 = fopen("gpio:write", (char_ptr) &pins1 );等价于port_file1 = _io_fopen("gpio:write",(char_ptr) &pins1);_io_fopen函数的具体实现位于io_fopen.c中,同理其他相关函数也都在以各自函数名命名的单个文档中。我们之所以能够轻松的调用函数操作io口,mqx底层肯定做了其他相关准备工作。打开io_gpio.c文档,有函数如下:
这就是gpio驱动安装函数,由mqx调用,负责安装open、close、read、write、ioctl函数而我们平常的用到的函数,在内部都是调用的这些函数,这些函数在mqx内核进行了注册。
那什么时候进行gpio驱动的注册呢?打开init_bsp.c文件,在“ uint_32 _bsp_enable_card(void)”函数中
当我们把BSPCFG_ENABLE_GPIODEW置为0,GPIO模块便不再被加载。这样做的好处是,编译内核时,可以去掉不必要的模块,节省空间。
最后把目光定位在了uer_config.h中,该文件可以由用户修改,决定模块注册情况。
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name : _io_gpio_install
* Returned Value : _mqx_uint a task error code or MQX_OK
* Comments :
* Install a gpio driver.
*
*END*----------------------------------------------------------------------*/
_mqx_uint _io_gpio_install
(
/* [IN] A string that identifies the device for fopen */
/* input values are those identifiers defined in io_gpio.h file */
char_ptr identifier
)
{ /* Body */
if (IO_OK == gpio_cpu_init())
return _io_dev_install(identifier,
_io_gpio_open,
_io_gpio_close,
_io_gpio_read,
_io_gpio_write,
gpio_cpu_ioctl,
NULL);
return (_mqx_uint)IO_ERROR;
} /* Endbody */
这就是gpio驱动安装函数,由mqx调用,负责安装open、close、read、write、ioctl函数而我们平常的用到的函数,在内部都是调用的这些函数,这些函数在mqx内核进行了注册。
那什么时候进行gpio驱动的注册呢?打开init_bsp.c文件,在“ uint_32 _bsp_enable_card(void)”函数中
/* Install the GPIO driver */
#if BSPCFG_ENABLE_GPIODEV
_io_gpio_install("gpio:");
#endif
这个预处理标志是不是眼熟,他就是user_config.h中定义的宏。这些宏负责在mqx的bsp模块编译时,选择性的加载合适的模块。
当我们把BSPCFG_ENABLE_GPIODEW置为0,GPIO模块便不再被加载。这样做的好处是,编译内核时,可以去掉不必要的模块,节省空间。
最后把目光定位在了uer_config.h中,该文件可以由用户修改,决定模块注册情况。
更多推荐
已为社区贡献2条内容
所有评论(0)