Skip to content

A Python based Jinja System for creating C++ Headers for Embedded Programming

Notifications You must be signed in to change notification settings

emrainey/peripheralyzer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

peripheralyzer

A Python based Jinja System for creating C++ Headers or C Headers for Embedded Programming of memory mapped peripherals.

Step One

transmogrify.py allows you to convert CMSIS SVD files into the yaml format that the peripheralyzer.py supports. You can get SVD files from ARM. The description of what a SVD could contain is here.

python3 transmogrify.py -s STM32F407.svd -yr svd -ns cmsis -ns stm32 -nm STM32F407_name_map.yml

This will arrange all peripherals into the cmsis::stm32 namespace in C++ (after the next step). This will also emit a renaming map which will maps the weird CMSIS names like DADDR to reasonable names like DestinationAddress. Merely change all the names and types you'd like and re-run the transmogrify step, as it will read the file in before processing, then use it, then write it back out.

An example of the naming map file:

ACTIVE:
  as_type: ACTIVE
  as_variable: active
  context:
  - NVIC.IABR0
  - NVIC.IABR1
  - NVIC.IABR2

Step Two

peripheralyzer.py allows you to convert from something like this:

include_lock: TEST_H_
includes:
- <cstdint>
namespaces:
- testing
peripheral:
    name: Test
    sizeof: 0x10
    default_type: std::uint32_t
    default_depth: 32
    members:
        - name: first
          type: std::uint8_t
          offset: 0x0
          count: 4
          sizeof: 4
        - name: second
          offset: 0x4
        - name: third
          type: float
          offset: 0x8
          sizeof: 4
        - name: fourth
          type: std::uint16_t
          offset: 0xC
          count: 2
          sizeof: 4

Into C++ Peripherals, Registers, and Enumerations with proper include name locks, namespaces, bitfield unions, and static_asserts for all field offsets and sizeofs.

The YAML is organized into a hierarchy of:

  • Peripherals
    • [optional] Enumerations
    • [optional] Structures
    • Registers
      • [optional] Enumerations
      • (bit) Fields Structure

Each of these is scoped within it's container.

This is an example of a generated structure.

#ifndef TEST_H_
#define TEST_H_
/// @file
/// Auto Generated Structure Definitions for Test from the Peripheralyzer.
/// @copyright
#include <cstdint>
namespace testing {
struct Test final {
    std::uint8_t first[4]; // offset 0x0UL
    std::uint32_t second; // offset 0x4UL
    float third; // offset 0x8UL
    std::uint16_t fourth[2]; // offset 0xcUL
};
// Ensure the structure is in standard layout format
static_assert(std::is_standard_layout<Test>::value, "Must be standard layout");
// Ensure the offsets are all correct
static_assert(offsetof(Test, first) == 0x0UL, "Must be located at this offset");
static_assert(offsetof(Test, second) == 0x4UL, "Must be located at this offset");
static_assert(offsetof(Test, third) == 0x8UL, "Must be located at this offset");
static_assert(offsetof(Test, fourth) == 0xcUL, "Must be located at this offset");
// Ensure the sizeof the entire structure is correct.
static_assert(sizeof(Test) == 0x10UL, "Must be this exact size");
}  // namespace testing
#endif // TEST_H_

The table below summarizes some of the differences of differences between the two generations.

C17 Code Generation C++14 Code Generation
Peripherals, Structures and Registers are final to prevent inheritance and virtual issues -- Yes
Peripherals, Structures, Enums and Registers namespace scoping global limited
Headers are #ifndef locked. No pragma once Yes Yes
Bitfields are structures contained within anonymous unions Yes Yes
Peripherals, Structures and Registers are sizeof and offsetof checked Yes Yes
Registers have operator overloads to make the load, modify, store cycle easier -- Yes
Registers have associated functions to make load, modify, store cycle easier but with null checks Yes No
enum can be typed No Yes
Generates Unit Tests for all fields in unions Yes Yes

About

A Python based Jinja System for creating C++ Headers for Embedded Programming

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published