Project configuration and build tool for OpenCPLC
Project description
OpenCPLC ⚒️ Forge
Forge is a console app that makes working with OpenCPLC easier. Its job is to set up your environment so you 👨💻developer can focus on building apps instead of fighting with configs and compilation. Available as a Python pip package or standalone opencplc.exe from 🚀Releases (in that case add its location to system PATH manually)
pip install opencplc
Just pick a folder (your workspace) open CMD and type:
opencplc -n <project_name> -b <board>
opencplc -n myapp -b Uno
This creates a directory (or directory tree) in projects location ${projects} matching the name <project_name>. Two files are created inside: main.c and main.h: the minimal project setup. Don't delete them or move to subfolders.
When you have more projects, you can switch between them freely:
opencplc <project_name>
opencplc myapp
You can also pick projects by number from list:
opencplc -l # show project list
opencplc 3 # load project #3 from list
When creating new project or switching to existing one, all files needed for compilation (makefile, flash.ld, ...) are regenerated. These transform everything (project and framework files: .c, .h, .s) into binary files .bin/.hex that can be flashed to the PLC.
If you change PRO_x config values in main.h or modify project structure:
- adding new files,
- moving files,
- deleting files,
- renaming files,
you need to reload the project. If project is already active, no need to type its name -r --reload:
opencplc <project_name>
opencplc -r
Here (roughly) ends Forge job, and further work goes like typical embedded systems project using ✨Make.
✨ Make
If you have proper project config and makefile generated by ⚒️Forge, to build and flash program to PLC just open console in workspace and type:
make build # build C project to binary
make flash # upload binary to PLC memory
# or
make run # run = build + flash
makefile has few more functions. Full list:
make buildor justmake: Builds C project to.bin,.hex,.elffilesmake flash: Uploads program to PLC (microcontroller) memorymake run: Doesmake build, thenmake flashmake cleanormake clr: Removes built files for active projectmake clean_allormake clr_all: Removes built files for all projectsmake dist: Copies.binand.hexfiles to the project foldermake erase: Completely wipes microcontroller memory (erase full chip)
⚙️ Config
On first run ⚒️Forge creates config file opencplc.json. It contains:
version: Default OpenCPLC framework version. This version gets installed. Replaces unspecified-f --framework. Valuelatestmeans newest stable version.paths: List of (relative) pathsprojects: Main projects directory. New projects go here. You can also copy projects manually. All projects are detected automatically. Project name is the path after this location.examples: Directory with demo examples downloaded from Demo repository.framework: Directory with all OpenCPLC framework versions. Subdirectories are created for versions likemajor.minor.patch,developormain. Each contains files for that framework version. Only needed versions are downloaded.build: Directory with built applications
default: Default values (chip,flash,ram,optLevel) for params not passed when creating new projectpwsh: Detected automatically. Whentrue,makefileuses PowerShell syntax. Forfalseit's Bash version.available-versions: List of all available framework versions. Set automatically.
🤔 How works?
First Forge installs GNU Arm Embedded Toolchain, OpenOCD, Make, Git client and sets system variables if these apps aren't visible from console. For HOST platform, MinGW (GCC for Windows) is installed instead of ARM toolchain. If you don't want anyone messing with your system, you can set it up manually. When ⚒️Forge installs missing apps, it adds them to system PATH and continues. Restart your console afterward to use them directly.
Then if needed, it clones OpenCPLC framework from repository to ${framework} folder from opencplc.json. Version from config or specified with -f --framework gets cloned:
opencplc <project_name> --new -f 1.0.2
opencplc <project_name> --new -f develop
📌 Project versioning
Each project stores in main.h the framework version it was created with (definition PRO_VERSION). When switching to existing project:
- If project version differs from current framework, Forge tries to download matching version
- If download fails, warning about potential incompatibility shows up
- Demo examples
-e --examplealways use version saved in project
This way old projects can compile even after framework update to newer version.
Main Forge function is preparing files needed for project:
flash.ld: defines RAM and FLASH memory layout (overwrites, STM32 only)makefile: Contains build, clean and flash rules (overwrites)c_cpp_properties.json: sets header paths and IntelliSense config in VS Code (overwrites)launch.json: configures debugging in VSCode (overwrites)tasks.json: describes tasks like compile or flash (overwrites)settings.json: sets local editor preferences (creates once, not overwritten)extensions.json: suggests useful VSCode extensions (creates once, not overwritten)
There's also bunch of helper functions accessible through smart use of 🚩flags.
🗂️ Workspace structure
workspace/
├─ opencplc.json # workspace config
├─ makefile # active project (generated by Forge)
├─ flash.ld # linker script (generated by Forge, STM32 only)
├─ .vscode/ # VSCode config (generated by Forge)
├─ opencplc/ # framework (downloaded automatically)
│ ├─ 1.0.3/
│ ├─ 1.2.0/
│ └─ develop/
├─ projects/ # user projects
│ ├─ myapp/
│ │ ├─ main.c
│ │ └─ main.h
│ └─ firm/app/ # projects can be nested
│ ├─ main.c
│ └─ main.h
├─ examples/ # demo examples
└─ build/ # compiled binary files
If IntelliSense stops working, use F1 → C/C++: Reset IntelliSense Database.
🖥️ Host
Forge supports Host platform for developing and testing code on PC (Windows/Linux) without embedded hardware:
opencplc -n myapp -c Host # desktop project
This creates project that compiles with native GCC (MinGW on Windows) instead of ARM toolchain. Useful for:
- Testing algorithms and logic without hardware
- Developing protocol parsers and data processing
- Unit testing framework components
- Quick prototyping before deploying to PLC
Host platform provides stub implementations for hardware-dependent modules (GPIO, timers, etc.) so code structure remains compatible with STM32 targets.
🚩 Flags
Beyond the basic flags described above, there are a few more worth knowing. Full list:
Basic
name: Project name. Default first argument. Also defines the project path:${projects}/name, and output files (.bin,.hex,.elf) are tied to it. Can also be a project number from the-llist.-n --new: Creates a new project with the given name.-e --example: Loads a demo example by name from the Demo repository.-r --reload: Reads the project name and example flag from an existingmakefile, then regenerates project files.nameis not required.-d --delete: Deletes the project with the givenname.-g --get: Downloads a project from Git (GitHub, GitLab, ...) or a remote ZIP and adds it as a new project. The second argument (first is the link) can be a reference (branch,tag). Ifnameis not specified, it tries to read it from the@namefield inmain.h.
Hardware config
-b --board: PLC board for the new project:Uno,Dio,Aio,Eco,Customfor a custom design, orNonefor a bare microcontroller.Customprovides the PLC layer without peripheral mapping — fill it in manually.-c --chip: Microcontroller or platform:STM32G081,STM32G0C1,STM32WB55,HOST(compile for PC). Without-b --board, the project runs without the PLC layer — only HAL and standard framework libraries. Useful for Nucleo boards or custom hardware.-m --memory: Memory in kB:FLASH RAM [RESERVED].RESERVEDis the memory allocated for config and EEPROM, subtracted from FLASH in the linker fileflash.ld. (STM32 only)
Build config
-f --framework: Framework version:latest,develop,1.0.0. If not provided, read from theversionfield inopencplc.json.-o --opt-level: Compiler optimization level:O0(debug),Og(default),O1,O2,O3. LevelsO2andO3show a warning for STM32 (timing/debugging issues) but are allowed forHOST.
Info
-l --list: Lists existing projects, or examples when-e --exampleis active.-i --info: Returns basic info about the specified or active project, including project and framework versions.-F --framework-versions: Lists all available OpenCPLC framework versions.-v --version: Shows the ⚒️Forge version and repository link.
Tools
-a --assets: Downloads helper materials for design (docs, diagrams). Optionally accepts a folder name as destination.-u --update: Checks for and installs ⚒️Forge updates. Accepts a specific version orlatest.-y --yes: Auto-confirms all prompts (non-interactive mode).
Hash utilities
-hl --hash-list: Generates an enum with DJB2 hashes from a tag list.-ht --hash-title: Enum type name for the hash generator.-hd --hash-define: Uses#defineinstead ofenumfor hash output.
🗑️ Deleting and 💾 copying projects can be done directly from the OS.
Each project stores all the information it needs in main.h, and its presence is auto-detected on startup.
📟 Console
⚒️Forge and ✨Make are console programs. Essential for working with OpenCPLC.
System console is available in many apps like Command Prompt, PowerShell, GIT Bash, even terminal in VSCode. If console call returns error, it probably wasn't opened in workspace. Close console and open it in right folder or navigate manually with cd command.
📋 Usage examples
# Creating new project
opencplc -n myapp -b Uno # project for OpenCPLC Uno board
opencplc -n myapp -b Eco -m 128 36 # project for Eco with 128kB/36kB memory
opencplc -n myapp -b Custom -c STM32G081 # custom hardware with PLC layer (no peripheral mapping)
opencplc -n myapp -c STM32G081 # bare-metal project for STM32G081 (e.g. Nucleo)
opencplc -n myapp -c Host # desktop project (Windows/Linux)
# Managing projects
opencplc myapp # load project 'myapp'
opencplc 3 # load project #3 from list
opencplc -r # reload active project
opencplc -l # list all projects
opencplc -i # info about active project
# Demo examples
opencplc -e blinky # load example 'blinky'
opencplc -e -l # list available examples
# Downloading projects
opencplc -g https://github.com/user/repo
opencplc -g https://github.com/user/repo v1.0.0
# Updates
opencplc -u # update Forge to latest version
opencplc -F # show available Core versions
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opencplc-0.1.3.tar.gz.
File metadata
- Download URL: opencplc-0.1.3.tar.gz
- Upload date:
- Size: 36.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33da4b722d1c8bedb39ad4c5f02ccfc528e094e4a911e7022d060047c64111cd
|
|
| MD5 |
d5f718a9bf002e5cdb267b8021a26d6f
|
|
| BLAKE2b-256 |
0bd34a56a44843f84ebbc111dd2580bc3f5fa746c9eee853ccb91ec190e55cda
|
Provenance
The following attestation bundles were made for opencplc-0.1.3.tar.gz:
Publisher:
publish.yml on OpenCPLC/Forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opencplc-0.1.3.tar.gz -
Subject digest:
33da4b722d1c8bedb39ad4c5f02ccfc528e094e4a911e7022d060047c64111cd - Sigstore transparency entry: 1236415888
- Sigstore integration time:
-
Permalink:
OpenCPLC/Forge@c6b1b94d5e6cfc930664b05460d9bc0ca982c7ab -
Branch / Tag:
refs/tags/0.1.3 - Owner: https://github.com/OpenCPLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c6b1b94d5e6cfc930664b05460d9bc0ca982c7ab -
Trigger Event:
release
-
Statement type:
File details
Details for the file opencplc-0.1.3-py3-none-any.whl.
File metadata
- Download URL: opencplc-0.1.3-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97d311d1b57bae483ec12e7cda3756e20c5034f772f582d78148fb3590f369b6
|
|
| MD5 |
41b90d490054e4e3aae3ba8f21ac96d4
|
|
| BLAKE2b-256 |
069daf1e2df2ec9f37104c1081c43bc98f4c36b99abaf475c81c6bbbf92194e7
|
Provenance
The following attestation bundles were made for opencplc-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on OpenCPLC/Forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opencplc-0.1.3-py3-none-any.whl -
Subject digest:
97d311d1b57bae483ec12e7cda3756e20c5034f772f582d78148fb3590f369b6 - Sigstore transparency entry: 1236415961
- Sigstore integration time:
-
Permalink:
OpenCPLC/Forge@c6b1b94d5e6cfc930664b05460d9bc0ca982c7ab -
Branch / Tag:
refs/tags/0.1.3 - Owner: https://github.com/OpenCPLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c6b1b94d5e6cfc930664b05460d9bc0ca982c7ab -
Trigger Event:
release
-
Statement type: