Recommend a lightweight embedded system framework

Introduction to mr-library

mr-library is a lightweight framework for embedded systems. It provides a unified underlying driver device model and basic service functions. It has the characteristics of modular design, configurability and scalability, and can help Developers quickly build embedded applications.

The mr-library framework supports basic kernel functions such as mutex locks and object management. Integrate asynchronous event-driven framework (event), multi-time base software timer (soft-timer) and other services. Provide driver device models for common peripherals such as serial ports, SPI, I2C, ADC/DAC, etc., access underlying hardware devices through a unified driver interface (open, close, ioctl, read, write), and decouple underlying drivers and applications.

Application scenarios

  • Low-level driver developed by MCU.

  • Plug-in framework for RTOS real-time operating system (used as a driver device framework).

  • Rapid development of various IoT and smart hardware products.

Driver Device Framework

Developers can access peripherals in an object-oriented manner, simplifying the development process of driver logic. The framework implements universal driver templates for commonly used peripherals, and developers can quickly port them to different hardware platforms.

The driver device framework supports common interfaces for common devices, automatic bus control of bus devices, and interrupt takeover of multiple devices.

Driver device interface

The device driver framework provides a unified operation interface. All operations of the device need to be implemented through the following interfaces:

Interface Description
mr_device_add Add device
mr_device_find Find device
mr_device_open Open device
mr_device_close Close the device
mr_device_ioctl Control the device
td>
mr_device_read Read data from the device
mr_device_write Write to the device Enter data

SPI device usage example:

/* Define SPI device */
#define SPI_DEVICE0_CS_PIN 10
#define SPI_DEVICE1_CS_PIN 20
struct mr_spi_device spi_device0, spi_device1;

/* Add SPI device */
mr_spi_device_add( & amp;spi_device0, "spi10", SPI_DEVICE0_CS_PIN);
mr_spi_device_add( & amp;spi_device1, "spi11", SPI_DEVICE1_CS_PIN);

/* Find SPI device */
mr_device_t spi0_device = mr_device_find("spi10");
mr_device_t spi1_device = mr_device_find("spi11");

/* Mount bus */
mr_device_ioctl(spi0_device, MR_CTRL_ATTACH, "spi1");
mr_device_ioctl(spi1_device, MR_CTRL_ATTACH, "spi1");

/* Open the SPI device in a readable and writable manner */
mr_device_open(spi0_device, MR_OPEN_RDWR);
mr_device_open(spi1_device, MR_OPEN_RDWR);

/* send data */
char buffer0[] = "hello";
char buffer1[] = "world";
mr_device_write(spi0_device, 0, buffer0, sizeof(buffer0) - 1);
mr_device_write(spi1_device, 0, buffer1, sizeof(buffer1) - 1);

/* Read data */
mr_device_read(spi0_device, 0, buffer0, sizeof(buffer0) - 1);
mr_device_read(spi1_device, 0, buffer1, sizeof(buffer1) - 1);

/* Shut down the device */
mr_device_close(spi0_device);
mr_device_close(spi1_device);

Service Framework

The mr-library framework integrates a lightweight service framework for building application services in embedded development, supporting asynchronous event monitoring, multi-time base software timers, etc. The service framework is used to complete the decoupling of different applications in the application layer, achieving modularization and tailorability of applications, clear business logic, rapid development, and high code reuse.

Event Service

Event service is an asynchronous event processing mechanism that can effectively improve the asynchronous processing capabilities, decoupling and scalability of the system through event distribution and callbacks.

The event service consists of two parts: event server and events.

  • The event server is used to receive and distribute events. It maintains an event queue internally to store pending events and an event list to store created events.

  • Events need to be created to the event server and provide a callback function.

When an event occurs, the event server inserts the event into the event queue for caching. The event server will periodically take out events from the event queue for distribution, and find the corresponding event callback for event processing.

Event service operation interface
Interface Description
mr_event_server_find Find event server
mr_event_server_add Add event server
mr_event_server_remove Remove event server
mr_event_server_handle Event server handler
mr_event_create Create event
mr_event_delete Remove event
mr_event_notify Notify event occurrence
mr_event_trigger Trigger event
Event service usage example:
/* Define events */
#define EVENT1 1
#define EVENT2 2
#define EVENT3 3

/* Define event server */
struct mr_event_server event_server;

mr_err_t event1_cb(mr_event_server_t server, void *args)
{
    printf("event1_cb\r\\
");
    
    /* Notify the event server that event 2 occurs */
    mr_event_notify(EVENT2, server);
    return MR_ERR_OK;
}

mr_err_t event2_cb(mr_event_server_t server, void *args)
{
    printf("event2_cb\r\\
");

    /* Notify the event server that event 3 has occurred */
    mr_event_notify(EVENT3, server)
    return MR_ERR_OK;
}

mr_err_t event3_cb(mr_event_server_t server, void *args)
{
    printf("event3_cb\r\\
");
    return MR_ERR_OK;
}

int main(void)
{
    /* Add event server to kernel container */
    mr_event_server_add( & amp;event_server, "server", 4);
    
    /* Create event to server */
    mr_event_create(EVENT1, event1_cb, MR_NULL, & amp;event_server);
    mr_event_create(EVENT2, event2_cb, MR_NULL, & amp;event_server);
    mr_event_create(EVENT3, event3_cb, MR_NULL, & event_server);
    
    /* Notify the event server that event 1 has occurred */
    mr_event_notify(EVENT1, & amp;event_server);
    
    while (1)
    {
        /* Event server processing */
        mr_event_server_handle( & amp;event_server);
    }
}

Phenomenon:

event1_cb
event2_cb
event3_cb

Software timer service

Software timer is a mechanism that implements timing functions at the software level. Through software timer, specific events can be triggered at specific time points or intervals. Software timers are often used to implement functions such as periodic tasks, timeout processing, and timer interrupts.

Software timers contain two main components: timing servers and timers.

  • Timing server is used for time management and timer processing.

  • The timer is used to handle specific timeout processing. It needs to be registered with the timing server and provide a callback function.

Software timer service operation interface

Interface Description
mr_soft_timer_server_find Find timing server
mr_soft_timer_server_add Add timing server
mr_soft_timer_server_remove Remove timing server
mr_soft_timer_server_update Timing server time base signal update
mr_soft_timer_server_handle Timing server processing
mr_soft_timer_add Add timer
mr_soft_timer_remove Remove timer
mr_soft_timer_start Start timer
mr_soft_timer_stop Pause timer
mr_soft_timer_add_then_start Add timer and start

Example of using software timer service:

/* Define timing server and timer */
struct mr_soft_timer_server server;
struct mr_soft_timer timer1, timer2, timer3;

mr_err_t timer1_callback(mr_soft_timer timer, void *args)
{
    printf("timer1_callback\r\\
");
    return MR_ERR_OK;
}

mr_err_t timer2_callback(mr_soft_timer timer, void *args)
{
    printf("timer2_callback\r\\
");
    return MR_ERR_OK;
}

mr_err_t timer3_callback(mr_soft_timer timer, void *args)
{
    printf("timer3_callback\r\\
");
    mr_soft_timer_stop(timer);
    return MR_ERR_OK;
}

int main(void)
{
    /* Add timing server */
    mr_soft_timer_server_add( & amp;server, "soft-timer");

    /* Add timer and start */
    mr_soft_timer_add_then_start( & amp;timer1, 5, timer1_callback, MR_NULL, & amp;server);
    mr_soft_timer_add_then_start( & amp;timer2, 10, timer2_callback, MR_NULL, & amp;server);
    mr_soft_timer_add_then_start( & amp;timer3, 15, timer3_callback, MR_NULL, & amp;server);

    while (1)
    {
        /* Update the scheduled server clock */
        mr_soft_timer_server_update( & amp;server, 1);
        
        /* Timing server processing (wherever it is placed, the callback will be called) */
        mr_soft_timer_server_handle( & amp;server);
    }
}

Code directory

The code directory structure of mr-library is as shown in the following table:

Name Description
bsp Board support package
device Device file
document Documentation
driver Driver file
include library header file
module Component
package Software package
src Library source file
  • Kernel layer: The core part of mr-library, which implements object management, device control, service interfaces, etc.

  • Device layer: Provides a unified device interface to connect devices to the kernel.

  • Driver layer: Provides the underlying hardware driver for the device. When the hardware is replaced, only the driver layer needs to be modified.

  • Component layer: Implement different functions through the API provided by the framework. Including but not limited to virtual file systems, universal sensor modules, network frameworks, etc.

  • Software package: A software package that can be used independently and has no dependencies.

Source: https://gitee.com/MacRsh/mr-library

Reposted from the public account: Embedded Hodgepodge

Copyright Statement: This article comes from the Internet, and the copyright belongs to the original author. For copyright issues, please contact us for deletion.

Recommended articles

Summary of GPIO basics! (The most complete information)?

The artifact is here! Improve embedded code quality with one click

How can a chip the size of a fingernail contain tens of billions of transistors?