Preskočiť na hlavný obsah

Š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_t do humidity_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 _t jasne 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 const pred #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​

PravidloPopis
Odsadenie4 medzery, nikdy tabulátory
Zložené zátvorkyŠtýl K&R ({ na tom istom riadku)
Maximálna dĺžka riadku120 znakov
MedzeryVždy medzera za čiarkou a okolo operátorov
Prázdne riadkyPoužívajte na vizuálne oddelenie logických častí
Include guardsFormá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ýlPríklad
PremennálowerCamelCaseloopIndex, sensorCount
TyplowerCamelCase + _ttemperature_t, systemState_t
FunkciaUpperCamelCaseRcc_InitSystemClock()
Makro / DefineUPPER_CASE_WITH_UNDERSCORESMAX_BUFFER_SIZE
KonštantaUpperCamelCasePiValue
Názov štruktúryUpperCamelCaseDeviceInfo_t
Člen štruktúrylowerCamelCasedeviceId
Hodnota enumuUPPER_CASESTATE_IDLE
Názov súboruUpperCamelCase + podčiarkovníkGpio_Handler.c