Bluepill STM32F103C8 support for Mbed OS 6

Bluepill board support for Mbed OS 6

Warning

It does not work with the Mbed Online Compiler.

This is an example of configuration for the Bluepill board for Mbed OS 6.

It shows how to create a custom board support based on Mbed OS and how to compile a simple Blinky application.

Note this project makes use of the full Mbed OS with RTOS included. It's possible to make changes in the configuration to support the Baremetal profile and reduce memory requirements - see this.

Example application

This repository includes blinky.cpp as an example application to demonstrate how to use the Bluepill custom board support. It's expected to work out of the box using both Mbed CLI and Mbed Studio. Note this test application can be ignored using the MBED_BLINKY_EXAMPLE macro in mbed_app.json, so you can add your own files and application on top of this project.

You can follow these steps to import and compile with Mbed CLI:

mbed import https://os.mbed.com/users/hudakz/code/mbed-os-bluepill
mbed compile -t GCC_ARM -m bluepill

Bluepill and Mbed OS version support

BluepillMbed OS (hash)Status
preview6.2.0 (#a2ada74770 )Compiles and runs ok

Updating Mbed OS

Note not every version of Mbed OS is being tested, therefore update at your own risk. Unless strictly required, you should stick to versions of Mbed OS that are known to work ok.

If you do want to udpate Mbed OS, then follow these steps:

cd mbed-os
mbed update <mbed-os hash / tag>

Testing

This application has been tested on the Bluepill board and runs ok: it blinks and LED and sends a message over the serial port (115200 bauds - see mbed_app.json).

However, it's recomended to run regression tests based on the Greentea framework whether possible (more details to be added).

Programming with STLink programming utility

The Bluepill board doesn't have a programming interface on board. However, it's easy to connect an external adapter such as the STLink/V2 and get it working in minutes.

Use the STM32 ST-Link utility to program the binary into the device.

https://os.mbed.com/media/uploads/hudakz/stlink-prog.png

Wire the Bluepill to the STLink and serial adapter as follow:

BluepillSTLink (20-pin JTAG)Serial adapter
SDWIO (CN4)7-
SWCLK (CN4)9-
RESET15-
GND4GND
TX (PA_2)-RX
RX (PA_3)-TX

ST-LINK/V2 JTAG pintout
https://os.mbed.com/media/uploads/hudakz/jtag_pinout.png

This is the pinout of the Bluepill board: /media/uploads/hudakz/stm32f103c8t6_pinout_voltage01.png

https://os.mbed.com/media/uploads/hudakz/connections.jpg

Additional example programs

Bare metal on Bluepill
Bare metal with EventQueue on Bluepill

Warning

The examples above are not meant to be compiled with the online compiler. Follow these steps to import and compile them with Mbed CLI:

mbed import Program's_URL
mbed compile -t GCC_ARM -m bluepill

Known issues

  • Please check the issues reported.
Committer:
hudakz
Date:
Wed May 13 12:25:39 2020 +0000
Revision:
0:2577a4fb6e72
Bluepill STM32F103C8 support for Mbed OS 6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:2577a4fb6e72 1 /* mbed Microcontroller Library
hudakz 0:2577a4fb6e72 2 * Copyright (c) 2006-2017 ARM Limited
hudakz 0:2577a4fb6e72 3 *
hudakz 0:2577a4fb6e72 4 * Licensed under the Apache License, Version 2.0 (the "License");
hudakz 0:2577a4fb6e72 5 * you may not use this file except in compliance with the License.
hudakz 0:2577a4fb6e72 6 * You may obtain a copy of the License at
hudakz 0:2577a4fb6e72 7 *
hudakz 0:2577a4fb6e72 8 * http://www.apache.org/licenses/LICENSE-2.0
hudakz 0:2577a4fb6e72 9 *
hudakz 0:2577a4fb6e72 10 * Unless required by applicable law or agreed to in writing, software
hudakz 0:2577a4fb6e72 11 * distributed under the License is distributed on an "AS IS" BASIS,
hudakz 0:2577a4fb6e72 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hudakz 0:2577a4fb6e72 13 * See the License for the specific language governing permissions and
hudakz 0:2577a4fb6e72 14 * limitations under the License.
hudakz 0:2577a4fb6e72 15 */
hudakz 0:2577a4fb6e72 16
hudakz 0:2577a4fb6e72 17 /**
hudakz 0:2577a4fb6e72 18 * This file configures the system clock as follows:
hudakz 0:2577a4fb6e72 19 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 20 * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
hudakz 0:2577a4fb6e72 21 * | (external 8 MHz clock) | (internal 8 MHz)
hudakz 0:2577a4fb6e72 22 * | 2- PLL_HSE_XTAL |
hudakz 0:2577a4fb6e72 23 * | (external 8 MHz xtal) |
hudakz 0:2577a4fb6e72 24 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 25 * SYSCLK(MHz) | 72 | 64
hudakz 0:2577a4fb6e72 26 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 27 * AHBCLK (MHz) | 72 | 64
hudakz 0:2577a4fb6e72 28 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 29 * APB1CLK (MHz) | 36 | 32
hudakz 0:2577a4fb6e72 30 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 31 * APB2CLK (MHz) | 72 | 64
hudakz 0:2577a4fb6e72 32 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 33 * USB capable (48 MHz precise clock) | NO | NO
hudakz 0:2577a4fb6e72 34 *-----------------------------------------------------------------------------
hudakz 0:2577a4fb6e72 35 ******************************************************************************
hudakz 0:2577a4fb6e72 36 */
hudakz 0:2577a4fb6e72 37
hudakz 0:2577a4fb6e72 38 #include "stm32f1xx.h"
hudakz 0:2577a4fb6e72 39
hudakz 0:2577a4fb6e72 40 /*!< Uncomment the following line if you need to relocate your vector Table in
hudakz 0:2577a4fb6e72 41 Internal SRAM. */
hudakz 0:2577a4fb6e72 42 /* #define VECT_TAB_SRAM */
hudakz 0:2577a4fb6e72 43 #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
hudakz 0:2577a4fb6e72 44 This value must be a multiple of 0x200. */
hudakz 0:2577a4fb6e72 45
hudakz 0:2577a4fb6e72 46
hudakz 0:2577a4fb6e72 47 /* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
hudakz 0:2577a4fb6e72 48 #define USE_PLL_HSE_EXTC (0) /* Use external clock */
hudakz 0:2577a4fb6e72 49 #define USE_PLL_HSE_XTAL (1) /* Use external xtal */
hudakz 0:2577a4fb6e72 50
hudakz 0:2577a4fb6e72 51
hudakz 0:2577a4fb6e72 52 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
hudakz 0:2577a4fb6e72 53 uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
hudakz 0:2577a4fb6e72 54 #endif
hudakz 0:2577a4fb6e72 55
hudakz 0:2577a4fb6e72 56 uint8_t SetSysClock_PLL_HSI(void);
hudakz 0:2577a4fb6e72 57
hudakz 0:2577a4fb6e72 58
hudakz 0:2577a4fb6e72 59 /**
hudakz 0:2577a4fb6e72 60 * @brief Setup the microcontroller system
hudakz 0:2577a4fb6e72 61 * Initialize the Embedded Flash Interface, the PLL and update the
hudakz 0:2577a4fb6e72 62 * SystemCoreClock variable.
hudakz 0:2577a4fb6e72 63 * @note This function should be used only after reset.
hudakz 0:2577a4fb6e72 64 * @param None
hudakz 0:2577a4fb6e72 65 * @retval None
hudakz 0:2577a4fb6e72 66 */
hudakz 0:2577a4fb6e72 67 void SystemInit (void)
hudakz 0:2577a4fb6e72 68 {
hudakz 0:2577a4fb6e72 69 /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
hudakz 0:2577a4fb6e72 70 /* Set HSION bit */
hudakz 0:2577a4fb6e72 71 RCC->CR |= 0x00000001U;
hudakz 0:2577a4fb6e72 72
hudakz 0:2577a4fb6e72 73 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
hudakz 0:2577a4fb6e72 74 #if !defined(STM32F105xC) && !defined(STM32F107xC)
hudakz 0:2577a4fb6e72 75 RCC->CFGR &= 0xF8FF0000U;
hudakz 0:2577a4fb6e72 76 #else
hudakz 0:2577a4fb6e72 77 RCC->CFGR &= 0xF0FF0000U;
hudakz 0:2577a4fb6e72 78 #endif /* STM32F105xC */
hudakz 0:2577a4fb6e72 79
hudakz 0:2577a4fb6e72 80 /* Reset HSEON, CSSON and PLLON bits */
hudakz 0:2577a4fb6e72 81 RCC->CR &= 0xFEF6FFFFU;
hudakz 0:2577a4fb6e72 82
hudakz 0:2577a4fb6e72 83 /* Reset HSEBYP bit */
hudakz 0:2577a4fb6e72 84 RCC->CR &= 0xFFFBFFFFU;
hudakz 0:2577a4fb6e72 85
hudakz 0:2577a4fb6e72 86 /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
hudakz 0:2577a4fb6e72 87 RCC->CFGR &= 0xFF80FFFFU;
hudakz 0:2577a4fb6e72 88
hudakz 0:2577a4fb6e72 89 #if defined(STM32F105xC) || defined(STM32F107xC)
hudakz 0:2577a4fb6e72 90 /* Reset PLL2ON and PLL3ON bits */
hudakz 0:2577a4fb6e72 91 RCC->CR &= 0xEBFFFFFFU;
hudakz 0:2577a4fb6e72 92
hudakz 0:2577a4fb6e72 93 /* Disable all interrupts and clear pending bits */
hudakz 0:2577a4fb6e72 94 RCC->CIR = 0x00FF0000U;
hudakz 0:2577a4fb6e72 95
hudakz 0:2577a4fb6e72 96 /* Reset CFGR2 register */
hudakz 0:2577a4fb6e72 97 RCC->CFGR2 = 0x00000000U;
hudakz 0:2577a4fb6e72 98 #elif defined(STM32F100xB) || defined(STM32F100xE)
hudakz 0:2577a4fb6e72 99 /* Disable all interrupts and clear pending bits */
hudakz 0:2577a4fb6e72 100 RCC->CIR = 0x009F0000U;
hudakz 0:2577a4fb6e72 101
hudakz 0:2577a4fb6e72 102 /* Reset CFGR2 register */
hudakz 0:2577a4fb6e72 103 RCC->CFGR2 = 0x00000000U;
hudakz 0:2577a4fb6e72 104 #else
hudakz 0:2577a4fb6e72 105 /* Disable all interrupts and clear pending bits */
hudakz 0:2577a4fb6e72 106 RCC->CIR = 0x009F0000U;
hudakz 0:2577a4fb6e72 107 #endif /* STM32F105xC */
hudakz 0:2577a4fb6e72 108
hudakz 0:2577a4fb6e72 109 #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
hudakz 0:2577a4fb6e72 110 #ifdef DATA_IN_ExtSRAM
hudakz 0:2577a4fb6e72 111 SystemInit_ExtMemCtl();
hudakz 0:2577a4fb6e72 112 #endif /* DATA_IN_ExtSRAM */
hudakz 0:2577a4fb6e72 113 #endif
hudakz 0:2577a4fb6e72 114
hudakz 0:2577a4fb6e72 115 #ifdef VECT_TAB_SRAM
hudakz 0:2577a4fb6e72 116 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
hudakz 0:2577a4fb6e72 117 #else
hudakz 0:2577a4fb6e72 118 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
hudakz 0:2577a4fb6e72 119 #endif
hudakz 0:2577a4fb6e72 120
hudakz 0:2577a4fb6e72 121 }
hudakz 0:2577a4fb6e72 122
hudakz 0:2577a4fb6e72 123 /**
hudakz 0:2577a4fb6e72 124 * @brief Configures the System clock source, PLL Multiplier and Divider factors,
hudakz 0:2577a4fb6e72 125 * AHB/APBx prescalers and Flash settings
hudakz 0:2577a4fb6e72 126 * @note This function should be called only once the RCC clock configuration
hudakz 0:2577a4fb6e72 127 * is reset to the default reset state (done in SystemInit() function).
hudakz 0:2577a4fb6e72 128 * @param None
hudakz 0:2577a4fb6e72 129 * @retval None
hudakz 0:2577a4fb6e72 130 */
hudakz 0:2577a4fb6e72 131 void SetSysClock(void)
hudakz 0:2577a4fb6e72 132 {
hudakz 0:2577a4fb6e72 133 /* 1- Try to start with HSE and external clock */
hudakz 0:2577a4fb6e72 134 #if USE_PLL_HSE_EXTC != 0
hudakz 0:2577a4fb6e72 135 if (SetSysClock_PLL_HSE(1) == 0)
hudakz 0:2577a4fb6e72 136 #endif
hudakz 0:2577a4fb6e72 137 {
hudakz 0:2577a4fb6e72 138 /* 2- If fail try to start with HSE and external xtal */
hudakz 0:2577a4fb6e72 139 #if USE_PLL_HSE_XTAL != 0
hudakz 0:2577a4fb6e72 140 if (SetSysClock_PLL_HSE(0) == 0)
hudakz 0:2577a4fb6e72 141 #endif
hudakz 0:2577a4fb6e72 142 {
hudakz 0:2577a4fb6e72 143 /* 3- If fail start with HSI clock */
hudakz 0:2577a4fb6e72 144 if (SetSysClock_PLL_HSI() == 0) {
hudakz 0:2577a4fb6e72 145 while(1) {
hudakz 0:2577a4fb6e72 146 // [TODO] Put something here to tell the user that a problem occured...
hudakz 0:2577a4fb6e72 147 }
hudakz 0:2577a4fb6e72 148 }
hudakz 0:2577a4fb6e72 149 }
hudakz 0:2577a4fb6e72 150 }
hudakz 0:2577a4fb6e72 151
hudakz 0:2577a4fb6e72 152 /* Output clock on MCO1 pin(PA8) for debugging purpose */
hudakz 0:2577a4fb6e72 153 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); // 72 MHz or 64 MHz
hudakz 0:2577a4fb6e72 154 }
hudakz 0:2577a4fb6e72 155
hudakz 0:2577a4fb6e72 156 #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
hudakz 0:2577a4fb6e72 157 /******************************************************************************/
hudakz 0:2577a4fb6e72 158 /* PLL (clocked by HSE) used as System clock source */
hudakz 0:2577a4fb6e72 159 /******************************************************************************/
hudakz 0:2577a4fb6e72 160 uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
hudakz 0:2577a4fb6e72 161 {
hudakz 0:2577a4fb6e72 162 RCC_ClkInitTypeDef RCC_ClkInitStruct;
hudakz 0:2577a4fb6e72 163 RCC_OscInitTypeDef RCC_OscInitStruct;
hudakz 0:2577a4fb6e72 164
hudakz 0:2577a4fb6e72 165 /* Enable HSE oscillator and activate PLL with HSE as source */
hudakz 0:2577a4fb6e72 166 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
hudakz 0:2577a4fb6e72 167 if (bypass == 0) {
hudakz 0:2577a4fb6e72 168 RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
hudakz 0:2577a4fb6e72 169 } else {
hudakz 0:2577a4fb6e72 170 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */
hudakz 0:2577a4fb6e72 171 }
hudakz 0:2577a4fb6e72 172 RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
hudakz 0:2577a4fb6e72 173 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
hudakz 0:2577a4fb6e72 174 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
hudakz 0:2577a4fb6e72 175 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 72 MHz (8 MHz * 9)
hudakz 0:2577a4fb6e72 176 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
hudakz 0:2577a4fb6e72 177 return 0; // FAIL
hudakz 0:2577a4fb6e72 178 }
hudakz 0:2577a4fb6e72 179
hudakz 0:2577a4fb6e72 180 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
hudakz 0:2577a4fb6e72 181 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
hudakz 0:2577a4fb6e72 182 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 72 MHz
hudakz 0:2577a4fb6e72 183 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 72 MHz
hudakz 0:2577a4fb6e72 184 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 36 MHz
hudakz 0:2577a4fb6e72 185 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 72 MHz
hudakz 0:2577a4fb6e72 186 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
hudakz 0:2577a4fb6e72 187 return 0; // FAIL
hudakz 0:2577a4fb6e72 188 }
hudakz 0:2577a4fb6e72 189
hudakz 0:2577a4fb6e72 190 /* Output clock on MCO1 pin(PA8) for debugging purpose */
hudakz 0:2577a4fb6e72 191 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // 8 MHz
hudakz 0:2577a4fb6e72 192
hudakz 0:2577a4fb6e72 193 return 1; // OK
hudakz 0:2577a4fb6e72 194 }
hudakz 0:2577a4fb6e72 195 #endif
hudakz 0:2577a4fb6e72 196
hudakz 0:2577a4fb6e72 197 /******************************************************************************/
hudakz 0:2577a4fb6e72 198 /* PLL (clocked by HSI) used as System clock source */
hudakz 0:2577a4fb6e72 199 /******************************************************************************/
hudakz 0:2577a4fb6e72 200 uint8_t SetSysClock_PLL_HSI(void)
hudakz 0:2577a4fb6e72 201 {
hudakz 0:2577a4fb6e72 202 RCC_ClkInitTypeDef RCC_ClkInitStruct;
hudakz 0:2577a4fb6e72 203 RCC_OscInitTypeDef RCC_OscInitStruct;
hudakz 0:2577a4fb6e72 204
hudakz 0:2577a4fb6e72 205 /* Enable HSI oscillator and activate PLL with HSI as source */
hudakz 0:2577a4fb6e72 206 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
hudakz 0:2577a4fb6e72 207 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
hudakz 0:2577a4fb6e72 208 RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
hudakz 0:2577a4fb6e72 209 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
hudakz 0:2577a4fb6e72 210 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
hudakz 0:2577a4fb6e72 211 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
hudakz 0:2577a4fb6e72 212 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; // 64 MHz (8 MHz/2 * 16)
hudakz 0:2577a4fb6e72 213 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
hudakz 0:2577a4fb6e72 214 return 0; // FAIL
hudakz 0:2577a4fb6e72 215 }
hudakz 0:2577a4fb6e72 216
hudakz 0:2577a4fb6e72 217 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
hudakz 0:2577a4fb6e72 218 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
hudakz 0:2577a4fb6e72 219 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 64 MHz
hudakz 0:2577a4fb6e72 220 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 64 MHz
hudakz 0:2577a4fb6e72 221 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 32 MHz
hudakz 0:2577a4fb6e72 222 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 64 MHz
hudakz 0:2577a4fb6e72 223 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
hudakz 0:2577a4fb6e72 224 return 0; // FAIL
hudakz 0:2577a4fb6e72 225 }
hudakz 0:2577a4fb6e72 226
hudakz 0:2577a4fb6e72 227 /* Output clock on MCO1 pin(PA8) for debugging purpose */
hudakz 0:2577a4fb6e72 228 //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); // 8 MHz
hudakz 0:2577a4fb6e72 229
hudakz 0:2577a4fb6e72 230 return 1; // OK
hudakz 0:2577a4fb6e72 231 }
hudakz 0:2577a4fb6e72 232