代码示例_平台总线

 

 

 


 

 

 

  1 #include <linux/init.h>
  2 #include <linux/module.h>
  3 #include <linux/platform_device.h>
  4 #include <linux/fs.h>
  5 #include <linux/device.h>
  6 #include <linux/miscdevice.h>
  7 
  8 #include <asm/io.h>
  9 #include <asm/uaccess.h>
 10 
 11 
 12 static void *led_reg_base;
 13 static struct miscdevice  led_misc;
 14 
 15 //实现设备操作接口
 16 int led_plat_drv_open(struct inode *inode, struct file *filp)
 17 {
 18 
 19     printk("--------^_^ %s------------\n",__FUNCTION__);
 20     // 对寄存器进行初始化
 21     unsigned long value = __raw_readl(led_reg_base);
 22     value &= ~(0xff<<12);
 23     value |= (0x11<<12); //配置成输出功能
 24     __raw_writel(value, led_reg_base);
 25 
 26     return 0;
 27 }
 28 ssize_t led_plat_drv_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags)
 29 {
 30     int ret;
 31     printk("--------^_^ %s------------\n",__FUNCTION__);
 32 
 33     unsigned int  value;
 34     //应用空间数据转换为内核空间数据
 35     ret = copy_from_user(&value, buf, size);
 36     if(ret != 0){
 37         printk("copy_from_user error!\n");
 38         return -EFAULT;
 39     }
 40 
 41     
 42 
 43     if(value)
 44     {
 45         // 将led亮起来
 46         __raw_writel(__raw_readl(led_reg_base + 4) | (0x3<<3), led_reg_base + 4);
 47     }else
 48     {
 49         __raw_writel(__raw_readl(led_reg_base + 4) &~(0x3<<3), led_reg_base + 4);
 50     }
 51 
 52 
 53     return size;
 54 }
 55 
 56 int led_plat_drv_close(struct inode *inode, struct file *filp)
 57 {
 58     printk("--------^_^ %s------------\n",__FUNCTION__);
 59 
 60     __raw_writel(__raw_readl(led_reg_base + 4) &~(0x3<<3), led_reg_base + 4);
 61     
 62     return 0;
 63 }
 64 
 65 
 66 
 67 const struct file_operations plat_led_fops = {
 68     .open = led_plat_drv_open,
 69     .write = led_plat_drv_write,
 70     .release = led_plat_drv_close,
 71 
 72 };
 73 
 74 int led_pdrv_probe(struct platform_device *pdev)
 75 {
 76     printk("-----------%s-----------\n", __FUNCTION__);
 77 
 78 
 79     //任务1---与应用交互
 80     // register_chrdev() , class_create, device_create, fops
 81     // 或一种写法---用一个函数搞定上面所有函数
 82     led_misc.name = "plat_led";  // /dev/plat_led
 83     led_misc.minor = 120;  // 主设备号默认为10, 次设备自由定义--MISC_DYNAMIC_MINOR(255)由系统分配
 84     led_misc.fops = &plat_led_fops;
 85     misc_register(&led_misc);
 86     
 87 
 88     //任务2---与硬件交互---先要获取资源, ioremap/request_irq()
 89     //参数1--从哪个pdev中获取
 90     //参数2--资源的类型
 91     //参数3--同种资源的第几个
 92     struct resource *mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 93 
 94     //获取地址资源就需要进行地址映射
 95     led_reg_base = ioremap(mem_res->start,  resource_size(mem_res));
 96 
 97 
 98 
 99     return 0;
100 }
101 int led_pdrv_remove(struct platform_device *pdev)
102 {
103     printk("-----------%s-----------\n", __FUNCTION__);
104     
105     iounmap(led_reg_base);
106     misc_deregister(&led_misc);
107     
108     return 0;
109 }
110 
111 
112 const struct platform_device_id led_id_table[] = {
113         {"s5pv210_led", 0x123}, //第二个值随便写
114         {"exynos4_led", 0x124},
115         {"s5p6818_led", 0x444},
116 };
117 
118 
119 struct platform_driver led_pdrv = {
120     .probe = led_pdrv_probe,
121     .remove = led_pdrv_remove,
122     .driver = { //父类一定要初始化
123         .name = "samsung_led_drv", // 一定要初始化--自定义
124     },
125     .id_table = led_id_table,
126 
127 };
128 
129 static int __init plat_led_drv_init(void)
130 {
131 
132     //注册一个pdrv
133     return platform_driver_register(&led_pdrv);
134 
135 }
136 
137 static void __exit plat_led_drv_exit(void)
138 {
139 
140     platform_driver_unregister(&led_pdrv);
141 }
142 
143 
144 module_init(plat_led_drv_init);
145 module_exit(plat_led_drv_exit);
146 MODULE_LICENSE("GPL");

 

 


 

 

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/platform_device.h>
 4 
 5 
 6 #define GPC0_REG_BASE 0xE0200060
 7 #define GPC0_SIZE 8
 8 
 9 struct resource     led_res[] = {
10     [0] = {
11         .start = GPC0_REG_BASE,
12         .end = GPC0_REG_BASE + GPC0_SIZE - 1,
13         .flags = IORESOURCE_MEM,
14     },
15     //以下代码为演示如何定义多个资源--led硬件实际没有
16     [1] = {
17         .start = 0x666,
18         .end = 0x666,
19         .name = "fake_irq",
20         .flags = IORESOURCE_IRQ,
21     },
22     [2] = {
23         .start = 0x12345678,
24         .end = 0x12345678 + 0x8 - 1,
25         .name = "fake_mem",
26         .flags = IORESOURCE_MEM,
27     },
28 };
29 
30 
31 //主要用于解决rmmod的有警告
32 void    led_pdev_release(struct device *dev) //pdev从总线移除系统自动调用
33 {
34 
35 
36 }
37 
38 
39 struct platform_device  led_pdev = {
40     .name = "s5pv210_led",
41     .id = -1,
42     .dev = {
43         .release = led_pdev_release,
44     },
45     .num_resources = ARRAY_SIZE(led_res),
46     .resource = led_res,
47 };
48 
49 
50 static int __init plat_led_dev_init(void)
51 {
52 
53     //注册一个pdev
54     return platform_device_register(&led_pdev);
55 
56 }
57 
58 static void __exit plat_led_dev_exit(void)
59 {
60 
61     platform_device_unregister(&led_pdev);
62 }
63 
64 
65 module_init(plat_led_dev_init);
66 module_exit(plat_led_dev_exit);
67 MODULE_LICENSE("GPL");

 

 


 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 #include <fcntl.h>
 7 
 8 int main(void)
 9 {
10 
11     int fd;
12     int on;
13 
14     fd = open("/dev/plat_led",O_RDWR);
15     if(fd < 0)
16     {
17         perror("open");
18         exit(1);
19     }
20 
21     
22     while(1)
23     {
24         
25         on = 1;
26         write(fd,&on,sizeof(on));
27         sleep(1);
28 
29         
30         on = 0;
31         write(fd,&on,sizeof(on));
32         sleep(1);
33     }
34 
35     close(fd);
36     return 0;
37 }

 

 


 

 

 

 

 1 CROSS_COMPILE = arm-none-linux-gnueabi-
 2 CC = $(CROSS_COMPILE)gcc
 3 
 4 #指定内核源码路径
 5 KERNEL_DIR = /home/farsight/s5pv210/kernel/driver/linux-3.0.8
 6 CUR_DIR = $(shell pwd)
 7 
 8 MYAPP = plat_led_app
 9 
10 MODULE = plat_led_dev
11 MODULE2 = plat_led_drv
12 
13 all:
14     #让make进入内核源码编译,同时将当前目录中的c程序作为内核模块一起编译
15     make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
16 ifneq ($(MYAPP), )    
17     $(CC)  -o $(MYAPP) $(MYAPP).c
18 endif
19 
20 clean:
21     #删除上面编译生成的文件
22     make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
23     rm -rf $(MYAPP)
24 
25 install:
26     cp *.ko $(MYAPP) /opt/rootfs/drv_module
27 
28 #指定当前目录下哪个文件作为内核模块编
29 obj-m += $(MODULE).o
30 obj-m += $(MODULE2).o

 

posted @ 2019-06-09 13:10  panda_w  阅读(277)  评论(0编辑  收藏  举报