Developing a re-usable custom driver with STM32 and VSCode - Page 1
Forum section: electronics / general

author: imacgreg
author_rank: Contributor
timestamp: December 21, 2023, 08:50:29 pm
content: I am using CubeMX to create HAL code structure + makefile that I am then opening with VScode as my IDE (using the STM32 for VSCODE extension). This works really well and I have been able to develop self-contained software for both nucleo dev boards and custom designs with various STM32 parts just fine.For a new project, I would like to develop a driver for a custom LED PCB that I can then use with multiple STM32 projects in the future. In other words, I am writing the driver code using an F446 Nucleo, but I'd like to re-use the same driver with a custom board in the future.I expect the driver to have "my_Driver.c" source and "my_Driver.h" include files in a folder called "my_Driver" that I can then point to. This is where I am stuck.What kind of folder/file structure should I use and how do I need to configure the makefile (or VScode workspace?) to do this properly? I'm having a hard time finding or describing (and searching) for this topic, any assistance would be appreciated!

author: dobsonr741
author_rank: Frequent Contributor
timestamp: December 24, 2023, 03:42:38 pm
content: Creating a reusable driver for your custom LED PCB is a great approach to streamline development across multiple STM32 projects. Here’s a suggested folder/file structure and some guidance on configuring your Makefile and VSCode workspace:Folder/File StructureYou can organize your driver in a modular way. Here’s a basic structure:MyProject/│├── my_Driver/│ ├── my_Driver.c│ ├── my_Driver.h│ └── README.md (optional, but good for documentation)│├── Src/│ ├── main.c│ ├── stm32f4xx_it.c│ └── ...│├── Inc/│ ├── main.h│ ├── stm32f4xx_it.h│ └── ...│├── Makefile└── .vscode/├── settings.json├── c_cpp_properties.json└── ...Makefile ConfigurationTo include your custom driver in your Makefile, you’ll need to modify a few things:1. Include Directory: Add the path to your driver’s header file to the include directories.C_INCLUDES += -I../my_Driver2. Source Files: Add the path to your driver’s source file to the list of source files.C_SOURCES += ../my_Driver/my_Driver.cVSCode ConfigurationIn your .vscode/c_cpp_properties.json, you should include the path to your driver’s header file to ensure IntelliSense works correctly:{"configurations": [{"name": "STM32","includePath": ["${workspaceFolder}/Inc","${workspaceFolder}/my_Driver",// other include paths],// other configuration settings}],// other VSCode settings}General Tips• Relative Paths: Use relative paths in your Makefile and VSCode settings to ensure portability.• Documentation: Document your driver’s API in the my_Driver.h or a separate README file within the my_Driver folder.• Version Control: Consider using a version control system like Git to manage your driver code, especially if you plan to use it across multiple projects.• Testing: Ensure your driver is thoroughly tested on the Nucleo board before integrating it with other projects.• Portability: Make your driver as hardware-agnostic as possible, abstracting out any hardware-specific details.By following this structure and configuration, you should be able to develop a reusable driver for your LED PCB and easily integrate it into various STM32 projects. Remember that each project might require slight adjustments in the Makefile, especially if there are different hardware configurations or additional dependencies.

author: IOsetting
author_rank: Regular Contributor
timestamp: December 24, 2023, 05:46:41 pm
content: I organized my project in this way to reuse the libraries while the Makefiles can be different.The common driver files can be put into Hardware folder.Code:├── Apps│ ├── RemoteController # project 1│ │ ├── Driver│ │ ├── Makefile│ │ └── User│ └── ServoDriverBoard # project 2│ ├── Driver│ ├── Makefile│ └── User├── Build├── Hardware # common drivers│ ├── 74hc165.c│ ├── 74hc165.h│ ├── 74hc595.c│ ├── 74hc595.h│ ├── SEGGER_RTT.c│ ├── SEGGER_RTT_Conf.h│ ├── SEGGER_RTT.h│ ├── SEGGER_RTT_printf.c│ ├── st7567.c│ ├── st7567.h│ ├── xl2400.c│ ├── xl2400.h│ ├── xl2400p.c│ ├── xl2400p.h│ ├── xn297l.c│ └── xn297l.h├── Libraries # common libs│ ├── CMSIS│ ├── LDScripts│ ├── PY32F0xx_LL_BSP│ └── PY32F0xx_LL_Driver├── Misc└── rules.mk

author: imacgreg
author_rank: Contributor
timestamp: December 24, 2023, 10:33:28 pm
content: I appreciate the replies! It's very useful to see overall project/folder structures and I'm starting to understand how to navigate around folders within the makefile. Started to make more sense when I figured out how to use relative paths. I was able to link to a local test driver source and header file.Something I noticed is the VScode configuration file updated automatically when I updated the C_INCLUDES path. I wonder if there's an extension doing that for me.I posted this question elsewhere and also got the git recommendation. It appears that the makefile could pull directly from a repo during compile? That all makes sense conceptually but I will need to dig in and work out the nuts and bolts.Thank you!

author: dobsonr741
author_rank: Frequent Contributor
timestamp: December 24, 2023, 11:55:25 pm
content: Yes it could. Here is an example as it was given by GPT-4:To create a Makefile that pulls a dependency from a Git repository, you need to define a target in the Makefile that executes the git clone command. Here's a basic example:Code:make# Makefile# The URL of the Git repositoryREPO_URL = https://github.com/user/repo.git# The directory where the repository will be clonedREPO_DIR = ./dependency-repo# Default targetall: clone_repo# Target for cloning the repositoryclone_repo:@if [ ! -d "$(REPO_DIR)" ]; then \git clone $(REPO_URL) $(REPO_DIR); \else \echo "Repository already cloned."; \fi# Clean target to remove the cloned repositoryclean:rm -rf $(REPO_DIR)In this Makefile:- `REPO_URL` is set to the Git repository URL. Replace `https://github.com/user/repo.git` with the actual URL of the dependency repository.- `REPO_DIR` is the local directory where the repository will be cloned.- The `all` target, which is the default when you run `make`, depends on the `clone_repo` target.- The `clone_repo` target checks if the directory exists. If it doesn't, it clones the repository. If the directory already exists, it prints a message stating that the repository is already cloned.- The `clean` target is an optional target to remove the cloned repository directory.To use this Makefile, just run `make` in the directory where the Makefile is located. To remove the cloned repository, run `make clean`.Code: