Skip to content

Core API

The Core API provides fundamental system initialization and control functions for the EmbSec SDK.

Overview

The core module is the foundation of the SDK, providing:

  • System initialization
  • Interrupt management
  • System control functions
  • Basic timing utilities
  • Version information
#include <embsec/embsec.h>

System Initialization

embsec_init

void embsec_init(void);

Initialize the EmbSec environment. This function must be called before using any other SDK functions.

The initialization process:

  1. Configures system clock to 80MHz
  2. Initializes UART0 for console I/O (115200 baud, 8N1)
  3. Sets up SysTick timer for millisecond timing
  4. Configures basic GPIO for LEDs and switches
  5. Seeds the random number generator

Example:

int main(void) {
    // Always initialize first
    embsec_init();

    // Now safe to use other SDK functions
    embsec_printf("System initialized!\n");

    // Main application loop
    while (1) {
        // Application code
    }
}

embsec_is_initialized

bool embsec_is_initialized(void);

Check if the EmbSec SDK has been initialized.

Returns:

  • true if embsec_init() has been called successfully
  • false otherwise

Example:

if (!embsec_is_initialized()) {
    // Handle error - SDK not initialized
    return -1;
}

System Control

embsec_system_reset

void embsec_system_reset(void);

Perform a software reset of the microcontroller. This function does not return.

Example:

if (critical_error) {
    embsec_printf("Critical error! Resetting system...\n");
    embsec_uart_flush();  // Ensure message is sent
    embsec_system_reset();
}

embsec_enable_interrupts

void embsec_enable_interrupts(void);

Enable interrupts globally. This is equivalent to the ARM CPSIE I instruction.

embsec_disable_interrupts

void embsec_disable_interrupts(void);

Disable interrupts globally. This is equivalent to the ARM CPSID I instruction.

Example:

// Critical section
embsec_disable_interrupts();

// Modify shared data safely
shared_counter++;

embsec_enable_interrupts();

embsec_memory_barrier

static inline void embsec_memory_barrier(void);

Insert a memory barrier to ensure all memory operations complete before continuing. This prevents compiler and CPU reordering of memory accesses.

Example:

// Write to hardware register
*hardware_reg = value;

// Ensure write completes before continuing
embsec_memory_barrier();

// Safe to proceed

Timing Functions

embsec_get_tick_ms

uint32_t embsec_get_tick_ms(void);

Get the current system tick count in milliseconds since boot.

Returns:

  • Millisecond count since system initialization
  • Wraps around after approximately 49.7 days

Example:

uint32_t start = embsec_get_tick_ms();

// Do some work
perform_operation();

uint32_t elapsed = embsec_get_tick_ms() - start;
embsec_printf("Operation took %u ms\n", elapsed);

embsec_delay_ms

void embsec_delay_ms(uint32_t ms);

Delay execution for the specified number of milliseconds. This is a blocking delay.

Parameters:

  • ms: Number of milliseconds to delay

Example:

// Blink LED
embsec_led_set(EMBSEC_LED_RED, true);
embsec_delay_ms(500);
embsec_led_set(EMBSEC_LED_RED, false);
embsec_delay_ms(500);

Version Information

embsec_get_version

const char *embsec_get_version(void);

Get the SDK version string.

Returns:

  • Version string in format "major.minor.patch" (e.g., "1.0.0")

Example:

embsec_printf("EmbSec SDK Version: %s\n", embsec_get_version());
embsec_printf("Build Date: %s %s\n", __DATE__, __TIME__);

Best Practices

Initialization Order

Always follow this initialization pattern:

int main(void) {
    // 1. Initialize SDK first
    embsec_init();

    // 2. Print startup message
    embsec_printf("\n=== My Application v1.0 ===\n");
    embsec_printf("SDK Version: %s\n", embsec_get_version());

    // 3. Application-specific initialization
    app_init();

    // 4. Main loop
    while (1) {
        app_main_loop();
    }
}

Interrupt Safety

When working with interrupts:

// Save interrupt state
bool int_state = __get_PRIMASK();
embsec_disable_interrupts();

// Critical section
modify_shared_data();

// Restore interrupt state
if (!int_state) {
    embsec_enable_interrupts();
}

Error Handling

Implement robust error handling:

typedef enum {
    STATUS_OK = 0,
    STATUS_INIT_FAILED = -1,
    STATUS_INVALID_PARAM = -2
} status_t;

status_t app_init(void) {
    if (!embsec_is_initialized()) {
        return STATUS_INIT_FAILED;
    }

    // Application initialization
    return STATUS_OK;
}

Hardware Notes

Clock Configuration

The SDK configures the system for optimal performance:

  • Main oscillator: 16MHz crystal
  • PLL output: 400MHz
  • System clock: 80MHz (PLL/5)
  • APB clock: 40MHz

Memory Map

Key memory regions on TM4C123GH6PM:

  • Flash: 0x00000000 - 0x0003FFFF (256KB)
  • SRAM: 0x20000000 - 0x20007FFF (32KB)
  • Peripherals: 0x40000000 - 0x400FFFFF

Power Consumption

For low-power applications:

  • System runs at full speed (80MHz) by default
  • No sleep modes are configured
  • All peripherals remain powered

Common Issues

Initialization Forgotten

Symptom: Functions hang or crash Solution: Always call embsec_init() first

Stack Overflow

Symptom: Random crashes or resets Solution: Increase stack size in linker script

Interrupt Priorities

Symptom: Timing functions inaccurate Solution: Don't disable interrupts for extended periods

Example: Complete Core Usage

#include <embsec/embsec.h>
#include <embsec/uart.h>
#include <embsec/gpio.h>

int main(void) {
    // Initialize SDK
    embsec_init();

    // Print banner
    embsec_printf("\n=====================================\n");
    embsec_printf("EmbSec Core API Demo\n");
    embsec_printf("SDK Version: %s\n", embsec_get_version());
    embsec_printf("=====================================\n\n");

    // Demonstrate timing
    embsec_printf("System running for %u ms\n", embsec_get_tick_ms());

    // Blink LED 3 times
    for (int i = 0; i < 3; i++) {
        embsec_led_set(EMBSEC_LED_GREEN, true);
        embsec_delay_ms(200);
        embsec_led_set(EMBSEC_LED_GREEN, false);
        embsec_delay_ms(200);
    }

    // Main loop
    uint32_t last_print = embsec_get_tick_ms();

    while (1) {
        // Print uptime every 5 seconds
        if (embsec_get_tick_ms() - last_print >= 5000) {
            uint32_t uptime_sec = embsec_get_tick_ms() / 1000;
            embsec_printf("Uptime: %u:%02u\n", 
                         uptime_sec / 60, uptime_sec % 60);
            last_print = embsec_get_tick_ms();
        }

        // Check for user input
        if (embsec_kbhit()) {
            char c = embsec_getchar();
            if (c == 'r' || c == 'R') {
                embsec_printf("Reset requested...\n");
                embsec_uart_flush();
                embsec_system_reset();
            }
        }
    }
}

This example demonstrates:

  • Proper initialization
  • Version reporting
  • Basic timing functions
  • LED control
  • Interactive reset command