@@ -1315,26 +1315,23 @@ CMSIS is an ARM standard, and since CMSIS headers are supplied by the MCU
1315
1315
vendor, they are the source of authority. Therefore, using vendor
1316
1316
headers is a preferred way, rather than writing definitions manually.
1317
1317
1318
- In this section, we will replace our API functions in the `mcu.h` by the
1319
- CMSIS vendor header, and leave the rest of the firmware intact.
1320
-
1321
- STM32 CMSIS headers for F4 family can be found at
1322
- https://github.com/STMicroelectronics/cmsis_device_f4 repo. From there,
1323
- copy the following files into our firmware directory,
1324
- [step-5-cmsis](step-5-cmsis):
1325
- - [stm32f429xx.h](https://raw.githubusercontent.com/STMicroelectronics/cmsis_device_f4/master/Include/stm32f429xx.h)
1326
- - [system_stm32f4xx.h](https://raw.githubusercontent.com/STMicroelectronics/cmsis_device_f4/master/Include/system_stm32f4xx.h)
1327
-
1328
- Those two files depend on a standard ARM CMSIS includes, download them too:
1329
- - [core_cm4.h](https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF4/master/Drivers/CMSIS/Core/Include/core_cm4.h)
1330
- - [cmsis_gcc.h](https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF4/master/Drivers/CMSIS/Core/Include/cmsis_gcc.h)
1331
- - [cmsis_version.h](https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF4/master/Drivers/CMSIS/Core/Include/cmsis_version.h)
1332
- - [cmsis_compiler.h](https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF4/master/Drivers/CMSIS/Core/Include/cmsis_compiler.h)
1333
- - [mpu_armv7.h](https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF4/master/Drivers/CMSIS/Core/Include/mpu_armv7.h)
1334
-
1335
- From the `mcu.h`, remove all peripheral API and definitions, and leave only
1336
- standard C inludes, vendor CMSIS include, defines to PIN, BIT, FREQ, and
1337
- `timer_expired()` helper function:
1318
+ There are two sets of CMSIS headers:
1319
+ - First, there are ARM Core CMSIS headers. They describe ARM core,
1320
+ and published by ARM on github: https://github.com/ARM-software/CMSIS_5
1321
+ - Second, there are MCU vendor CMSIS headers. They describe MCU peripherals,
1322
+ and published by the MCU vendor. In our case, ST publishes them at
1323
+ https://github.com/STMicroelectronics/cmsis_device_f4
1324
+
1325
+ We can pull those headers by a simple Makefile snippet:
1326
+
1327
+ The ST CMSIS package also provides startup files for all their MCUs. We
1328
+ can use those instead of hand-writing the startup.c. The ST-provided startup
1329
+ file calls `SystemInit()` function, so we define it in the `main.c`.
1330
+
1331
+ Now, let' s replace our API functions in the ` mcu.h` using CMSIS definitions,
1332
+ and leave the rest of the firmware intact. From the ` mcu.h` , remove all
1333
+ peripheral API and definitions, and leave only standard C inludes, vendor CMSIS
1334
+ include, defines to PIN, BIT, FREQ, and `timer_expired ()` helper function:
1338
1335
1339
1336
` ` ` c
1340
1337
# pragma once
@@ -1366,38 +1363,12 @@ If we try to rebuild the firmware - `make clean build`, then GCC will fail
1366
1363
complaining about missing ` systick_init()` , ` GPIO_MODE_OUTPUT` , ` uart_init()` ,
1367
1364
and ` UART3` . Let' s add those using STM32 CMSIS files.
1368
1365
1369
- Let' s start from `systick_init()`. The `core_cm4.h` header defines
1370
- `SysTick_Type` structure which is identical to our `struct systick`, and has
1371
- an appropriate #define for `SysTick` peripheral. Also, `stm32f429xx.h` has
1372
- a `RCC_TypeDef` structure and appropriate #define for the `RCC`. Therefore
1373
- our `systick_init()` function remains almost unchanged: we only have to replace
1374
- `SYSTICK` with `SysTick`:
1375
-
1376
- ```c
1377
- static inline void systick_init(uint32_t ticks) {
1378
- if ((ticks - 1) > 0xffffff) return; // Systick timer is 24 bit
1379
- SysTick->LOAD = ticks - 1;
1380
- SysTick->VAL = 0;
1381
- SysTick->CTRL = BIT(0) | BIT(1) | BIT(2); // Enable systick
1382
- RCC->APB2ENR |= BIT(14); // Enable SYSCFG
1383
- }
1384
- ```
1366
+ Let' s start from ` systick_init()` . ARM core CMSIS headers provide a
1367
+ ` SysTick_Config()` function that does the same - so we' ll use it.
1385
1368
1386
1369
Next goes `gpio_set_mode()` function. The `stm32f429xx.h` header has
1387
1370
`GPIO_TypeDef` structure, identical to our `struct gpio`. Let' s use it:
1388
-
1389
- ` ` ` c
1390
- # define GPIO(bank) ((GPIO_TypeDef *) (GPIOA_BASE + 0x400 * (bank)))
1391
- enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG };
1392
-
1393
- static inline void gpio_set_mode(uint16_t pin, uint8_t mode) {
1394
- GPIO_TypeDef * gpio = GPIO(PINBANK(pin)); // GPIO bank
1395
- int n = PINNO(pin); // Pin number
1396
- RCC-> AHB1ENR | = BIT(PINBANK(pin)); // Enable GPIO clock
1397
- gpio-> MODER & = ~ (3U << (n * 2)); // Clear existing setting
1398
- gpio->MODER |= (mode & 3) << (n * 2); // Set new mode
1399
- }
1400
- ` ` `
1371
+ https://github.com/cpq/bare-metal-programming-guide/blob/2a61ea23e44c4531b66f6508238cfc43ca7c2634/step-5-cmsis/mcu.h#L32-L41
1401
1372
1402
1373
The ` gpio_set_af()` and ` gpio_write()` functions is also trivial -
1403
1374
simply replace ` struct gpio` with ` GPIO_TypeDef` , and that' s all.
@@ -1419,15 +1390,11 @@ shows the output. Congratulations, we have adopted our firmware code to
1419
1390
use vendor CMSIS header files. Now let' s reorganise the repository a bit
1420
1391
by moving all standard files into `include` directory and updating Makefile
1421
1392
to let GCC know about it:
1393
+ https://github.com/cpq/bare-metal-programming-guide/blob/2a61ea23e44c4531b66f6508238cfc43ca7c2634/step-5-cmsis/Makefile#L3
1422
1394
1423
- ```make
1424
- ...
1425
- -g3 -Os -ffunction-sections -fdata-sections -I. -Iinclude \
1426
- ```
1427
-
1428
- We have left with
1429
- a project template that can be reused for the future projects.
1430
- A complete project source code you can find in [step-5-cmsis](step-5-cmsis)
1395
+ We have left with a project template that can be reused for the future
1396
+ projects. A complete project source code you can find in
1397
+ [step-5-cmsis](step-5-cmsis)
1431
1398
1432
1399
1433
1400
## Setting up clocks
0 commit comments