KSDK_1.1.0 之hardware_init()函数
来源:互联网 发布:网络牛牛赌博犯法 编辑:程序博客网 时间:2024/04/28 00:29
硬件平台TWR_K60D100M
先来分析main()里的第一个函数hardware_init():
该函数主要完成了打开clock gate 和进行板载GPIO的pinmux设置
void hardware_init(void) { uint8_t i; /* enable clock for PORTs */ for (i = 0; i < HW_PORT_INSTANCE_COUNT; i++) { CLOCK_SYS_EnablePortClock(i); } /* Setup board clock source. */ g_xtal0ClkFreq = 50000000U; g_xtalRtcClkFreq = 32768U; for (i = 0; i < HW_PORT_INSTANCE_COUNT; i++) { configure_gpio_pins(i); }}
这个函数会调用CLOCK_SYS_EnablePortClock()和configure_gpio_pins()两个函数,CLOCK_SYS_EnablePortClock()定义如下:
/*FUNCTION********************************************************************** * * Function Name : CLOCK_SYS_EnablePortClock * Description : Enable the clock for PORT module * This function enables the clock for PORT module * *END**************************************************************************/void CLOCK_SYS_EnablePortClock(uint32_t instance){ assert(instance < sizeof(portGateTable)/sizeof(portGateTable[0])); SIM_HAL_EnableClock(SIM_BASE, portGateTable[instance]);}
其中portGateTable定义如下:
/* PORT instance table. */static const sim_clock_gate_name_t portGateTable[] ={ kSimClockGatePortA, kSimClockGatePortB, kSimClockGatePortC, kSimClockGatePortD, kSimClockGatePortE};
sim_clock_gate_name_t 是一个枚举类型,其定义如下
/*! @brief Clock gate name used for SIM_HAL_EnableClock/SIM_HAL_DisableClock. */typedef enum _sim_clock_gate_name{ kSimClockGateUart4 = FSL_SIM_SCGC_BIT(1U, 10U), kSimClockGateUart5 = FSL_SIM_SCGC_BIT(1U, 11U), kSimClockGateEnet0 = FSL_SIM_SCGC_BIT(2U, 0U), kSimClockGateDac0 = FSL_SIM_SCGC_BIT(2U, 12U), kSimClockGateDac1 = FSL_SIM_SCGC_BIT(2U, 13U), kSimClockGateRnga0 = FSL_SIM_SCGC_BIT(3U, 0U), kSimClockGateFlexcan1 = FSL_SIM_SCGC_BIT(3U, 4U), kSimClockGateSpi2 = FSL_SIM_SCGC_BIT(3U, 12U), kSimClockGateSdhc0 = FSL_SIM_SCGC_BIT(3U, 17U), kSimClockGateFtm2 = FSL_SIM_SCGC_BIT(3U, 24U), kSimClockGateAdc1 = FSL_SIM_SCGC_BIT(3U, 27U), kSimClockGateEwm0 = FSL_SIM_SCGC_BIT(4U, 1U), kSimClockGateCmt0 = FSL_SIM_SCGC_BIT(4U, 2U), kSimClockGateI2c0 = FSL_SIM_SCGC_BIT(4U, 6U), kSimClockGateI2c1 = FSL_SIM_SCGC_BIT(4U, 7U), kSimClockGateUart0 = FSL_SIM_SCGC_BIT(4U, 10U), kSimClockGateUart1 = FSL_SIM_SCGC_BIT(4U, 11U), kSimClockGateUart2 = FSL_SIM_SCGC_BIT(4U, 12U), kSimClockGateUart3 = FSL_SIM_SCGC_BIT(4U, 13U), kSimClockGateUsbfs0 = FSL_SIM_SCGC_BIT(4U, 18U), kSimClockGateCmp = FSL_SIM_SCGC_BIT(4U, 19U), kSimClockGateVref0 = FSL_SIM_SCGC_BIT(4U, 20U), kSimClockGateLlwu0 = FSL_SIM_SCGC_BIT(4U, 28U), kSimClockGateLptmr0 = FSL_SIM_SCGC_BIT(5U, 0U), kSimClockGateTsi0 = FSL_SIM_SCGC_BIT(5U, 5U), kSimClockGatePortA = FSL_SIM_SCGC_BIT(5U, 9U), kSimClockGatePortB = FSL_SIM_SCGC_BIT(5U, 10U), kSimClockGatePortC = FSL_SIM_SCGC_BIT(5U, 11U), kSimClockGatePortD = FSL_SIM_SCGC_BIT(5U, 12U), kSimClockGatePortE = FSL_SIM_SCGC_BIT(5U, 13U), kSimClockGateFtf0 = FSL_SIM_SCGC_BIT(6U, 0U), kSimClockGateDmamux0 = FSL_SIM_SCGC_BIT(6U, 1U), kSimClockGateFlexcan0 = FSL_SIM_SCGC_BIT(6U, 4U), kSimClockGateSpi0 = FSL_SIM_SCGC_BIT(6U, 12U), kSimClockGateSpi1 = FSL_SIM_SCGC_BIT(6U, 13U), kSimClockGateSai0 = FSL_SIM_SCGC_BIT(6U, 15U), kSimClockGateCrc0 = FSL_SIM_SCGC_BIT(6U, 18U), kSimClockGateUsbdcd0 = FSL_SIM_SCGC_BIT(6U, 21U), kSimClockGatePdb0 = FSL_SIM_SCGC_BIT(6U, 22U), kSimClockGatePit0 = FSL_SIM_SCGC_BIT(6U, 23U), kSimClockGateFtm0 = FSL_SIM_SCGC_BIT(6U, 24U), kSimClockGateFtm1 = FSL_SIM_SCGC_BIT(6U, 25U), kSimClockGateAdc0 = FSL_SIM_SCGC_BIT(6U, 27U), kSimClockGateRtc0 = FSL_SIM_SCGC_BIT(6U, 29U), kSimClockGateFlexbus0 = FSL_SIM_SCGC_BIT(7U, 0U), kSimClockGateDma0 = FSL_SIM_SCGC_BIT(7U, 1U), kSimClockGateMpu0 = FSL_SIM_SCGC_BIT(7U, 2U),#if (defined(DOXYGEN_OUTPUT) && (DOXYGEN_OUTPUT))} sim_clock_gate_name_k60d10_t;#else} sim_clock_gate_name_t;
以kSimClockGatePortA为例, kSimClockGatePortA = FSL_SIM_SCGC_BIT(5U, 9U), PORTA的Clock Gate位位于SIM_SCG5的第9位,FSL_SIM_SCGC_BIT的两个参数看起来与之有关系。
#define FSL_SIM_SCGC_BIT(SCGCx, n) (((SCGCx-1U)<<5U) + n)
这个宏定义代表什么含义呢?
它表示PORTA的clock gate 位(也就是SIM_SCGC5的第9位)相对与SIM_SCGC1起始位置的位数。<<5 就是乘以32的意思。
于是乎kSimClockGatePortA = (((5-1U)<<5U) + 9)=0x89
紧接着调用 SIM_HAL_EnableClock(SIM_BASE, portGateTable[instance]);也就是 SIM_HAL_EnableClock(SIM_BASE, kSimClockGatePortA);第一个参数是
SIM模块的基地址,第二个参数是PORTA gate 使能位相对SIM_SCGC1的位数。
这个函数定义如下:
/*! * @brief Enable the clock for specific module. * * This function enables the clock for specific module. * * @param baseAddr Base address for current SIM instance. * @param name Name of the module to enable. */static inline void SIM_HAL_EnableClock(uint32_t baseAddr, sim_clock_gate_name_t name){ BW_SIM_SCGC_BIT(baseAddr, name, 1U);}
它调用 BW_SIM_SCGC_BIT(baseAddr, name, 1U)这个,BW_SIM_SCGC_BIT这个宏的定义如下:
#define BW_SIM_SCGC_BIT(x, n, v) (BITBAND_ACCESS32(HW_SIM_SCGC_BIT_ADDR((x), (n)), BP_SIM_SCGC_BIT(n)) = (uint32_t)(v))
这里面又调用了一个宏BITBAND_ACCESS32,这个宏非常关键。
/** * @brief Macro to access a single bit of a 32-bit peripheral register (bit band region * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. * @param Reg Register to access. * @param Bit Bit number to access. * @return Value of the targeted bit in the bit band region. */#define BITBAND_ACCESS32(Reg,Bit) (*((uint32_t volatile*)(0x42000000u + (32u*((uint32_t)(Reg) - (uint32_t)0x40000000u)) + (4u*((uint32_t)(Bit))))))
这个宏定义是为了获取bit band 区域中的某个位的值。实现的方式是通过访问别名区的地址来实现的。别名区的地址可以通过0x42000000+32*(reg-0x40000000)+4*bit来实现。其中reg就是寄存器的地址。 bit是寄存器中的bit 位数(0~32)。
位段操作可参考:Bit_nand介绍
再来看看BITBAND_ACCESS32具体的两个参数值,分别为:HW_SIM_SCGC_BIT_ADDR((x), (n))和BP_SIM_SCGC_BIT(n),HW_SIM_SCGC_BIT_ADDR(x,n) 定义如下
#define HW_SIM_SCGC_BIT_ADDR(x, n) (HW_SIM_SCGC1_ADDR(x) + ((((uint32_t)(n) >> 5) - 0U) * 4U))#define HW_SIM_SCGC1_ADDR(x) ((uint32_t)(x) + 0x1028U)
0x4004_7000+0x1028=0x4004_8028得到的是SIM_SCGC1的地址,((((uint32_t)(n) >> 5) - 0U) * 4U))这个的含义是n先除以32,再乘以4,得到的结果是SIM_SCGC1应该加的地址增加数,对于PORTA,就得到SIM_SCG4的地址4004_8038
再看BP_SIM_SCGC_BIT(n)
#define BP_SIM_SCGC_BIT(n) ((uint32_t)(n) & ((1U << 5) - 1U))
我的目标是得到0x89的后五位(0~31),方法是与上0b11111, ((1U << 5) - 1U)) =31,恰好符和。
这样就得到SIM_SCGC5的地址和bit位数。Bitnand再一操作就可以对那位进行赋值。
说了这么多就是完成了对SIM_SCGC5的第9位赋1,结果整的这么复杂。在实际使用中如果你想打开UART0的Clock gate,需要做的是在portGateTable加入kSimClockGateUart0
/* PORT instance table. */static const sim_clock_gate_name_t portGateTable[] ={ kSimClockGatePortA, kSimClockGatePortB, kSimClockGatePortC, kSimClockGatePortD, kSimClockGatePortE, kSimClockGateUart0 };
HW_PORT_INSTANCE_COUNT设置为6即可。
本质也就是调用了HAL层的SIM_HAL_EnableClock(uint32_t baseAddr, sim_clock_gate_name_t name),直接调用SIM_HAL_EnableClock(SIM_BASE,kSimClockGateUart0)也可以。
- KSDK_1.1.0 之hardware_init()函数
- 函数之分析函数
- 函数之重载函数
- 函数之内联函数
- oracle函数之转换函数
- 函数模版之整数函数
- mysql函数之比较函数
- 分析函数之窗口函数
- 分析函数之窗口函数
- c函数之【时间函数】
- c函数之【数据结构函数】
- c函数之【随机数函数】
- c函数之【信号函数】
- c函数之【记录函数】
- c函数之【环境变量函数】
- c函数之【动态函数】
- c函数之【其他函数】
- SQL函数之日期函数
- 11212 - Editing a Book
- UVa-213Message Decoding
- 12325 Zombie's Treasure Chest
- Android 4.2 Documentation
- 最长回文子串
- KSDK_1.1.0 之hardware_init()函数
- 黑盒测试用例设计模式-因果图
- oracle使用指南
- JavaScript实现Tab选项卡特效代码总结
- Codeforces 520E. Pluses everywhere 数学
- redhat6.6+nginx+apache+subversion搭建svn服务器
- O(n)回文子串算法
- (7)栈 队列 优先级队列 《java数据结构与算法》一书第四章读书笔记。
- SSH2 DAO注入sessionfactory的方式汇总