libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
Programmer's Manual for `libmicroemu`

Introduction

Welcome to the Programmer's Manual for the libmicroemu Library!

It is a work in progress and will be updated regularly.

Overview of the Library

Namespaces

  • Public Namespace:
    All user-accessible features are within libmicroemu.
  • Private Namespace:
    Internals of the library reside in libmicroemu::internal. These are not accessible to library users.

Key Classes

  • libmicroemu::Machine:
    The primary class for controlling the emulator. It allows configuration, ELF loading, and execution.
  • libmicroemu::CpuStates:
    Encapsulates the emulator's state, including CPU registers and exception states.
  • libmicroemu::ExecResult:
    Represents the result of an emulation run, detailing why execution stopped.

Error Management

Logging

Overview

  • Purpose:
    Logging in libmicroemu is used for tracking emulator activity, debugging, and performance monitoring.

Logging Configuration

  1. Registering a Callback:
    • Use libmicroemu::Machine::RegisterLoggerCallback.
    • Callback is static for performance reasons.
    • Expected function signature is clearly defined.
  2. Log Levels:

Built-In Loggers

  1. libmicroemu::StaticLogger:
    Outputs logs to static files or predefined locations.
  2. libmicroemu::NullLogger:
    Disables logging entirely for performance-critical applications.

Typical Usage

Here’s an example demonstrating a typical use case for the emulator:

Example Code

#include <iostream>
#include <vector>
// Path to the ELF file
constexpr static const char *kElfPath = "coremark/prebuilt/bin/coremark.elf";
constexpr static libmicroemu::me_adr_t kFlashSegVadr = 0x0U;
constexpr static libmicroemu::me_adr_t kRam1SegVadr = 0x20000000U;
int main() {
std::cout << "Using libmicroemu version: " << machine.GetVersion() << std::endl;
// Allocate memory for FLASH and RAM1 segments
auto flash_seg = std::vector<uint8_t>(0x20000u); // 128KB for FLASH
auto ram1_seg = std::vector<uint8_t>(0x40000u); // 256KB for RAM1
// Set up memory segments
machine.SetFlashSegment(flash_seg.data(), flash_seg.size(), kFlashSegVadr);
machine.SetRam1Segment(ram1_seg.data(), ram1_seg.size(), kRam1SegVadr);
// Load the ELF file and set the entry point
if (machine.Load(kElfPath, true) != libmicroemu::StatusCode::kSuccess) {
std::cerr << "Failed to load ELF file." << std::endl;
return EXIT_FAILURE;
}
// Execute the ELF file
auto res_exec = machine.Exec();
if (res_exec.IsErr()) {
std::cerr << "Failed to execute ELF file." << std::endl;
return EXIT_FAILURE;
}
return 0;
}
Represents the main emulation machine for handling microcontroller emulation.
Definition machine.h:54
std::string_view GetVersion() noexcept
Gets the version of the library.
Definition machine.cpp:146
ExecResult Exec(i64 max_instructions=-1, FPreExecStepCallback cb_pre_exec=nullptr, FPostExecStepCallback cb_post_exec=nullptr) noexcept
Executes the loaded program.
Definition machine.cpp:123
void SetRam1Segment(u8 *seg_ptr, me_size_t seg_size, me_adr_t seg_vadr) noexcept
Sets the RAM1 segment The RAM1 segment is where a microcontroller stores its data....
Definition machine.cpp:101
void SetFlashSegment(u8 *seg_ptr, me_size_t seg_size, me_adr_t seg_vadr) noexcept
Sets the Flash segment The flash segment is where a microcontroller stores its program code....
Definition machine.cpp:95
StatusCode Load(const char *elf_file, bool set_entry_point=false) noexcept
Loads an ELF file into memory and optionally sets the entry point.
Definition machine.cpp:27
Contains the Machine class which is the main emulation machine for handling microcontroller emulation...
@ kSuccess
Operation succeeded successfully.
Definition status_code.h:20

Step 1: Memory Setup

Step 2: Load ELF Files

  • Load an ELF file using libmicroemu::Machine::Load.
  • Ensure the allocated FLASH memory can accommodate the ELF file contents.
  • Set the entry point either automatically (from the ELF file) or manually.
  • If the entry point is not set from the ELF file, the reset vector specifies the entry point.

Step 3: Start Emulation

  • Start emulation with libmicroemu::Machine::Exec.
  • Emulation stops under specific conditions:
    • Reaching a maximum instruction count (useful for coroutine-like workflows).
    • Program exit via:
      • SVC call.
      • Semihosting, e.g., exit() in the emulated program (handles termination automatically).

Extensibility

TBD