我是靠谱客的博主 漂亮书包,这篇文章主要介绍KSDK_1.1.0 之hardware_init()函数,现在分享给大家,希望可以做个参考。

硬件平台TWR_K60D100M
先来分析main()里的第一个函数hardware_init():
该函数主要完成了打开clock gate 和进行板载GPIO的pinmux设置

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()定义如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*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定义如下:

复制代码
1
2
3
4
5
6
7
8
9
/* PORT instance table. */ static const sim_clock_gate_name_t portGateTable[] = { kSimClockGatePortA, kSimClockGatePortB, kSimClockGatePortC, kSimClockGatePortD, kSimClockGatePortE };

sim_clock_gate_name_t 是一个枚举类型,其定义如下

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*! @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的两个参数看起来与之有关系。

复制代码
1
#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的位数。
这里写图片描述
这个函数定义如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
/*! * @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这个宏的定义如下:

复制代码
1
2
#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,这个宏非常关键

复制代码
1
2
3
4
5
6
7
8
9
/** * @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) 定义如下

复制代码
1
2
3
#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)

复制代码
1
2
#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

复制代码
1
2
3
4
5
6
7
8
9
10
/* 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()函数的全部内容,更多相关KSDK_1.1.0内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部