# 4. Coding Guidelines ## 4.1. Regeln Im folgenden finden Sie einige Regeln wie der C-Code in diesem Praktikum formatiert sein muss. Sauber strukturierter Quellcode trägt entscheident dazu bei, dass Fehler entweder von vorneherin vermieden werden oder beim Debugging leichter eingrenzbar sind. ## 4.1.1. Modul- und Funktionsnamen Ein Modul (z.B. eine C-Datei mit Funktionen die als Gruppe eine Teilfunktion erfüllen) hat einen prägnanten Namen. Dieser wird sowohl im Dateinamen verwendet, wie auch als präfix für alle Funktionen und Variablen. Beispiel: Die Datei ’imu.c’ soll soll alle Funktionen zum auslesen der IMU enthalten. Diese heißen dann entsprechend ’imu_init()’, ’imu_readGyro()’ usw. und nutzen globale Variablen wie ’imu_config’ ## 4.1.2. Interne Funktionen und Variablen Als Grundsatz gilt: Alles was nicht für andere Module als Interface nötig ist wird mit ’static’ und einem Unterstrich als Präfix versehen. Somit ist es nur innerhalb dieser einen C-Datei bekannt und es wird klar wie die Schnittstellen nach außen aussehen. ``` /∗∗ Dies ist eine interne variable ∗/ static int32_t _internalTimerCount; /∗∗ Dies ist eine interne Funktion ∗/ static void _imu_handleError(int err); ``` Quellcode 4.1: Deklaration von static Variablen und Funktionen ## 4.1.3. Kommentare Jede Funktion bekommt einen Kommentar im Doxygen-Stil, der den Inhalt der Funktion sowie ihre Parameter und Rückgabewerte beschreibt. ``` /∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/ /∗∗ ∗ This function initiates an interrupt−driven receive in master mode. ∗ ∗ It sets the transfer size register so the slave can send data to us. ∗ The rest of the work is managed by interrupt handler. ∗ ∗ @param InstancePtr is a pointer to the XIicPs instance . ∗ @param MsgPtr is the pointer to the receive buffer . ∗ @param ByteCount is the number of bytes to be received. ∗ @param SlaveAddr is the address of the slave we are receiving from. ∗ ∗ @return None. ∗ ∗ @note This receive routine is for interrupt−driven transfer only. ∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/ void XIicPs_MasterRecv(XIicPs ∗InstancePtr, u8 ∗MsgPtr, s32 ByteCount,u16 SlaveAddr){ ... } ``` Quellcode 4.2: Beispielhaftes Doxygen Kommentar aus der Xilinx Libary ## 4.1.4. Aufbau der C-Datei Jede C-Datei hat einen klaren Aufbau der sich in die Bereiche “Includes”, “Inputs”, “Outputs”, “interne Variablen”, “interne Konstanten”, “interne Funktions-Prototypen” und die eigentliche Implementierung aufteilt. So ist klar ersichtlich wo man eingreifen muss um z.B. konstante Parameter zu verändern. ``` /∗∗ Includes ∗/ #include " .... h" /∗∗ module input variables ∗/ extern int16_t accData [3]; /∗∗ module output variables ∗/ int32_t pidValue=0; /∗∗ module internal variables ∗/ static float _pid_errorSumAngle=0; /∗∗ module internal constatns ∗/ const int16_t ACC_MIN[3] = {−10, −20, −30}; /∗∗ internal function prototypes ∗/ static int16_t _pid_map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max); ... /∗∗ functions ∗∗/ void pid_init (void) { ... } static int16_t _pid_map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max){ ... } ``` Quellcode 4.3: Aufbau einer C-Datei