Lightweight Framework for Embedded Systems

Follow+Star Public Account, don’t miss exciting content

Lightweight Framework for Embedded Systems

Material Source | Network

Today I will share an open-source, lightweight framework designed specifically for embedded systems.

Introduction to mr-library

MR framework is a lightweight framework specifically designed for embedded systems, fully considering the resource and performance requirements of embedded systems. By providing standardized device management interfaces, it greatly simplifies the difficulty of embedded application development, helping developers quickly build embedded applications.

The framework provides standardized interfaces for developers to open (open), close (close), control (ioctl), read (read), and write (write). It decouples the application from the underlying hardware drivers, allowing the application to operate without needing to understand the implementation details of the drivers.

When hardware changes, only the underlying driver needs to be adapted, and the application can seamlessly migrate to the new hardware. This greatly enhances the reusability of the software and the scalability to new hardware.

Lightweight Framework for Embedded Systems
Project Structure Diagram

Key Features

  • Standardized device access interfaces
  • Decoupling application and driver development
  • Simplifying low-level driver and application development
  • Lightweight and easy to use, low resource consumption
  • Modular design, decoupled and independently developed components, extremely low hardware migration costs
  • Supports use in bare-metal and operating system environments

Main Components

  • Device framework: Provides standardized device access interfaces
  • Memory management: Dynamic memory management
  • Tools: Common data structures such as linked lists, queues, balanced trees
  • Various functional components

Standardized Device Interfaces

All operations on devices can be implemented through the following interfaces:

Interface Description
mr_dev_register Register device
mr_dev_open Open device
mr_dev_close Close device
mr_dev_ioctl Control device
mr_dev_read Read data from device
mr_dev_write Write data to device

Example:

struct mr_spi_dev spi_dev;

int main(void)
{
    /* Register SPI10 device (CS active low) to SPI1 bus */
    mr_spi_dev_register(&spi_dev, "spi1/spi10", 0, MR_SPI_CS_ACTIVE_LOW);

    /* Open SPI10 device under SPI1 bus */
    int ds = mr_dev_open("spi1/spi10", MR_OFLAG_RDWR);
    
    /* Send data */
    uint8_t wr_buf[] = {0x01, 0x02, 0x03, 0x04};
    mr_dev_write(ds, wr_buf, sizeof(wr_buf));
    
    /* Receive data */
    uint8_t rd_buf[4] = {0};
    mr_dev_read(ds, rd_buf, sizeof(rd_buf));
    
    /* Close device */
    mr_dev_close(ds);
}

Configuration Tool

MR provides a Kconfig visual configuration tool, allowing developers to configure without needing to delve into the source code.

Kconfig automatically generates a configuration options interface based on the configuration file. Developers can select the required functional components and set related parameters through simple operations.

Lightweight Framework for Embedded Systems
Configuration Tool
Lightweight Framework for Embedded Systems
Configuration Tool 1

By modifying parameters, quickly trim the required functions. After configuration, the configuration file is automatically generated using a Python script.

Directory Structure

Name Description
bsp Board Support Package
components Components
device Device files
document Documentation
driver Driver files
include Library header files
source Library source files
Kconfig Configuration file
kconfig.py Automatic configuration script
LICENSE License

Getting Started

Configure Kconfig Environment

Note: Kconfig is not mandatory, but it is recommended (installation and configuration are very quick, and subsequent tutorials will also use Kconfig as an example).

  1. Verify if the Python environment is installed. Run python --version in the command line to check the Python version (Kconfig depends on python, if there is no python environment, please install it yourself).

  2. Use the command shown in the command line to install Kconfig:

    python -m pip install windows-curses
    python -m pip install kconfiglib
    
  3. Run menuconfig -h in the command line to verify if the installation was successful.

Import the Framework into the Project

  1. Download the latest version of the source code from the Gitee or Github repository to your local machine.

  2. Import the source code into the directory where your project is located. For example, in the STM32 project:

    Lightweight Framework for Embedded Systems
    Project Directory
  3. If the chip you are using has already been adapted with BSP, please refer to the configuration tutorial in the corresponding BSP to complete the BSP configuration.

  4. Remove unnecessary files and directories such as bsp, document, module (if GIT is not needed, you can also delete the .git file). After completion, the directory structure is as follows:

    Lightweight Framework for Embedded Systems
    Project Directory 1
  5. Add the files to the IDE (most IDEs can automatically recognize the files under the project path, no need to perform this step). For example, in keil:

    Lightweight Framework for Embedded Systems
    Project Directory Keil

    Add all files under source, device, and driver directories.

Configure Menu Options

  1. Open the command line tool in the mr-library directory and run menuconfig for menu configuration.

    Lightweight Framework for Embedded Systems
    Project Directory 2

    Note: When adding the corresponding chip driver, Device configure and Driver configure will be displayed. Please refer to the tutorial under BSP for Driver configure.

  2. Select Device configure and press Enter to enter the menu, configuring functions as needed.

    Lightweight Framework for Embedded Systems
    Project Directory 3
  3. After configuration is complete, press Q to exit the menu configuration interface, and press Y to save the configuration.

Generate Configuration File

  1. Open the command line tool in the mr-library directory and run python kconfig.py to automatically generate the configuration file mr_config.h.

Add Include Path

  1. Add the include path of mr-library in the compiler, taking keil as an example:

    Lightweight Framework for Embedded Systems
    Project Directory 4
  2. Configure automatic initialization (GCC environment), find the linker script file with the suffix .ld under your project (usually link.ld), and add the following code to the script file: Note: If you are in an environment like keil that can automatically generate linker scripts, please skip this step.

    /* mr-library auto init */
    . = ALIGN(4);
    _mr_auto_init_start = .;
    KEEP(*(SORT(.auto_init*)))
    _mr_auto_init_end = .;
    

    Example:

    Lightweight Framework for Embedded Systems
    Project Directory 5
  3. Configure GNU syntax. If you are using a non-GCC compiler, please enable GNU syntax. For example, keil:

    AC5:

    Lightweight Framework for Embedded Systems
    Project Directory 6

    AC6:

    Lightweight Framework for Embedded Systems
    Project Directory 7
  4. In your project, include #include "include/mr_lib.h".

  5. Add mr_auto_init(); automatic initialization function in the main function.

Let’s Light Up

#include "include/mr_lib.h"

/* Define LED pin (PC13)*/
#define LED_PIN_NUMBER                  45

int main(void)
{
    /* Automatic initialization */
    mr_auto_init();

    /* Open PIN device */
    int ds = mr_dev_open("pin", MR_OFLAG_RDWR);
    /* Set to LED pin */
    mr_dev_ioctl(ds, MR_CTL_PIN_SET_NUMBER, mr_make_local(int, LED_PIN_NUMBER));
    /* Set LED pin to push-pull output mode */
    mr_dev_ioctl(ds, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT));

    while(1)
    {
        /* Light up LED */
        mr_dev_write(ds, mr_make_local(uint8_t, MR_PIN_HIGH_LEVEL), sizeof(uint8_t));
        mr_delay_ms(500);
        mr_dev_write(ds, mr_make_local(uint8_t, MR_PIN_LOW_LEVEL), sizeof(uint8_t));
        mr_delay_ms(500);
    }
}

Hello World

#include "include/mr_lib.h"

int main(void)
{
    /* Automatic initialization */
    mr_auto_init();

    /* Open Serial-1 device */
    int ds = mr_dev_open("serial1", MR_OFLAG_RDWR);
    /* Output Hello World */
    mr_dev_write(ds, "Hello World\r\n", sizeof("Hello World\r\n"));
    
    while(1);
}
Open Source Address:

https://gitee.com/MacRsh/mr-librar

———— END ————

Lightweight Framework for Embedded Systems

● Column “Embedded Tools”

● Column “Embedded Development”

● Column “Keil Tutorial”

● Selected Tutorials from Embedded Column

Follow the public account reply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Click “Read the Original” to see more shares.

Leave a Comment