Štýl kódovania
Každá firma má svoj vlastný štýl kódovania.
Môj štýl kódovania vychádza zo štandardov používaných v automobilovom priemysle — vylepšených pre embedded vývoj — pretože je z môjho pohľadu najčitateľnejší a najlepšie udržiavateľný.
Nižšie nájdete zdôvodnenie každého pravidla a to, ako prispieva k prehľadnosti a dlhodobej udržiavateľnosti.
🔡 Premenné
Premenné majú používať pomenovanie lower camelCase.
Názov premennej musí obsahovať aspoň tri znaky.
❌ Nesprávne
int x, y, z;
for(int i = 0; i < 10; i++) { ... }
✅ Správne
int loopIndex;
float temperatureCelsius;
uint8_t sensorCount;
📘 Prečo: Každá premenná musí mať zmysluplný názov.
Krátke, záhadné názvy ničia čitateľnosť a sťažujú údržbu kódu.
⚠️ Externé premenné
Existencia premenných extern je prísne zakázaná.
Ak sa taká premenná nájde, jej autor má byť verejne lynčovaný (obrazne 😉).
💡 Dôvod:
Externé premenné sa takmer nedajú vysledovať — nezistíte jednoducho, kto do nich zapisuje alebo ich číta.
Dáta vždy zapuzdrite za gettery a settery.
🧱 Dátové typy
Názvy typov nasledujú vzor lowerCamelCase, ale musia končiť na _t,
podľa štandardného pomenovania používaného v <stdint.h> (napr. uint8_t, uint16_t atď.).
✅ Príklad
typedef uint16_t temperature_t;
typedef float voltage_t;
typedef uint8_t humidity_t;
🧩 Dôvod:
Okamžite viete, či identifikátor predstavuje typ alebo premennú.
🚫 Vyhnite sa všeobecným vstavaným typom
Nepoužívajte v projekte priamo holé uint8_t, uint16_t atď.
Namiesto toho definujte vlastné, sémanticky zmysluplné typedefy.
✅ Tým sa zabráni zmiešaniu nekompatibilných premenných:
nemôžete omylom priradiťtemperature_tdohumidity_t.
temperature_t temp = 25;
humidity_t humidity = 40;
temp = humidity; // ❌ Compilation error
Tým sa vynucuje typová bezpečnosť a skracuje sa čas ladenia.
🧭 Názvy funkcií
Názvy funkcií majú používať štýl UpperCamelCase.
Každá funkcia by mala obsahovať prefix modulu, aby bolo jasné, komu patrí.
✅ Príklad
rcc_InitSystemClock();
rcc_GetClockFrequency();
gpio_SetPinState(GPIOA, PIN_5, true);
📘 Prečo:
Okamžite je jasné, či je identifikátor premenná, funkcia alebo typ.
Prefix modulu vám umožňuje ľahko nájsť funkciu v hierarchii projektu.
⚙️ Direktívy preprocesora
Direktívy preprocesora a makrá musia používať UPPER_CASE_WITH_UNDERSCORES.
✅ Príklad
#define MAX_SENSOR_COUNT 8
#define ENABLE_DEBUG_MODE 1
📘 Prečo:
Pomenovanie veľkými písmenami okamžite prezrádza, že ide o symbol času kompilácie, nie o premennú za behu.
📄 Názvy súborov
Názvy súborov používajú štýl UpperCamelCase.
Každý názov súboru musí začínať názvom modulu, za ktorým nasleduje podčiarkovník a popis funkcionality.
✅ Príklad
Rcc_Config.c
Gpio_Handler.c
Modbus_Transport.c
🧩 Kompletná štruktúra organizácie súborov je popísaná na samostatnej wiki stránke:
Organizácia súborov
🗂️ Enumerácie
Enumeračné typy používajú UpperCamelCase pre typ a UPPER_CASE pre enumerátory.
✅ Príklad
typedef enum
{
STATE_IDLE,
STATE_RUNNING,
STATE_ERROR
} systemState_t;
📘 Prečo:
Hodnoty písané veľkými písmenami odlišujú enumeračné konštanty od premenných, zatiaľ čo prípona_tjasne označuje typ.
🧮 Konštanty
Konštanty definované v kóde (nie makrá) majú používať názvy v štýle UpperCamelCase.
✅ Príklad
const uint32_t SystemTimeoutMs = 5000;
const float PiValue = 3.14159f;
💡 Kdekoľvek je to možné, uprednostňujte
constpred#define— poskytuje kontrolu typov a riadenie rozsahu platnosti.
🧰 Štruktúry a uniony
Názvy štruktúr používajú UpperCamelCase,
zatiaľ čo ich členy používajú lowerCamelCase.
✅ Príklad
typedef struct
{
uint8_t deviceId;
uint16_t firmwareVersion;
float batteryVoltage;
} DeviceInfo_t;
📘 Prečo:
Konzistentné používanie veľkých a malých písmen jasne odlišuje typ štruktúry od jej polí.
🔣 Makrá a inline funkcie
- Makrá (
#define) → UPPER_CASE_WITH_UNDERSCORES - Inline pomocné funkcie → UpperCamelCase (rovnako ako bežné funkcie)
✅ Príklad
#define ENABLE_INTERRUPTS() __enable_irq()
#define DISABLE_INTERRUPTS() __disable_irq()
static inline void DelayMs(uint32_t ms) { ... }
💬 Komentáre a dokumentácia
Pre všetky verejné funkcie, typy a makrá používajte komentáre v štýle Doxygen.
✅ Príklad
/**
* @brief Initializes system clocks.
* @param None
* @retval None
*/
void Rcc_InitSystemClock(void);
💡 Komentáre majte krátke, presné a písané v angličtine.
Opisujte, prečo sa niečo robí, nie čo sa robí — to by mal objasniť samotný kód.
🧾 Pravidlá formátovania
| Pravidlo | Popis |
|---|---|
| Odsadenie | 4 medzery, nikdy tabulátory |
| Zložené zátvorky | Štýl K&R ({ na tom istom riadku) |
| Maximálna dĺžka riadku | 120 znakov |
| Medzery | Vždy medzera za čiarkou a okolo operátorov |
| Prázdne riadky | Používajte na vizuálne oddelenie logických častí |
| Include guards | Formát #ifndef MODULE_FILENAME_H |
| Poradie includov | <system> → "project" → "module" |
✅ Príklad
#include <stdint.h>
#include "Rcc_Config.h"
#include "Gpio_Handler.h"
void Gpio_Init(void)
{
gpioState_t state = GPIO_LOW;
if (state == GPIO_LOW)
{
gpio_SetPinState(GPIOA, PIN_5, true);
}
}
🧩 Menné priestory a prefixy
Každý modul musí mať jedinečný prefix (napr. rcc_, gpio_, adc_).
Tým sa zaručí, že sa názvy funkcií a typov v rámci systému nebudú kolidovať.
📘 Pravidlo veľkého prsta:
- Prefix = názov modulu
- CamelCase = funkcia
- _t = typ
- lowerCamelCase = premenná
Príklad konzistentnosti:
rcc_Init()
rcc_Config_t
rccState_t
rcc_GetClock()
✅ Zhrnutie
| Prvok | Štýl | Príklad |
|---|---|---|
| Premenná | lowerCamelCase | loopIndex, sensorCount |
| Typ | lowerCamelCase + _t | temperature_t, systemState_t |
| Funkcia | UpperCamelCase | Rcc_InitSystemClock() |
| Makro / Define | UPPER_CASE_WITH_UNDERSCORES | MAX_BUFFER_SIZE |
| Konštanta | UpperCamelCase | PiValue |
| Názov štruktúry | UpperCamelCase | DeviceInfo_t |
| Člen štruktúry | lowerCamelCase | deviceId |
| Hodnota enumu | UPPER_CASE | STATE_IDLE |
| Názov súboru | UpperCamelCase + podčiarkovník | Gpio_Handler.c |