#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
// ============================================================================
// 2. Struct with bit-fields summing to exactly 16 bits
// ============================================================================
typedef struct BitFields{
unsigned int field1 : 4;
unsigned int field2 : 4;
unsigned int field3 : 4;
unsigned int field4 : 4;
} BitFields;
// ============================================================================
// 1. Pass an int by reference
// ============================================================================
void int_by_ref(int *ptr){
if (ptr != NULL){
*ptr = *ptr + 4;
printf("pointer is not null\n");
}
}
// ============================================================================
// 3. 100-element array on stack vs heap — print both addresses
// ============================================================================
void array_100_elements (){
int stack[100];
int *heap = (int*)malloc(100 * sizeof(int));
printf("Stack array address: %p\n", (void*)stack);
printf("Heap array address: %p\n", (void*)heap);
free(heap);
}
// ============================================================================
// 4. UB pitfall + safe version next to it
// ============================================================================
void UB_pitfall(){
int near_max = 2147483640; // Close to signed INT_MAX
int add = 20;
// PITFALL (Undefined Behavior): Signed integer overflow is UB in C
if (near_max + add < near_max) {
printf("UB Pitfall: Overflow!\n");
}
// SAFE VERSION: Check boundaries before doing the addition
if (add > __INT_MAX__ - near_max) {
printf("Safe Version, overflow avoided\n");
}
else {
near_max += add;
}
}
// ============================================================================
// 5. volatile for an MMIO read
// ============================================================================
void mmio_read(){
// Dummy address mimicking a Memory-Mapped I/O hardware register
uint32_t simulated_register = 0x1;
// CRITICAL WHY: Tells the compiler that the value can change due to hardware actions outside
// the code's sight, forcing a real memory/bus read instruction every single time.
// WHAT IT DOES NOT GIVE YOU: Atomicity or thread-safety synchronization across dual cores.
volatile uint32_t *mmio_reg = &simulated_register;
uint32_t reg_val = *mmio_reg;
printf("Volatile Read MMIO register state: 0x%02lx\n", reg_val);
}
// ============================================================================
// 6. Static Inline Demo
// ============================================================================
static inline int fast_multiply_by_4(int val) {
return val << 2; // Fast multiplication using a bit-shift operation
}
//the compiler will ignore the hint, generating a normal, separate function block in
//assembly memory anyway under these common conditions:
//Debugging is turned on
//You take the function's address
//The function is too long or complex
void app_main() {
printf("--- Starting HW2 Concept Demonstrations ---\n\n");
// 1. Pass an int by reference demo
int my_number = 50;
printf("[1] Before pass-by-reference: my_number = %d\n", my_number);
int_by_ref(&my_number);
printf("[1] After pass-by-reference: my_number = %d\n\n", my_number);
// 2. Struct with bit-fields size check
BitFields sample_fields = { .field1 = 1, .field2 = 2, .field3 = 3, .field4 = 4 };
printf("[2] Size of BitFields struct: %d bytes (Exactly 16 bits total)\n\n", (int)sizeof(sample_fields));
// 3. Stack vs Heap addresses
array_100_elements();
printf("\n");
// 4. UB pitfall vs Safe check
UB_pitfall();
printf("\n");
// 5. Volatile MMIO read
mmio_read();
printf("\n");
// 6. Static Inline function replacement execution
int inline_input = 10;
int inline_output = fast_multiply_by_4(inline_input);
printf("[6] Static Inline evaluation: %d * 4 = %d\n\n", inline_input, inline_output);
printf("--- All HW2 Demonstrations Completed successfully! ---\n");
// Infinite system background loop to keep the execution alive in Wokwi
while (true) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1