Configurable Module Parameter for GPIO Serial Communication Device Driver
Pravin Raghul
Embedded Software Engineer | Cortex-M | Embedded Linux & Kernel Drivers | C, C++, Python
This article focuses on improving the GPIO Serial Device Driver (gpioserdev-driver) project with configurable module parameters. We'll explore the need for configurable parameters in this project, how to implement them and how to test this feature in the Raspberry Pi 3B+.
This article is a continuation of the previous article Building a Custom GPIO Serial Communication Device Driver.
Why we need configurable module parameter?
Configurable module parameters allow users to modify the kernel module’s behavior at load time without the need to change the source code. This provides re-usability, testing and tailoring of the modules for various environments or requirements.
In our case, the configurable module parameters are as follows,
How to implement module parameter?
Module parameters in gpioserdev-driver are implemented using module_param or module_param_cb.
1. Define Parameters:
static int delay_us = GPIOSERDEV_DELAY_US; // Default 750 μs
static char byte_order[4] = "lsb"; // Default LSB-first
2. Declare Parameters as Configurable:
module_param(delay_us, int, 0644);
MODULE_PARM_DESC(delay_us, "Bit transaction delay in microseconds");
static const struct kernel_param_ops param_ops = {
.set = gpioserdev_validate_byteorder,
.get = gpioserdev_get_byteorder,
};
// this module_param_cb will have callback function being called to validate the updated parameter value
module_param_cb(data_order, ¶m_ops, byte_order, 0644);
MODULE_PARM_DESC(data_order, "Byte order: lsb or msb");
3. Validate and Use Parameters: Validation ensures the data_order parameter only accepts "lsb" or "msb" values:
static int gpioserdev_validate_byteorder(const char *val, const struct kernel_param *kp) {
if (strcmp(val, "lsb\n") == 0 || strcmp(val, "msb\n") == 0) {
// kp->arg is nothing but the byte_order variable
strscpy((char *)kp->arg, val, sizeof(byte_order));
return 0;
}
pr_err("Invalid value for %s. Allowed values: lsb, msb\n", kp->name);
return -EINVAL;
}
领英推荐
Testing the configurable module parameter
Similar hardware setup which we used in the previous article Building a Custom GPIO Serial Communication Device Driver, as shown in the below table,
Verifying Parameters
Once the module is loaded, check the parameter exists, and what's their default values from the sysfs, as shown from the below image.
Testing the delay_us parameter
To test the delay_us module parameter and observe its impact on data transfer speed, the driver has the default value of 750 μs and an updated value of 2000 μs. This parameter accepts integer values to configure the delay in microseconds. The results demonstrate a noticeable difference in data transmission timing, validating the functionality of the configurable parameter. Please refer to the image below for details.
Testing the data_order parameter
The data_order parameter determines the data transfer mode and accepts only the string values lsb or msb. Attempting to set an invalid value, as shown in the image, results in an error. For details, refer to the implementation of the callback function that validates these inputs.
Summary
Configurable module parameters make the gpioserdev-driver easy to adapt to different use cases. This article demonstrated how to add such parameters, validate them, and test their functionality. Also refer the previous article Building a Custom GPIO Serial Communication Device Driver.
In the next article, we’ll explore the need for ioctl calls in this project and integrating into gpioserdev-driver. Let me know your thoughts..!