This repository contains my work in Embedded Firmware Development for AVR microcontrollers as part of the Embedded Software Architecture course taught by Eng. Romario Bassem in Information Technology Institute (ITI)'s 9-month Professional Training Program --- Embedded Systems Track.
Since AVR architecture is fairly simple, it was a golden opportunity to learn how to design low-level drivers through intricate techniques and utilize tools like CMake for building and flashing, Unity Test Framework for writing unit tests for drivers, and cppcheck to test how compliant the software I wrote is with MISRAC standard.
- MDIO (Tested on Hardware && Proteus)
- MPORT (Tested on Hardware && Proteus)
- MGIE (Tested on Proteus)
- MEXTI (Tested on Proteus)
- MTIMER (Tested TIMER0 on Proteus)
- HLED (Tested on Hardware && Proteus)
- HSWITCH (Tested on Hardware && Proteus)
- H7SEGMENT (Tested on Hardware && Proteus)
- HLCD (Tested on Proteus)
- HKEYPAD (Tested on Proteus)
Install the following packages:
sudo apt install gcc-avr avr-libc avrdude
# gcc-avr -> avr toolchain
# avr-libc -> avr c library with avr-headers
# avrdude -> for flashing hex/bin files
cmake -S . -B build
cmake --build build
cd build
make flash
Open a terminal and execute the following:
simulavr -d atmega32 -f AVR_PROJECT.elf --gdbserver
In another terminal, run:
avr-gdb AVR_PROJECT.elf
In order to begin debugging using GDB, connect it with SimulAVR using the following command. Port 1212 is the default port for SimulAVR; make sure it matches the port returned by SimulAVR upon starting it.
target remote localhost:1212
Symbol Table is read by GDB by default if
-g
compiler flag was used to add debugging symbols.
-
To place a breakpoint:
break LABEL_NAME
-
To continue executing until breakpoint is reached:
c
-
To print a variable's value (if it is a pointer for example):
print *PTR_NAME
-
To single step in C code:
n
-
To switch code layout from C to Assembly:
layout asm
-
To single step in Assembly code:
stepi
si
-
To switch code layout back to C:
layout src
Requirements: 4 applications in total.
- Task 1 -> Toggle an LED every 500ms.
- Task 2 -> Turn an LED on and off every 500ms.
- Task 3 -> If a button is pressed, turn on an LED; else, turn it off.
- Task 4 -> Pressing a button increments a 4-bit binary counter whose output is shown on 4 LEDs.
Requirements: DIO driver with 5 APIs + 2 tasks.
MDIO_enuErrorStatus_t MDIO_enuSetPinConfigration(Copy_enuPortNum,Copy_enuPinNum,Copy_enuConfigration);
MDIO_enuErrorStatus_t
MDIO_enuSetPortConfigration(Copy_enuPortNum,Copy_enuConfigration);
MDIO_enuErrorStatus_t
MDIO_enuSetPinValue( Copy_enuPortNum, Copy_enuPinNum, Copy_enuState);
MDIO_enuErrorStatus_t
MDIO_enuSetPortValue(Copy_enuPortNum,Copy_enuPortState);
MDIO_enuErrorStatus_t
MDIO_enuGetPinValue(Copy_enuPortNum,Copy_enuPinNum,u8* Add_pu8PinValue);
- Task 1 -> Multiple buttons control the states of multiple LEDs.
- Task 2 -> Pressing a button should start an 8-bit binary counter whose output is displayed on 8 LEDs.
Requirements: An additional API for DIO driver + 1 task.
void MDIO_vInit(void);
- Task 1 -> Toggle 3 LEDs' state using 3 buttons. These components should all be initialized using the newly-created API.
Requirements: MPORT driver with 2 APIs + migrate
MDIO_vInit
to MPORT driver.
MPORT_enuErrorStatus_t
MPORT_enuSetPinDirection( u8 Copy_enuPinNum , u8 Copy_enuPinDirection );
MPORT_enuErrorStatus_t
MPORT_enuSetPinMode( u8 Copy_enuPinNum , MPORT_enuPinMode_t Copy_enuPinMode );
void
MPORT_voidInit(void);
Requirements: HAL drivers for LED and SWITCH; each with 2 APIs.
/* LED */
void LED_init(void);
LED_enuErrorStatus_t LED_enuSetLedState(u8 Copy_u8LedName, u8 Copy_u8State);
/* SWITCH */
void SWITCH_init(void);
SWITCH_enuErrorStatus_t SWITCH_enuGetSwitchState(u8 Copy_u8SwitchName, u8* Add_pu8State);
Requirements: Modify all already-implemented drivers to match MISRA C guidelines. Details: Eliminated all
goto
statements + addedelse
for everyif
+ used C's commenting style/**/
instead of Cpp's//
.
Requirements: HAL driver for 7 Segment Display with 3 APIs.
void HSEVENSEG_vInit(void);
void HSEVENSEG_vSetValue(u8 Copy_enuSevenSegNum , u8 Copy_u8Value);
HSEVENSEG_enuErrorStatus_t HSEVENSEG_enuSetMultiDigitValue(u16 Copy_u16Value);
Requirements: HAL driver for LCD with 7 APIs.
void HLCD_voidInit(void);
void HLCD_voidWriteData(char data);
void HLCD_voidWriteCommand(uint8_t command);
void HLCD_voidGoToXY(uint8_t X, uint8_t Y);
void HLCD_voidDisplaySpecialChar(char* pattern, uint8_t X, uint8_t Y);
void HLCD_voidWriteString(char* str);
void HLCD_voidWriteNumber(uint32_t number);
Requirements: HAL driver for Keypad with 2 APIs.
void HKEYPAD_voidInit(void);
ErrorStatus_t HKEYPAD_enuGetKey(uint8_t* char);
Requirements: MCAL driver for EXTI with 2 APIs.
void EXTI_init(void);
void EXTI_registerCBF(EXTI_CBF_t cbf);
Requirements: MCAL driver for Timer with 6 APIs.
MTIMER_enuErrorStatus_t MTIMER_enuInit(MTIMER_enuTimers_t copy_enuTimer);
MTIMER_enuErrorStatus_t MTIMER_enuSetOverflowVal(MTIMER_enuTimers_t copy_enuTimer, uint32_t copy_uint32PreloadVal);
MTIMER_enuErrorStatus_t MTIMER_enuSetClkSelection(MTIMER_enuTimers_t copy_enuTimer, MTIMER_enuClockSelection_t copy_enuClkSel);
MTIMER_enuErrorStatus_t MTIMER_enuSetOutputCompareVal(MTIMER_enuTimers_t copy_enuTimer, uint8_t copy_uint32PreloadVal);
MTIMER_enuErrorStatus_t MTIMER_enuGetCounterVal(MTIMER_enuTimers_t copy_enuTimer, uint32_t* ptr_uint32CounterVal);
MTIMER_enuErrorStatus_t MTIMER_enuSetTimerCallBack(MGIE_CallBackFunction_t ptr_ISR, MGIE_enuVectorTable_t copy_enuISRNum);
-
Task 1 (Tested on Hardware)
-
Task 2 (Tested on Hardware)
-
Task 3 (Tested on Hardware)
-
Task 4 (Tested on Hardware)
-
MDIO Driver (Tested on Hardware && Proteus)
-
Task 1 (Tested on Proteus)
-
Task 2 (Tested on Proteus)
- Task 1 (Tested on Proteus)
- MPORT Driver (Tested on Hardware && Proteus)
- Task 1 (Tested on Hardware && Proteus)
- HLED Driver (Tested on Hardware && Proteus)
- HSWITCH Driver (Tested on Hardware && Proteus)
- Used cppcheck to see if my code breaks MISRA-C's guidelines.
- H7SEGMENT Driver (Tested on Hardware && Proteus)
- HLCD Driver (Tested on Proteus)
- HKEYPAD Driver (Tested on Proteus)
- MEXTI Driver (Builds Successfully But Not Tested Yet)
- GIE Driver (Builds Successfully But Not Tested Yet --- EXTRA)