Leveraging Linux Kernel Array Patterns for Configurable UART Drivers in C
This article explains how to adopt Linux kernel's struct‑array initialization and device‑tree matching techniques to implement a flexible C‑based UART driver that supports multiple compression configurations, complete with code examples and compilation guidance.
Introduction
The Linux kernel frequently uses immutable static const struct arrays together with a matching function to select configuration data based on a device‑tree compatible string. This pattern can be applied to user‑space programs that need to manage multiple sets of parameters, such as different voice‑compression profiles.
Kernel pattern example
static const struct ingenic_uart_config jz4740_uart_config = {
.tx_loadsz = 8,
.fifosize = 16,
};
static const struct ingenic_uart_config jz4760_uart_config = {
.tx_loadsz = 16,
.fifosize = 32,
};
static const struct ingenic_uart_config jz4780_uart_config = {
.tx_loadsz = 32,
.fifosize = 64,
};
static const struct of_device_id of_match[] = {
{ .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config },
{ .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4780-uart", .data = &jz4780_uart_config },
{ }
};
MODULE_DEVICE_TABLE(of, of_match);
static int ingenic_uart_probe(struct platform_device *pdev)
{
const struct ingenic_uart_config *cdata;
const struct of_device_id *match;
match = of_match_device(of_match, &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Error: No device match found
");
return -ENODEV;
}
cdata = match->data;
/* use cdata */
return 0;
}The driver obtains the appropriate configuration by comparing the device‑tree compatible string with the entries in of_match. Because the array is static const, the data cannot be altered at runtime.
Applying the pattern to a compression demo
Define a private struct that holds all parameters for a compression type and create a static const array of these structs. A simple lookup function returns the matching entry based on an integer identifier.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
struct my_private_s {
int comp_type;
int cfg1;
int cfg2;
int cfg3;
char compatible[32];
};
#define COMPRESS_TYPE1 0
#define COMPRESS_TYPE2 1
#define COMPRESS_TYPE3 3
#define COMPRESS_TYPE4 4
static const struct my_private_s of_match[] = {
{ .comp_type = COMPRESS_TYPE1, .cfg1 = 11, .cfg2 = 111, .cfg3 = 1111, .compatible = "com_type1" },
{ .comp_type = COMPRESS_TYPE2, .cfg1 = 22, .cfg2 = 222, .cfg3 = 2222, .compatible = "com_type2" },
{ .comp_type = COMPRESS_TYPE3, .cfg1 = 33, .cfg2 = 333, .cfg3 = 3333, .compatible = "com_type3" },
{ .comp_type = COMPRESS_TYPE4, .cfg1 = 44, .cfg2 = 444, .cfg3 = 444, .compatible = "com_type4" },
{ }
};
static const struct my_private_s *of_match_device(int comp_type)
{
for (size_t i = 0; i < ARRAY_SIZE(of_match); ++i) {
if (of_match[i].comp_type == comp_type)
return &of_match[i];
}
return NULL;
}
static void dump_compress_info(const struct my_private_s *c)
{
printf("
\tcomp type:%d
\tcfg1:%d
\tcfg2:%d
\tcfg3:%d
\tname:%s
",
c->comp_type, c->cfg1, c->cfg2, c->cfg3, c->compatible);
}
int main(void)
{
const struct my_private_s *my_dev = of_match_device(COMPRESS_TYPE1);
if (!my_dev) {
printf("[error] no valid compress type
");
return -1;
}
dump_compress_info(my_dev);
return 0;
}Compile with a standard C compiler, e.g. gcc -o compress_demo compress_demo.c. Running the program prints the selected configuration.
Key takeaways
Declare configuration tables as static const to make them read‑only.
Use a simple linear search (or a more efficient hash) to map an identifier to the appropriate struct.
Store a human‑readable compatible string for debugging and future extensions.
The same pattern used in kernel drivers can be safely reused in user‑space utilities.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
