MQX3.8源代码分析:GPIO(2)时钟门控制 gpio_cpu_init()

在bsp包初始化的过程中,系统会根据用户在user_config.h文件中的宏定义,选择性地初始化gpio。

1、文件Init_bsp.c  (source\bsp\twrk60n512)中,代码:

    /* Install the GPIO driver */
 #if BSPCFG_ENABLE_GPIODEV
     _io_gpio_install("gpio:");
 #endif
 


2、文件Io_gpio.c (source\io\gpio),代码:

/*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 */
 


3、文件Io_gpio_kgpio.c 文件(source\io\gpio\kgpio)中,代码:

/*FUNCTION*****************************************************************
 * 
 * Function Name    : gpio_cpu_install
 * Returned Value   : IO_OK
 * Comments         :
 *    Performs basic initialization specific to board
 *
 *END*********************************************************************/
 
 _mqx_int gpio_cpu_init()
 { /* Body */
 
     _bsp_gpio_io_init();    
     return IO_OK;
 } /* Endbody */
 


4、文件Init_gpio.c(source\bsp\twrk60n512)中,代码:

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _bsp_gpio_io_init
 * Returned Value   : MQX_OK or -1
 * Comments         :
 *    This function performs BSP-specific initialization related to GPIO
 *
 *END*----------------------------------------------------------------------*/
 
 _mqx_int _bsp_gpio_io_init
 (
     void
 )
 {
     /* Enable clock gating to all ports */
     SIM_SCGC5 |=   SIM_SCGC5_PORTA_MASK \
                  | SIM_SCGC5_PORTB_MASK \
                  | SIM_SCGC5_PORTC_MASK \
                  | SIM_SCGC5_PORTD_MASK \
                  | SIM_SCGC5_PORTE_MASK;
 
     return MQX_OK;
 }
 


5、文件MK60DZ10.h(source\psp\cortex)中,代码:

#define SIM_SCGC5                                SIM_SCGC5_REG(SIM_BASE_PTR)
#define SIM_SCGC5_REG(base)                      ((base)->SCGC5)
/* SIM - Peripheral instance base addresses */
 /** Peripheral SIM base pointer */
 #define SIM_BASE_PTR                             ((SIM_MemMapPtr)0x40047000u)
 
/** SIM - Peripheral register structure */
 typedef struct SIM_MemMap {
   uint32_t SOPT1;                                  /**< System Options Register 1, offset: 0x0 */
   uint8_t RESERVED_0[4096];
   uint32_t SOPT2;                                  /**< System Options Register 2, offset: 0x1004 */
   uint8_t RESERVED_1[4];
   uint32_t SOPT4;                                  /**< System Options Register 4, offset: 0x100C */
   uint32_t SOPT5;                                  /**< System Options Register 5, offset: 0x1010 */
   uint32_t SOPT6;                                  /**< System Options Register 6, offset: 0x1014 */
   uint32_t SOPT7;                                  /**< System Options Register 7, offset: 0x1018 */
   uint8_t RESERVED_2[8];
   uint32_t SDID;                                   /**< System Device Identification Register, offset: 0x1024 */
   uint32_t SCGC1;                                  /**< System Clock Gating Control Register 1, offset: 0x1028 */
   uint32_t SCGC2;                                  /**< System Clock Gating Control Register 2, offset: 0x102C */
   uint32_t SCGC3;                                  /**< System Clock Gating Control Register 3, offset: 0x1030 */
   uint32_t SCGC4;                                  /**< System Clock Gating Control Register 4, offset: 0x1034 */
   uint32_t SCGC5;                                  /**< System Clock Gating Control Register 5, offset: 0x1038 */
   uint32_t SCGC6;                                  /**< System Clock Gating Control Register 6, offset: 0x103C */
   uint32_t SCGC7;                                  /**< System Clock Gating Control Register 7, offset: 0x1040 */
   uint32_t CLKDIV1;                                /**< System Clock Divider Register 1, offset: 0x1044 */
   uint32_t CLKDIV2;                                /**< System Clock Divider Register 2, offset: 0x1048 */
   uint32_t FCFG1;                                  /**< Flash Configuration Register 1, offset: 0x104C */
   uint32_t FCFG2;                                  /**< Flash Configuration Register 2, offset: 0x1050 */
   uint32_t UIDH;                                   /**< Unique Identification Register High, offset: 0x1054 */
   uint32_t UIDMH;                                  /**< Unique Identification Register Mid-High, offset: 0x1058 */
   uint32_t UIDML;                                  /**< Unique Identification Register Mid Low, offset: 0x105C */
   uint32_t UIDL;                                   /**< Unique Identification Register Low, offset: 0x1060 */
 } volatile *SIM_MemMapPtr;
 

分析1:

地址0x40047000u是SIM模块在K60整个地址空间中的基地址,SIM模块占用一块连续的存储空间,作为自己的操作寄存器,为了操作方便,头文件中把这些寄存器定义成了一个空间结构体。这样,只要基地址正确,结构体中变量正好对应SIM的各个寄存器地址,当然也包括一些保留字节。

  该地址定义位于文件K60P100M100SF2RM.pdf 文件的12.1Memory map and register definition一节中。部分截图如下:




可以对照该结构体和文档地址空间定义进行分析理解。((SIM_MemMapPtr)0x40047000u)语句对物理地址进行了强制类型转换,然后根据结构体空间的顺序紧凑性,就可以得出:SIM_SCGC5_REG(SIM_BASE_PTR)语句就是操作了SCGC5寄存器,给里边的相应位置数操作。


6、文件MK60DZ10.h(source\psp\cortex)中,代码:

#define SIM_SCGC5_PORTA_MASK                     0x200u
 #define SIM_SCGC5_PORTA_SHIFT                    9
 #define SIM_SCGC5_PORTB_MASK                     0x400u
 #define SIM_SCGC5_PORTB_SHIFT                    10
 #define SIM_SCGC5_PORTC_MASK                     0x800u
 #define SIM_SCGC5_PORTC_SHIFT                    11
 #define SIM_SCGC5_PORTD_MASK                     0x1000u
 #define SIM_SCGC5_PORTD_SHIFT                    12
 #define SIM_SCGC5_PORTE_MASK                     0x2000u
 #define SIM_SCGC5_PORTE_SHIFT                    13


分析2:

从文档12.2.12 System Clock Gating Control Register 5 (SIM_SCGC5) 中可以看到,这些宏定义分别对应着ABCDE端口的始终脉冲门。在这里是打开了这些端口的时钟脉冲门,进行初始化。

我大概猜测一下:这些脉冲门,主要是控制给对应模块的时钟信号供给,当关闭脉冲门,就相当于关闭信号来源,那么就关闭了对应端口,可以达到省电的目的。为什么GPIO口还需要这些呢,其实当GPIO不管是输入还是输出,都有脉冲进行控制。当输出时,这些脉冲门信号供给,决定了你输出信号的响应时间,当信号频率越高,那么响应时间越短;当输入时,也是一样的道理,在微观上,当有外部信号过来,必须等到该引脚内部有脉冲输入的时候,他才能检测到你的外部信号过来,这里边同样有响应时间的问题。除了可以选择打开关闭,是不是还要有给GPIO口设置参考频率的寄存器,暂时还没有发现,不过我估计即便这个芯片没有,别的芯片可能也会有。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值