• “龙江二号”微卫星传回地月合影 2019-04-18
  • 中国驻泰国大使考察合艾国光中学孔子课堂 2019-04-18
  • 【清园20年】感恩大回馈!半价!半价! 2019-04-18
  • 中央纪委紧盯节点 4年来通报曝光问题近4000起 2019-04-13
  • 2013环球企业领袖宁夏圆桌会议嘉宾云集 2019-04-13
  • 《魔兽世界》未解之谜 那些仍不能被玩家们踏足的领地 2019-04-11
  • 钱江潮评 让高质量发展插上人才的翅膀 2019-04-10
  • 习近平两会期间谈社会主义核心价值观 2019-04-02
  • 文脉颂中华——黄河新闻网 2019-04-02
  • 陈小林的专栏作者中国国家地理网 2019-03-29
  • 中英航母大战谁能赢歼151枚炸弹就能炸瘫女王 2019-03-22
  • 独特“光捕捉器”可控制分子生化性质 2019-03-22
  • 女性之声——全国妇联 2019-03-19
  • 【理上网来·辉煌十九大】德国北威州经济部长:十九大报告表明中国有能力为世界做出更多贡献 2019-03-11
  • 全国小麦收获进度过八成 2019-03-07
  • 打印

    广东11选五的开奖结: [嵌入式linux] 芯灵思Sinlinx A33实现linux led驱动

    [复制链接]
    137|1
    跳转到指定楼层
    楼主
    本帖最后由 sin12 于 2019-3-15 10:14 编辑

    实验原理
    在芯灵思开发板上,没有led灯???,只能通过引脚电平观察: 这里我选择LS-INT引脚。
    全志A33一共有10组IO口,每组IO有9个相关功能控制器,LS-INT属于PB7,相关寄存器如图
    本次实验只用到这两个寄存器,在程序中命名为gpio_con,gpio_dat ,设置为输出引脚。

    1)注册 class_register(class)  将class注册到内核中。调用前,必须手动分配class内存;调用后,必须设置class的name等参数注册 class_create(owner,name)  创建class并将class注册到内核中。返回值为class结构体指针。注销 void class_unregister(struct class *cls)  注销class,与class_register()配对使用。注销 void class_destroy(struct class *cls)     注销class,与class_create()配对使用内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载??榈氖焙?,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。2)void* ioremap(unsigned long phys_addr , unsigned long size , unsigned long flags)用mmap映射一个设备意味着使用户空间的一段地址关联到设备内存上,这使得只要程序在分配的地址范围内进行读取或写入,实际上就是对设备的访问。解除映射:void iounmap(void* addr)//取消ioremap所映射的IO地址
    3)register_chrdev(unsigned int major, const char *name,const struct file_operations *fops);但其实这个函数是linux版本2.4之前的注册方式,它的原理是:
    (1)确定一个主设备号,如果major=0,则会自动分配设备号
    (2)构造一个file_operations结构体, 然后放在chrdevs数组中
    (3)注册:register_chrdev,cat /proc/devices查看内核中已经注册过的字符设备驱动(和块设备驱动),注意这里并不是驱动文件设备节点!
    4) Linux使用file_operations结构访问驱动程序的函数,这个结构的每一个成员的名字都对应着一个调用5)   class_device_create() 调用class_create为该设备创建一个class,再为每个设备调用 class_device_create创建对应的设备。
    大致用法如下:struct class *myclass = class_create(THIS_MODULE, “my_device_driver”);
    class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “my_device”);
    这样的module被加载时,udev daemon就会自动在/dev下创建my_device设备文件。
    总体代码框架

    1)先要有file_operations先要有引脚初始化函数myled_init(void),在myled_init里面注册class并将class类注册到内核中,创建设备节点,初始化引脚已经将寄存器地址映射到虚拟内存中,最后调用module_init(myled_init)驱动的加载就靠它
    2)创建这个file_operations结构体
    static struct file_operations myled_oprs = {
            .owner = THIS_MODULE,
            .open  = led_open,
            .write = led_write,
            .release = led_release,
    };  下面就围绕这个结构体写函数led_write() led_open() led_release()
    3)最后要注销设备.... ....
    不是很详细,因为详细写起来太多了,附实测代码,参考下
    LED驱动代码:
    1. #include <linux/module.h>
    2. #include <linux/kernel.h>
    3. #include <linux/fs.h>
    4. #include <linux/init.h>
    5. #include <linux/delay.h>
    6. #include <linux/uaccess.h>
    7. #include <asm/irq.h>
    8. #include <asm/io.h>
    9. #include <linux/of.h>
    10. #include <linux/of_device.h>
    11. #include <linux/of_platform.h>
    12. static int major;
    13. static struct class *led_class;
    14. volatile unsigned long *gpio_con = NULL;
    15. volatile unsigned long *gpio_dat = NULL;
    16. static int led_open (struct inode *node, struct file *filp)
    17. {
    18.     /* PB7 - 0x01C20824 */
    19.    if (gpio_con) {
    20.         printk("ioremap  0x%x\n", gpio_con);
    21.         }
    22.         else {
    23.     return -EINVAL;
    24.         }
    25.     return 0;
    26. }

    27. static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
    28. {
    29.      unsigned char val;        
    30.      copy_from_user(&val, buf, 1);

    31.         if (val)
    32.         {
    33.      *gpio_dat |= (1<<7);
    34.         }
    35.         else
    36.         {
    37.      *gpio_dat &= ~(1<<7);
    38.         }

    39.         return 1;
    40. }

    41. static int led_release (struct inode *node, struct file *filp)
    42. {
    43.     printk("iounmap(0x%x)\n", gpio_con);
    44.     iounmap(gpio_con);
    45.     return 0;
    46. }


    47. static struct file_operations myled_oprs = {
    48.     .owner = THIS_MODULE,
    49.     .open  = led_open,
    50.     .write = led_write,
    51.     .release = led_release,
    52. };
    53. static int myled_init(void)
    54. {
    55.    major = register_chrdev(0, "myled", &myled_oprs);
    56.    led_class = class_create(THIS_MODULE, "myled");
    57.    device_create(led_class, NULL, MKDEV(major, 0), NULL, "ledzzzzzzzz");
    58.    gpio_con = (volatile unsigned long *)ioremap(0x01C20824, 1);   //0x01C20824
    59.    gpio_dat = gpio_con + 4;     //0x01C20834        
    60.    *gpio_con &= ~(7<<28);
    61.    *gpio_con |=  (1<<28);
    62.    *gpio_dat &= ~(1<<7);
    63.    return 0;
    64. }
    复制代码


    APP代码:
    1. <div class="blockcode"><blockquote>#include <sys/types.h>
    2. #include <sys/stat.h>
    3. #include <fcntl.h>
    4. #include <stdio.h>
    5. /* ledtest on
    6. *   * ledtest off
    7. *     */
    8. int main(int argc, char **argv)
    9. {
    10.    int fd;
    11.    unsigned char val = 1;
    12.    fd = open("/dev/ledzzzzzzzz", O_RDWR);
    13.         if (fd < 0)
    14.         {
    15.     printf("can't open!\n");
    16.         }
    17.         if (argc != 2)
    18.         {
    19.    printf("Usage :\n");
    20.    printf("%s <on|off>\n", argv[0]);
    21.    return 0;
    22.         }

    23.         if (strcmp(argv[1], "on") == 0)
    24.         {
    25.    val  = 1;
    26.         }
    27.         else
    28.         {
    29.   val = 0;
    30.         }
    31.   write(fd, &val, 1);
    32.   return 0;
    33. }
    复制代码

    Makefile代码:
    1. KERN_DIR = /root/work/sinlinx/a33/lichee/linux-3.4
    2. all:
    3.         make -C $(KERN_DIR) M=`pwd` modules
    4.         arm-none-linux-gnueabi-gcc  ledtest.c -o ledtest
    5. clean:
    6.         make -C $(KERN_DIR) M=`pwd` modules clean
    7.         rm -rf modules.order
    8. obj-m        += led_drv.o
    复制代码


    沙发
    | 2019-3-15 10:57 | 只看该作者
    不错的??! 可以的?。。。?!
    扫描二维码,随时随地手机跟帖
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    我要发帖 投诉建议 创建版块 申请版主

    快速回复

    您需要登录后才可以回帖
    登录 | 注册
    高级模式

    论坛热帖

    关闭

    热门推荐上一条 /4 下一条

    快速回复 广东快乐十分走势图 返回列表
  • “龙江二号”微卫星传回地月合影 2019-04-18
  • 中国驻泰国大使考察合艾国光中学孔子课堂 2019-04-18
  • 【清园20年】感恩大回馈!半价!半价! 2019-04-18
  • 中央纪委紧盯节点 4年来通报曝光问题近4000起 2019-04-13
  • 2013环球企业领袖宁夏圆桌会议嘉宾云集 2019-04-13
  • 《魔兽世界》未解之谜 那些仍不能被玩家们踏足的领地 2019-04-11
  • 钱江潮评 让高质量发展插上人才的翅膀 2019-04-10
  • 习近平两会期间谈社会主义核心价值观 2019-04-02
  • 文脉颂中华——黄河新闻网 2019-04-02
  • 陈小林的专栏作者中国国家地理网 2019-03-29
  • 中英航母大战谁能赢歼151枚炸弹就能炸瘫女王 2019-03-22
  • 独特“光捕捉器”可控制分子生化性质 2019-03-22
  • 女性之声——全国妇联 2019-03-19
  • 【理上网来·辉煌十九大】德国北威州经济部长:十九大报告表明中国有能力为世界做出更多贡献 2019-03-11
  • 全国小麦收获进度过八成 2019-03-07
  • 彩经网官网 上海市福利彩票官网 好运快3下载 中彩网3d试机号 在线二八杠 今晚河南22选5开奖结果 香港六合彩开奖结果网 时时彩缩水软件电脑版 竟彩首页 足彩胜负彩中奖彩票 最新时时彩计划软件 黑龙江体彩6+1 老时时彩计算方法 搜狐彩票图表数据 通城二八杠 七星彩