Source: https://gitee.com/MacRsh/mr-library
Introduction to mr-library
MR
framework is a lightweight framework designed specifically for embedded systems, taking into full consideration 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 opening (open
), closing (close
), controlling (ioctl
), reading (read
), and writing (write
). It decouples the application from the underlying hardware drivers, allowing applications to operate without needing to understand the implementation details of the drivers.
When hardware changes, only the underlying drivers need to be adapted, allowing applications to seamlessly migrate to new hardware. This greatly enhances software reusability and scalability in response to new hardware.

Key Features
-
Standardized device access interfaces -
Decoupling of application and driver development -
Simplified development of underlying drivers and applications -
Lightweight and easy to use, low resource consumption -
Modular design, with decoupled and independently developed components, extremely low hardware migration costs -
Supports use in bare-metal environments and operating system environments
Main Components
-
Device framework: provides standardized device access interfaces -
Memory management: dynamic memory management -
Tools: commonly used data structures such as linked lists, queues, balanced trees, etc. -
Various functional components
Standardized Device Interface
All operations on the device can be achieved 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 on 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 choose the functionality components to enable and set related parameters through simple operations.


By modifying parameters, quickly trim the required functionality. After configuration, the configuration file is automatically generated through 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 files |
kconfig.py | Automatic configuration script |
LICENSE | License |
Getting Started
Configure Kconfig
Environment
Note: Kconfig
is not mandatory, but recommended (installation and configuration are very quick, and subsequent tutorials will take Kconfig
as an example).
-
Verify if the Python environment is installed on the system. Run
python --version
in the command line to check the Python version (sinceKconfig
depends onpython
, please installpython
if it is not available). -
Use the command shown in the command line to install
Kconfig
:python -m pip install windows-curses python -m pip install kconfiglib
-
Run
menuconfig -h
in the command line to verify if the installation was successful.
Import Framework into Project
-
Download the latest version of the source code from
Gitee
orGithub
repository to your local machine. -
Import the source code into the directory where your project is located. For example, for an STM32 project:
Project Directory -
If the chip you are using has already been adapted with
BSP
, please refer to the configuration tutorial in the correspondingBSP
to complete theBSP
configuration. -
Remove unnecessary files from the
bsp
,document
, andmodule
directories (ifGIT
is not needed, you can also remove the.git
file). After completion, the directory structure is as follows:Project Directory 1 -
Add the files to the IDE (most IDEs can automatically recognize the files under the project path, so this step is not necessary). For example, in
keil
:Project Directory Keil Add all files under the
source
,device
,driver
directories.
Configure Menu Options
-
Open the command line tool in the
mr-library
directory and runmenuconfig
for menu configuration.Project Directory 2 Note: After adding the corresponding chip driver,
Device configure
andDriver configure
will be displayed. Please refer to the tutorial inBSP
forDriver configure
. -
Select
Device configure
and press enter to enter the menu, configure functionalities as needed.Project Directory 3 -
After configuration is complete, press
Q
to exit the menu configuration interface, and pressY
to save the configuration.
Generate Configuration File
-
Open the command line tool in the mr-library
directory and runpython kconfig.py
to automatically generate the configuration filemr_config.h
.
Add Include Path
-
Add the include path of
mr-library
in the compiler, for example:Project Directory 4 -
Configure automatic initialization (GCC environment), find the linking script file with a
.ld
suffix under your project (usuallylink.ld
), add the following code to the script file: Note: If you are in an environment that can automatically generate linking scripts likekeil
, please skip this step./* mr-library auto init */ . = ALIGN(4); _mr_auto_init_start = .; KEEP(*(SORT(.auto_init*))) _mr_auto_init_end = .;
Example:
Project Directory 5 -
Configure GNU syntax. If you are using a non-
GCC
compiler, please enable GNU syntax. For example:AC5:
Project Directory 6 AC6:
Project Directory 7 -
Include
#include "include/mr_lib.h"
in your project. -
Add
mr_auto_init();
automatic initialization function in themain
function.
Let’s Turn on the Light
#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);
}
-END-

Embedded industrial tool, RK3568J supports asymmetric AMP: Linux + RTOS/bare metal!

How to let embedded projects unknowingly head towards a dead end?

A piece of employment information for embedded engineers