PHiLIP PAL (PHiLIP Protocol Abstraction Layer)

A set of python modules that abstract away and standardize shell based command for bare metal memory map access. PHiLIP PAL is used to interface to a memory map specified from a csv or by the device. It handles the parsing of offsets, sizes, etc. of the device.

To use this interface a memory must be provided, by default the package contains the PHiLIP memory map for all the versions. If a development version of PHiLIP is used and a memory map has not been released, the memory map can be scanned from the device.

PHiLIP PAL provides a philip_shell which developers can use for manual tests and interacting with PHiLIP.

For automated scripts, a Phil() class is provided.

memory_map_manager

To keep PHiLIP easily adaptable while maintaining a low memory footprint, the MMM was developed as a code generator for coordinating application information from a single configuration file. This reduces human error when adding or changing runtime parameters, improves development speed, and the information can be fed into tests with various interfaces. The JSON configuration file follows a schema that can provide named packed structures to embedded devices, and allows for documentation of the register map. Structures and parameter properties such as type, array size, or testing flags are defined from the configuration file, as well as default values, access levels, and information for describing the parameters. The registers are serialized and can be accessed as a structure (by name) or byte array (by address). For example:

my_map_t app_reg = {0};

uint8_t get_address_based_data(size_t index) {
  return app_reg.data8[index];
}

void name_based_access() {
  app_reg.my_stuff = OTHER_STUFF;
}

Describing the memory map based on parameter names with the respective types and sizes combines the versatility of named access with the efficiency of serialized packed memory. The interface only needs to translate the name to an offset and size to get the information. The simplicity of implementing only read and write register commands to deal with each parameter reduces bugs on the embedded device. The generated output of the MMM is C style data and consumed by the firmware application. By convention, parameters can be changed by writing registers, similar to MCUs or sensors. To initiate a change in properties, for example, altering the I2C address on PHiLIP, an initialization bit should be set before calling the command to execute changes. This allows for a peripheral to be configured only once, preventing possible initialization sequence errors.

The memory map manager has an input configuration tool to help expose and step through all the options available for defining the memory map. A prefilled example is also available

mm_pal (Memory Map Protocol Abstraction Layer)

Python package for providing an runtime access to embedded devices based on a memory map type interface.

Device connection such as serial and parsers such as json are used to get standard output.

Concept

Embedded devices are generally constrained and communication with runtime parameters can take up lots of resources. Since many users of microcontroller are familiar with the concept of a memory map or register map the Memory Map Manager can be used as and lightweight way of coordinating a single memory map for documentation, C structures, and python interface. The mm_pal provides the building blocks for a custom interface. All common functions related to connecting to the device, parsing output of the registers, and reading/writing to the registers are handled and only application specific functionality needs to be implemented. This can make development easier, especially when the registers are changing frequently.

Architecture

┏━━━━━━━━━━━┓       ┏━━━━━━━━━┓
┃ developer ┃       ┃ script  ┃
┗━━━━━▲━━━━━┛       ┗━━━━▲━━━━┛
      ┃                  ┃
 ┏━━━━┸━━━━┓       ┏━━━━━┸━━━━━┓
 ┃ my_cli  ◄━━━━━━━┫ my_app_if ┃
 ┗━━━━▲━━━━┛       ┗━━━━━▲━━━━━┛
      ┃    ┌────────┐    ┃
      ┃    │ mm_pal │    ┃
┌─────╂────┴────────┴────╂────────┐
│┏━━━━┸━━━┓          ┏━━━┸━━━┓    │
│┃ mm_cmd ◄━━━━━━━━━━┫ mm_if ┃    │
│┗━━━━━━━━┛          ┗━━━▲━━━┛    │
│                        ┃        │
│                ┏━━━━━━━┸━━━━━━━┓│
│                ┃ serial_driver ┃│
│                ┗━━━━━━━▲━━━━━━━┛│
└────────────────────────╂────────┘
                         ┃
              ┏━━━━━━━━━━▼━━━━━━━━━━┓
              ┃ my_embedded_device  ┃
              ┗━━━━━━━━━━━━━━━━━━━━━┛

The mm_cmd is based on the cmd2 module is probably worth reading the documentation.

Special thanks to riotctrl as it served as a great example.