STM32 Libraries

Hi, I would like to work with NUCELO F103RB board without using any framework. I prever working directly with registers.
Removing the framework line from platformio.ini file leads to problems with the toolchain.
(i have started with cube_mx library)

Compiling .pio\build\nucleo_f103rb\src\main.o
Linking .pio\build\nucleo_f103rb\firmware.elf
c:/users/piotr/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: cannot
open linker script file stm32f103xb.ld: No such file or directory
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\nucleo_f103rb\firmware.elf] Error 1

If writting from scratch is too complicated, it would be fine to at least disable HAL_Libraries from project. I was trying to expirent with library.json file but without success.

"build": {
    "srcFilter": [
        "-<C:/Users/Piotr/.platformio/packages/framework-stm32cube/f1/Drivers/STM32F1xx_HAL_Driver/Inc/*.h>",
        "-<C:/Users/Piotr/.platformio/packages/framework-stm32cube/f1/Drivers/CMSIS/Device/ST/STM32F1xx/Include/*.h>",
        "-<C:/Users/Piotr/.platformio/packages/framework-stm32cube/f1/Drivers/CMSIS/Device/ST/STM32F1xx/Include/*.c>"
    ]
}

How can I run writting the code without framework or simply disable to framework libraries from the project?

I’d be really thankful for receiving the answer.

It’s OK to remove the field framework in order to get rid of any additional files, but you still need to provide a linker script and some files with startup routine as they usually depend on framework.

Hi Valeros!

thanks for message. It seems that, deleting the whole framework may be not really useful.
Let’s stay with the linker script and startup routine from framework files but avoid all of the unnecessary drivers like I2C, CAN etc. They are taking some time during debugging, testing and may lead to name duplicates.

How to exclude selected CubeMX (framework) libraries from project?

I’m not sure I understand what you are trying to achieve, but all unused modules will be garbage collected during linkage stage, so they shouldn’t affect your memory footprint. If you want to exclude them from compilation, then probably the best option is to remove framework field from platformio.ini and organize the files you need from a framework in a form of a standalone library. Also, you can manually modify build script to fit your requirements, but keep in mind that your changes will be overwritten with the next platform update.

Thank you for advice. Indeed, the best way is deleting the framework and manually organizing the framework files, that i need.
I will do my best with customization. If I will succeed I’ll share the result.

1 Like

I am struggling with my own header files.
Unfortunately I encounter the problem, that i can’t really understand.
The IDE is showing the bug with #define command and the building can’t be succesfully performed.
I see nothing wrong with the command, since it looks same as the other ones.
I suspected the dupplicated variables names with CubeMX Framework, so added ‘m’ letter to the beginning of every my variable… Didn’t helped.

Is the problem with Visual Code, Platform IO or my Project?

I share the project: GitHub - Przasa/C_CubeMXwithVsCode: stm drivers development with visual code
and some results…

image

> Executing task: C:\Users\Piotr\.platformio\penv\Scripts\platformio.exe run --environment nucleo_f103rb <

Processing nucleo_f103rb (platform: ststm32; board: nucleo_f103rb; framework: stm32cube)
---------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/nucleo_f103rb.html
PLATFORM: ST STM32 5.5.0 > ST Nucleo F103RB
HARDWARE: STM32F103RBT6 72MHz, 20KB RAM, 128KB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, jlink)
PACKAGES: toolchain-gccarmnoneeabi 1.70201.0 (7.2.1), framework-stm32cube 2.0.181130
Warning! Cannot find a linker script for the required board! Firmware will be linked with a default linker script!
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 13 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <mystm32f103xx>
|-- <stm32f103xx_gpio_driver>
|   |-- <mystm32f103xx>
Compiling .pio\build\nucleo_f103rb\libf43\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.o
In file included from lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.h:12:0,
                 from lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:9:
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c: In function 'mGPIO_PeriphClockControl':
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:140:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOA_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<2)
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:19:4: note: in expansion of macro 'mGPIOA_PCLK_EN'
    mGPIOA_PCLK_EN();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:146:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOA_PCLK_DI() (mRCC->mAPB2_BASEADDR &= ~(1<<2))
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:21:4: note: in expansion of macro 'mGPIOA_PCLK_DI'
    mGPIOA_PCLK_DI();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:141:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOB_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<3)
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:25:4: note: in expansion of macro 'mGPIOB_PCLK_EN'
    mGPIOB_PCLK_EN();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:147:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOB_PCLK_DI() (mRCC->mAPB2_BASEADDR &= ~(1<<3))
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:27:4: note: in expansion of macro 'mGPIOB_PCLK_DI'
    mGPIOB_PCLK_DI();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:140:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOA_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<2)
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:31:4: note: in expansion of macro 'mGPIOA_PCLK_EN'
    mGPIOA_PCLK_EN();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:148:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOC_PCLK_DI() (mRCC->mAPB2_BASEADDR &= ~(1<<4))
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:33:4: note: in expansion of macro 'mGPIOC_PCLK_DI'
    mGPIOC_PCLK_DI();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:143:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOD_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<5)
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:37:4: note: in expansion of macro 'mGPIOD_PCLK_EN'
    mGPIOD_PCLK_EN();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:149:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOD_PCLK_DI() (mRCC->mAPB2_BASEADDR &= ~(1<<5))
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:39:4: note: in expansion of macro 'mGPIOD_PCLK_DI'
    mGPIOD_PCLK_DI();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:144:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOE_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<6)
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:43:4: note: in expansion of macro 'mGPIOE_PCLK_EN'
    mGPIOE_PCLK_EN();
    ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U
                            ^
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:37:26: note: in expansion of macro 'mPERIPRH_BASEADDR'
 #define mAPB2_BASEADDR   mPERIPRH_BASEADDR
                          ^~~~~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:150:33: note: in expansion of macro 'mAPB2_BASEADDR'
 #define mGPIOE_PCLK_DI() (mRCC->mAPB2_BASEADDR &= ~(1<<6))
                                 ^~~~~~~~~~~~~~
lib\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.c:45:4: note: in expansion of macro 'mGPIOE_PCLK_DI'
    mGPIOE_PCLK_DI();
    ^~~~~~~~~~~~~~
Compiling .pio\build\nucleo_f103rb\FrameworkHALDriver\Src\stm32f1xx_hal_dac.o
Compiling .pio\build\nucleo_f103rb\FrameworkHALDriver\Src\stm32f1xx_hal_dac_ex.o
*** [.pio\build\nucleo_f103rb\libf43\stm32f103xx_gpio_driver\stm32f103xx_gpio_driver.o] Error 1
Compiling .pio\build\nucleo_f103rb\FrameworkHALDriver\Src\stm32f1xx_hal_dma.o
========================================================= [ERROR] Took 2.35 seconds =========================================================
The terminal process terminated with exit code: 1

Terminal will be reused by tasks, press any key to close it.

Your code. Let’s walk through it slowly and expand the macros. You have written

mGPIOA_PCLK_EN();

When given that

#define mGPIOA_PCLK_EN() (mRCC->mAPB2_BASEADDR |= 1<<2)
#define mRCC 				((mRCC_RegDef*)mRCC_BASEADDR)
#define mAPB2_BASEADDR			mPERIPRH_BASEADDR
#define mPERIPRH_BASEADDR		0x40000000U
#define mRCC_BASEADDR			0x40021000U

#define mvo volatile
typedef struct  {
	mvo uint32_t CR; 	/*offset: 0x00*/
	mvo uint32_t CFGR;	/*offset: 0x04*/
	mvo uint32_t CIR;	/*offset: 0x08*/
	mvo uint32_t APB2RSTR;	/*offset: 0x0C*/
	mvo uint32_t APB1RSTR;	/*offset: 0x10*/
	mvo uint32_t AHBENR;	/*offset: 0x14*/
	mvo uint32_t APB2ENR;	/*offset: 0x18*/
	mvo uint32_t APB1ENR;	/*offset: 0x1C*/
	mvo uint32_t BDCR;	/*offset: 0x20*/
	mvo uint32_t CSR; /*offset: 0x24*/
} mRCC_RegDef;

will expand into

(mRCC->mAPB2_BASEADDR |= 1<<2);
(((mRCC_RegDef*)mRCC_BASEADDR)->mAPB2_BASEADDR |= 1<<2);
(((mRCC_RegDef*)0x40021000U)->mAPB2_BASEADDR |= 1<<2);
(((mRCC_RegDef*)0x40021000U)->0x40000000U |= 1<<2);

The error you’re getting is

lib\stm32f103xx_gpio_driver\../mystm32f103xx/mystm32f103xx.h:34:28: error: expected identifier before numeric constant
 #define mPERIPRH_BASEADDR  0x40000000U

Which makes sense. You’ve casted a memory addess to mRCC_RegDef* which has well-defined members (CR etc) but you’re attempting to do access it using a constant numeric value. That won’t work.

I think what you want is to modify is the RCC_APB2ENR register, in your code APB2ENR. (See here page 114). So you must do

#define mGPIOA_PCLK_EN() (mRCC->APB2ENR|= 1<<2)

Rest of the errors are similiar.

1 Like

You are right! The #define line was wrong.
I haven’t noticed that before.
After small correction, code builds successfully.

Thank you!

1 Like