Sometimes we want drivers to be added and removed through make menuconfig at the time of Linux compilation, which can be done in the following ways:
1.LED Drive For example
(1) Create an LED directory in the Kernel\drivers\char\ directory, and then write the LED driver code will be placed in this directory.
(2) Modify the makefile in the Kernel\drivers\char\ directory to include the LED directory.
That is: Add Obj-y + + led/in makefile.
Obj-y: Represents the foo.o compiled by xx.c or Foo.s files and connected to the kernel.
Obj-m: This indicates that the file is compiled as a module.
Targets in obj-x form other than Y and M are not compiled.
(3) Add makefile files and Kconfig files to the LED directory and add the following
Makefile File:
obj-$ (config_my_led_driver) + + MY-LED.O
Kconfig file:
Config My_led_driver
BOOL "My LED Driver"
Default Y
Help
Compile for Leddriver,y to kernel,m for the for module.
(4) Write MY_LED.C driver code.
#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/
sched.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <mach/hardware.h> #include <asm/mach-types.h> #include <linux/gpio.h> #include <asm/gpio.h> #include <asm/delay.h > #include <linux/clk.h> #include <plat/gpio-cfg.h> * * LED1-> D22-> gpj0_3 * LED2-> D23-& Gt
Gpj0_4 * LED3-> D24-> gpj0_5 * LED4-> D25->-gpd0_1/static int __my_led_status[4] = {0};
static void __my_led_probe (void) {int ret;
ret = Gpio_request (S5pv210_gpj0 (3), "GPJ0");
if (ret) PRINTK ("My-led:request Gpio GPJ0 (3) fail\n");
S3c_gpio_setpull (S5pv210_gpj0 (3), s3c_gpio_pull_up);
S3c_gpio_cfgpin (S5pv210_gpj0 (3), S3C_GPIO_SFN (1));
Gpio_set_value (S5pv210_gpj0 (3), 1);
ret = Gpio_request (S5pv210_gpj0 (4), "GPJ0");
if (ret) PRINTK ("My-led:request Gpio GPJ0 (4) fail\n"); S3c_gpio_setpulL (S5pv210_gpj0 (4), s3c_gpio_pull_up);
S3c_gpio_cfgpin (S5pv210_gpj0 (4), S3C_GPIO_SFN (1));
Gpio_set_value (S5pv210_gpj0 (4), 1);
ret = Gpio_request (s5pv210_gpj0 (5), "GPJ0");
if (ret) PRINTK ("My-led:request Gpio GPJ0 (5) fail\n");
S3c_gpio_setpull (S5pv210_gpj0 (5), s3c_gpio_pull_up);
S3c_gpio_cfgpin (S5pv210_gpj0 (5), S3C_GPIO_SFN (1));
Gpio_set_value (S5pv210_gpj0 (5), 1);
ret = Gpio_request (s5pv210_gpd0 (1), "GPD0");
if (ret) PRINTK ("My-led:request gpio GPD0 (1) fail\n");
S3c_gpio_setpull (s5pv210_gpd0 (1), s3c_gpio_pull_up);
S3c_gpio_cfgpin (s5pv210_gpd0 (1), S3C_GPIO_SFN (1));
Gpio_set_value (s5pv210_gpd0 (1), 1);
__my_led_status[0] = 0;
__my_led_status[1] = 0;
__MY_LED_STATUS[2] = 0;
__MY_LED_STATUS[3] = 0;
} static void __my_led_remove (void) {Gpio_free (S5pv210_gpj0 (3));
Gpio_free (S5pv210_gpj0 (4));
Gpio_free (S5pv210_gpj0 (5));
Gpio_free (s5pv210_gpd0 (1)); Static ssize_t my_led_read (struct device *dev, struct device_attribute *attr, char *buf) {if!strcmp (ATTR->ATTR.NAme, "led1")) {if (__my_led_status[0]!= 0) return strlcpy (buf, "1\n", 3);
else return strlcpy (buf, "0\n", 3);
else if (!strcmp (Attr->attr.name, "Led2")) {if (__my_led_status[1)!= 0) return strlcpy (buf, "1\n", 3);
else return strlcpy (buf, "0\n", 3);
else if (!strcmp (Attr->attr.name, "Led3")) {if (__my_led_status[2)!= 0) return strlcpy (buf, "1\n", 3);
else return strlcpy (buf, "0\n", 3);
else if (!strcmp (Attr->attr.name, "led4")) {if (__my_led_status[3)!= 0) return strlcpy (buf, "1\n", 3);
else return strlcpy (buf, "0\n", 3); } static ssize_t My_led_write (struct device *dev, struct device_attribute *attr, const char *BUF, size_t count) {Unsi
gned Long on = Simple_strtoul (buf, NULL, 10);
if (!strcmp (Attr->attr.name, "led1")) {if (on) {Gpio_set_value (S5pv210_gpj0 (3), 0);
__my_led_status[0] = 1;
else {Gpio_set_value (s5pv210_gpj0 (3), 1);
__my_led_status[0] = 0; } else if (!strcmp (attr->Attr.name, "Led2")) {if (on) {Gpio_set_value (S5pv210_gpj0 (4), 0);
__MY_LED_STATUS[1] = 1;
else {gpio_set_value (s5pv210_gpj0 (4), 1);
__my_led_status[1] = 0;
} else if (!strcmp (Attr->attr.name, "Led3")) {if (on) {Gpio_set_value (S5pv210_gpj0 (5), 0);
__MY_LED_STATUS[2] = 1;
else {Gpio_set_value (s5pv210_gpj0 (5), 1);
__MY_LED_STATUS[2] = 0;
} else if (!strcmp (Attr->attr.name, "led4")) {if (on) {Gpio_set_value (s5pv210_gpd0 (1), 0);
__MY_LED_STATUS[3] = 1;
else {gpio_set_value (s5pv210_gpd0 (1), 1);
__MY_LED_STATUS[3] = 0;
} return count;
Static device_attr (led1, 0666, My_led_read, my_led_write);
Static device_attr (Led2, 0666, My_led_read, my_led_write);
Static device_attr (Led3, 0666, My_led_read, my_led_write);
Static device_attr (Led4, 0666, My_led_read, my_led_write); static struct attribute * my_led_sysfs_entries[] = {&dev_attr_led1.attr, &dev_attr_led2.attr, &dev_attr_leD3.attr, &dev_attr_led4.attr, NULL,};
static struct Attribute_group My_led_attr_group = {. Name = NULL,. attrs = My_led_sysfs_entries,};
static int my_led_probe (struct platform_device *pdev) {__my_led_probe ();
Return Sysfs_create_group (&pdev->dev.kobj, &my_led_attr_group);
static int my_led_remove (struct platform_device *pdev) {__my_led_remove ();
Sysfs_remove_group (&pdev->dev.kobj, &my_led_attr_group);
return 0;
static int my_led_suspend (struct platform_device *pdev, pm_message_t state) {return 0;}
static int My_led_resume (struct platform_device *pdev) {return 0;} static struct Platform_driver My_led_driver = {. Probe = My_led_probe,. remove = My_led_remove,. Suspend = My_led_sus
Pend,. Resume = My_led_resume,. Driver = {. Name = ' my-led ',},};
static struct Platform_device My_led_device = {. Name = "My-led",. id =-1,};
static int __devinit my_led_init (void) {int ret;
PRINTK ("My led driver\r\n");
ret = Platform_device_register (&my_led_device);
if (ret) PRINTK ("Failed to register my led device\n");
ret = Platform_driver_register (&my_led_driver);
if (ret) PRINTK ("Failed to register my led driver\n");
return ret;
static void My_led_exit (void) {platform_driver_unregister (&my_led_driver);/Logoff Platform driver} module_init (My_led_init);
Module_exit (My_led_exit);
Module_license ("GPL");
Module_author ("Huajianzou");
Module_description ("My LED Driver");
Extending knowledge:
If a kernel module is built from multiple source files, Kbuild must know which parts of the module you want to build from. So you need to set the $ (<MODULE_NAME>-OBJS) variable to tell Kbuild.
Example:
#drivers/isdn/i4l/makefile
obj-$ (CONFIG_ISDN) + + ISDN.O
ISDN-OBJS: = ISDN_NET_LIB.O isdn_v110.o ISDN_COMMON.O
In this example, the module name is Isdn.o,kbuild will compile the object file listed in $ (ISDN-OBJS) and then call "$ (LD)-R" in the list of these files to produce ISDN.O.
Kbuild uses the suffix-objs,-y to identify mixed object files. This allows makefiles to use variable Config_sambol to determine whether an object is part of a mixed object.
Reference blog:
Kbuild Makefile Introduction: https://www.cnblogs.com/cecwxf/archive/2012/04/26/2470968.html