• 代码示例_平台总线



      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------------
    ",__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------------
    ",__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!
    ");
     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------------
    ",__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-----------
    ", __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-----------
    ", __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
    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    PAT 1053 住房空置率
    PAT 1078 字符串压缩与解压
    PAT 1024 科学计数法
    HDU 2078 复习时间
    HDU 2065 "红色病毒"问题
    网络协议分析
    多线程同步
    多线程程序设计
    消息队列通讯
    共享内存通讯
  • 原文地址:https://www.cnblogs.com/panda-w/p/10991957.html
Copyright © 2020-2023  润新知