内核版本不一样的问题解决后,就到了驱动编写步骤了,涉及硬件还是从简单的led驱动开始吧。硬件电路:
我选择了60号gpio,也就是P9_12。
源码如下:
- /**
- * [url=home.php?mod=space&uid=1455510]@file[/url] led.c
- * [url=home.php?mod=space&uid=40524]@author[/url] yang yongsheng
- * @date 2016.10.3
- */
- #include
- #include
- #include
- #include // Required for the GPIO functions
- #include
- #include
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("yang yongsheng");
- MODULE_DESCRIPTION("A LED test driver for the BBB");
- MODULE_VERSION("0.1");
- static unsigned int gpioLED = 60; ///< hard coding the LED gpio for this example to P9_23 (GPIO49)
- static unsigned int numberPresses = 0; ///< For information, store the number of button presses
- static bool ledOn = 0; ///< Is the LED on or off? Used to invert its state (off by default)
- static unsigned int major;
- static int led_open(struct inode *inode, struct file *file)
- {
- printk("bbb's led gpio60 will open.n");
-
- return 0;
- }
- static ssize_t led_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
- {
- int val;
- printk("write bbb's led.n");
- copy_from_user(&val, buf, count);
- if (val == 1)
- {
- gpio_set_value(gpioLED, true);
- }
- else
- {
- gpio_set_value(gpioLED, false);
- }
- return 0;
- }
- static ssize_t led_read (struct file *file, char __user *buf, size_t count, loff_t *ppos)
- {
- return 0;
- }
- static struct file_operations led_fops = {
- .owner = THIS_MODULE,
- .open = led_open,
- .write = led_write,
- .read = led_read,
- };
- static int __init led_init(void){
- int result = 0;
- printk(KERN_INFO "GPIO_TEST: Initializing the GPIO_TEST LKMn");
- // Is the GPIO a valid GPIO number (e.g., the BBB has 4x32 but not all available)
- if (!gpio_is_valid(gpioLED)){
- printk(KERN_INFO "GPIO_TEST: invalid LED GPIOn");
- return -ENODEV;
- }
- // Going to set up the LED. It is a GPIO in output mode and will be on by default
- ledOn = true;
- gpio_request(gpioLED, "sysfs"); // gpioLED is hardcoded to 60, request it
- gpio_direction_output(gpioLED, ledOn); // Set the gpio to be in output mode and on
- gpio_set_value(gpioLED, ledOn); // Not required as set by line above (here for reference)
- gpio_export(gpioLED, false); // Causes gpio49 to appear in /sys/class/gpio
- major = register_chrdev(0,"bbb_led",&led_fops); //注册字符驱动
- return result;
- }
- static void __exit led_exit(void){
- gpio_set_value(gpioLED, 0); // Turn the LED off, makes it clear the device was unloaded
- gpio_unexport(gpioLED); // Unexport the LED GPIO
- gpio_free(gpioLED); // Free the LED GPIO
- unregister_chrdev(major,"bbb_led"); //卸载字符驱动
- printk(KERN_INFO "GPIO_TEST: Goodbye from the LKM!n");
- }
- module_init(led_init);
- module_exit(led_exit);
复制代码
用户程序源码如下:
- #include
- #include
- #include
- #include
- int main(int argc, char **argv)
- {
- int fd;
- int val = 0;
- fd = open("/dev/bbb_led",O_RDWR);
- if (fd < 0)
- {
- printf("can't open!n");
- }
- if (argc != 2)
- {
- printf("Usage :n");
- printf("%s .n",argv[0]);
- return 0;
- }
- if (strcmp(argv[1], "on") == 0)
- {
- val = 1;
- }
- else
- {
- val = 0;
- }
- write(fd,&val,4);
- return 0;
- }
复制代码
看看便出来的内核信息bone80:
|