A DMOD module library that provides a standardized interface for device drivers, enabling uniform access to hardware devices in embedded systems.
dmdrvi is a driver interface module designed for embedded systems using the DMOD framework. It provides a consistent API for device driver operations including open, close, read, write, ioctl, and other standard device operations. The module uses device numbers (major/minor) to identify and manage devices.
- Standardized Device Interface: Uniform API for all device drivers
- Device Identification: Major/minor device number system
- Flexible Access Modes: Read-only, write-only, and read-write support
- Standard Operations: open, close, read, write, ioctl, flush, stat
- Configuration Support: Integration with dmini for device configuration
- SAL-Compatible: Uses only DMOD SAL functions
- Lightweight: Minimal memory footprint suitable for embedded systems
dmdrvi_create(config, dev_num)- Create driver context with configurationdmdrvi_free(context)- Free driver context
dmdrvi_open(context, flags)- Open device with specified flagsdmdrvi_close(context, handle)- Close device handledmdrvi_read(context, handle, buffer, size)- Read data from devicedmdrvi_write(context, handle, buffer, size)- Write data to devicedmdrvi_ioctl(context, handle, command, arg)- Device control operationsdmdrvi_flush(context, handle)- Flush device buffersdmdrvi_stat(context, handle, stat)- Get device status
DMDRVI_O_RDONLY- Open for read onlyDMDRVI_O_WRONLY- Open for write onlyDMDRVI_O_RDWR- Open for read and write
#include "dmdrvi.h"
// Define device number (UART channel 0, default config)
dmdrvi_dev_num_t dev_num = {
.major = 0,
.minor = 0
};
// Create driver context (config can be NULL or dmini context)
dmdrvi_context_t ctx = dmdrvi_create(NULL, &dev_num);
// Open device for reading and writing
void* handle = dmdrvi_open(ctx, DMDRVI_O_RDWR);
// Write data to device
char write_buffer[] = "Hello Device";
size_t written = dmdrvi_write(ctx, handle, write_buffer, sizeof(write_buffer));
// Read data from device
char read_buffer[256];
size_t read = dmdrvi_read(ctx, handle, read_buffer, sizeof(read_buffer));
// Get device status
dmdrvi_stat_t stat;
int result = dmdrvi_stat(ctx, handle, &stat);
Dmod_Printf("Device size: %u bytes\n", stat.size);
// Flush buffers
dmdrvi_flush(ctx, handle);
// Close device
dmdrvi_close(ctx, handle);
// Free context
dmdrvi_free(ctx);mkdir build
cd build
cmake .. -DDMOD_MODE=DMOD_MODULE
cmake --build .This generates:
dmf/dmdrvi.dmf- The driver interface library moduledmf/dmdrvi_version.txt- Version information
dmdrvi can work with dmini module for device configuration:
#include "dmini.h"
#include "dmdrvi.h"
// Parse device configuration
dmini_context_t config = dmini_create();
dmini_parse_file(config, "device.ini");
// Device numbers come from device filesystem, not from config
dmdrvi_dev_num_t dev_num = { .major = 0, .minor = 0 };
// Create driver context with configuration
// Config contains device-specific settings (baudrate, mode, etc.)
dmdrvi_context_t driver = dmdrvi_create(config, &dev_num);
// Use driver...
dmdrvi_free(driver);
dmini_destroy(config);The module uses a major/minor device numbering system:
- Major number: Identifies the device channel within a driver type (e.g., UART0, UART1, SPI0)
- Minor number: Identifies virtual configuration for the same channel (useful when you need different configurations, e.g., different SPI speeds for different CS lines)
Note: Major numbers are scoped per device driver type. Different drivers (UART, SPI, etc.) can use the same major numbers for their own channels.
Example device numbers:
Driver Channel Major Minor Description
-----------------------------------------------------
UART UART0 default 0 0 Default configuration
UART UART0 alt 0 1 Alternative configuration
UART UART1 default 1 0 Default configuration
SPI SPI0 CS0 0 0 SPI channel 0, config 0
SPI SPI0 CS1 0 1 SPI channel 0, config 1 (different speed)
Most functions return error codes compatible with standard errno values:
0- Success- Negative values - Error codes (implementation-specific)
For read/write operations:
- Returns number of bytes transferred on success
- Returns 0 or negative value on error
The driver interface module has a minimal footprint suitable for embedded systems. Actual memory usage depends on the underlying driver implementation.
MIT License - see LICENSE file for details