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文档,有函数如下:
/*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中,该文件可以由用户修改,决定模块注册情况。

Logo

更多推荐