-
Notifications
You must be signed in to change notification settings - Fork 0
Contributing
Thank you for your interest in contributing to Mk. This page covers everything you need to know before submitting code: how to set up the build environment, what coding conventions the project uses, how files and functions must be named, and how to submit a pull request.
- Prerequisites and build instructions
- Repository layout
-
Coding conventions
- 3.1 Language standard
- 3.2 File header
- 3.3 Naming rules
- 3.4 Formatting
- 3.5 Function structure
- 3.6 Comments
- Adding a new source file
- Submitting a pull request
Prerequisites, toolchain setup, build targets, and flashing instructions are maintained in the project README to avoid duplication. Refer to the README before setting up your environment.
Mk/
├── Flasher/
│ └── Jlink/ J-Link startup script
├── Includes/
│ ├── Application/ Graphical engine, application and shell headers
│ ├── Dispatcher/ Input event dispatcher headers
│ ├── FileSystem/ FAT file system headers
│ ├── Loader/ ELF loader headers
│ ├── Mcu/ MCU-specific headers (STM32F74xxx)
│ │ └── Stm32f74xxx/
│ │ ├── Binary/ Binary utility helpers
│ │ ├── Bsp/
│ │ │ ├── Drivers/
│ │ │ │ ├── Gpio/ GPIO pin driver
│ │ │ │ ├── I2c/ I2C peripheral driver
│ │ │ │ ├── Mmc/ SD/MMC controller driver
│ │ │ │ ├── Qspi/ QUADSPI external flash driver
│ │ │ │ │ └── Micron/ Micron NOR flash specific commands
│ │ │ │ └── Usb/
│ │ │ │ ├── Host/
│ │ │ │ │ ├── Hcd/ Host controller driver
│ │ │ │ │ ├── Hid/ HID class driver
│ │ │ │ │ │ └── Control/
│ │ │ │ │ │ ├── Axis/ Analog axis
│ │ │ │ │ │ ├── Button/ Button controls
│ │ │ │ │ │ ├── Consumer/ Consumer controls
│ │ │ │ │ │ ├── HatSwitch/ Hat switch
│ │ │ │ │ │ ├── Joystick/ Joystick
│ │ │ │ │ │ ├── Key/ Keyboard keys
│ │ │ │ │ │ ├── Keyboard/ Keyboard device
│ │ │ │ │ │ ├── Led/ LED outputs
│ │ │ │ │ │ ├── Mouse/ Mouse device
│ │ │ │ │ │ ├── Pointer/ Pointer controls
│ │ │ │ │ │ ├── Stick/ Analog stick
│ │ │ │ │ │ ├── Throttle/ Throttle axis
│ │ │ │ │ │ └── Wheel/ Wheel controls
│ │ │ │ │ └── Msc/ Mass Storage class driver
│ │ │ │ ├── Isr/ USB interrupt service routines
│ │ │ │ └── Port/ USB OTG port configuration
│ │ │ ├── Engine/
│ │ │ │ ├── Application/ Application lifecycle engine
│ │ │ │ ├── Chromart/ DMA2D (Chrom-ART) accelerator
│ │ │ │ ├── Color/ Color management
│ │ │ │ ├── Container/ Widget container management
│ │ │ │ ├── Display/ LTDC display controller
│ │ │ │ ├── Events/ Display engine events
│ │ │ │ ├── Factory/ Widget factory (container registration)
│ │ │ │ ├── Font/ Font rendering
│ │ │ │ ├── Graphics/ 2D drawing primitives
│ │ │ │ ├── Image/ Image loading and rendering
│ │ │ │ ├── Maths/ Fixed-point math helpers
│ │ │ │ ├── Objects/ Built-in widget objects
│ │ │ │ ├── Parser/ Resource / script parser
│ │ │ │ ├── Request/ Display engine request queue
│ │ │ │ └── Utils/ Engine utility functions
│ │ │ ├── Memory/
│ │ │ │ └── Page/ SDRAM / SRAM page allocator
│ │ │ └── System/ System initialisation
│ │ ├── Dma/ DMA stream configuration helpers
│ │ ├── Kernel/ Scheduler, tasks, SVC, SysTick, PendSV
│ │ ├── Peripherals/ STM32F74xxx peripheral register definitions
│ │ └── Termio/ Terminal I/O
│ ├── Shell/ Shell headers
│ ├── Utils/ Utility headers
│ ├── mk.h Top-level include (kernel types and macros)
│ ├── mk_api.h Public API umbrella header
│ └── mk_id.h Task and module identifiers
├── Make/
│ ├── linker.ld Linker script
│ └── makefile Build system
├── Sources/ C and ASM source files, mirroring Includes/
└── Storage/
└── mk/ Files placed on the target storage device at runtime
Each subsystem has a parallel structure: one header file per public function in Includes/, one source file per function in Sources/. The file name is the function name. For example, mk_dispatcher_handleMouse is declared in Includes/Dispatcher/Handler/Mouse/mk_dispatcher_handleMouse.h and defined in Sources/Dispatcher/Handler/Mouse/mk_dispatcher_handleMouse.c.
All contributions must follow the conventions described below. The compiler is configured with an extensive set of -W flags; code that does not compile cleanly at warning level will not be accepted. The full list of compiler flags is available in Mk/Make/makefile.
The project compiles under C18 (-std=c18) in a freestanding environment (-ffreestanding -nostdinc -nodefaultlibs -nostdlib). The standard library is not available. Use only the types and functions defined within the project itself.
External libraries are not permitted in the kernel or any of its subsystems, in order to preserve the self-contained philosophy of the project. External libraries may however be used freely in standalone applications built on top of Mk.
Every .c and .h file must begin with the standard BSD-3-Clause header block, followed by Doxygen @file, @brief, and @date tags. Use the copyright year that matches the date of creation.
/**
*
* @copyright Copyright (C) <year> <author>. All rights reserved.
*
* This file is part of Mk.
*
* Mk is free software. Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @file mk_module_myFunction.c
* @brief Définition de la fonction mk_module_myFunction.
* @date <dd mmm. yyyy>
*
*/The project enforces strict, systematic naming. Every identifier carries a prefix that encodes its kind and the subsystem it belongs to.
Types
| Kind | Prefix | Example |
|---|---|---|
| Struct / typedef | T_mk |
T_mkMouse, T_mkDispatcherHandler
|
| Enum | T_mk |
T_mkCtrlEvent |
| Enum constant | K_MK_ |
K_MK_EVENT_PRESS, K_MK_CONTROL_MOUSE
|
| Macro constant | K_MK_ |
K_MK_FIELD_REFRESH_ENABLED |
Functions and variables
| Scope | Prefix | Example |
|---|---|---|
| Global function | mk_ |
mk_dispatcher_handleMouse |
| Static (file-scope) function | mk_ |
mk_dispatcher_handleMouseButton |
| Global variable | g_mk |
g_mkDisplay, g_mkTermioHandler
|
| Local variable | l_ |
l_result, l_mouse
|
| Function parameter | p_ |
p_handler, p_message, p_mouse
|
Function names follow a mk_<module>_<verb><Object> pattern. The module segment mirrors the directory structure: mk_dispatcher_handleMouse, mk_hid_mouse_getCoord, mk_volume_dispatch. Keep names descriptive and unambiguous.
- Indentation: 3 spaces. No tabs.
-
Parentheses on return: always used —
return ( l_result );. -
Single exit point: every function must have exactly one
returnstatement, placed at the end of the function body. This is required to keep the control flow predictable during debugging.
T_mkCode mk_module_doSomething ( T_mkFoo* p_foo, uint32_t p_value )
{
/* Declaration of the return variable */
T_mkCode l_result = K_MK_OK;
/* Declaration of a working variable */
uint32_t l_count = 0;
/* If the parameter is valid */
if ( p_foo != K_MK_NULL )
{
/* Main processing */
l_count = p_value + 1;
l_result = mk_module_helper ( p_foo, l_count );
}
/* Otherwise */
else
{
/* Update of the return variable */
l_result = K_MK_ERROR_PARAM;
}
/* Return */
return ( l_result );
}Every function follows the same skeleton:
-
Return variable declaration — the variable name is free, but it must be initialized with a value of type
T_mkCode(not necessarilyK_MK_OK; use whichever default is appropriate for the function). The function may return either a singleT_mkCodevalue or a combination ofT_mkCodevalues. - Other local variable declarations — all at the top of the function body, before any statements.
Unused parameters must be suppressed explicitly with a cast to void at the end of the function body, grouped under the comment /* Suppress warning */:
/* Suppress warning */
( void ) p_unusedParam;Public function documentation: every public function declared in a .h file must be documented using the same Doxygen header block used for all functions in the project. The language of the documentation must be either French or English exclusively — do not mix both languages within the same file.
Implicit else branches are not allowed. If an else branch intentionally performs no operation, it must explicitly contain the comment /* Do nothing */.
else
{
/* Do nothing */
}Every module is composed of a fixed set of header files and one source file per public function. No #include directive is permitted inside any .h file — all inclusions are done exclusively in .c files.
Header files (in Includes/<module>/):
| File | Role |
|---|---|
mk_<module>_types.h |
Type definitions (T_mk* structs and enums) used by the module. |
mk_<module>_constants.h |
Constants and enum values (K_MK_*) used by the module. |
mk_<module>.h |
Public function prototypes — the interface exposed to the rest of the OS. |
mk_<module>_data.h |
Declarations of global variables (g_mk*) owned by the module. |
mk_<module>_private.h |
Private function prototypes — internal helpers not accessible outside the module. |
Source files (in Sources/<module>/): one file per function, named after the function it defines: mk_<module>_<myFunction>.c.
Global variables (g_mk*) owned by the module are declared in a dedicated mk_<module>_data.c file.
-
Create the function headers structure in the appropriate
Includes/subdirectory. Wrap the entire content in an include guard named after the file in upper snake case: e.g.MK_<MODULE>_TYPES_Hfor file mk__types. -
Declare the function in
mk_<module>.h(public) ormk_<module>_private.h(private) depending on whether the function is part of the module's external interface. -
Create the source file in the mirrored
Sources/subdirectory:mk_<module>_<myFunction>.c. Include only the individual.hfiles of each sub-module that the function actually needs. Themk_*_api.humbrella headers are reserved for external applications and must not be used inside the OS.
-
Fork the repository and create a branch from
mainwith a descriptive name:feature/usb-audio-classorfix/dispatcher-hatswitch-idle. -
One concern per pull request. Do not mix refactoring, new features, and bug fixes in a single PR. If you spot an unrelated issue while working, file a separate issue or PR.
-
Build passes. The CI check runs
make clean && make all. A PR that introduces any compiler warning or error will not be merged. -
Conventions are respected. Review §3 and §4 before submitting. Pay particular attention to the naming prefixes, the function skeleton, and the
/* Do nothing */pattern — reviewers will flag deviations. -
Description. In the PR body, briefly describe what the change does, why it is needed, and — for bug fixes — how to reproduce the issue before the fix.