【Linux驱动】【手把手设置3568寄存器】点亮RK3568的一颗LED ...

打印 上一主题 下一主题

主题 512|帖子 512|积分 1536

【硬件】

3568的LED9 :引脚 GPIO0 B7
【设置GPIO的复用】


    找设置复用关系的寄存器基地址、偏移地址、对应设置的GPIO。
  查找:io -r -4 0xfdc2000c 系统设置的默认值
结果为1,意思是只有bit 0是1,其他全都为0。所以系统默认就是设置GPIO功能,所以可以不消设置复用GPIO。
【设置GPIO的方向 Direction Register】


查找对应IO设置:io -r -4 0xfdd60008 的默认值(GPIO基地址为0xfdd60000,GPIOB地址偏移8位:0xfdd60008)
结果为:0000c064
二进制 : 1100 0000 0110 0010

bit 15为1 ,所以默认已经设置为输出了

【设置GPIO数据寄存器】


查找对应IO设置:io -r -4 0xfdd60000 的默认值
结果为:8000c040
可知bit15 默以为1
   PB7写1对应的数据寄存器地址:   8000c040
  【问】B7的写使能位是哪一位?


bit31。

   PB7写0对应的数据寄存器地址:80004040
  
  PS   :   bit15设置为0(PB7写0),B7对应控制位bit31必须使能1(写使能) 
  【驱动】 

  1. #define GPIO_DR 0xFDD60000
  2. struct device_test{
  3.     dev_t dev_num;
  4.     static int major = 0;
  5.     static int minor = 0;
  6.     struct cdev cdev_test;
  7.     struct class *class;
  8.     struct device *device;
  9.     char kbuf[32];  //模拟内核寄存器的数据
  10.    
  11.     /************************/
  12.     unsigned int *vir_gpio_dr; //保存GPIO寄存器虚拟地址用的
  13. };
  14. /* 然后定义结构体变量 */
  15. struct device_test dev1;
  16. static int moduleparam_init()
  17. {
  18.            int ret;
  19.            ret = alloc_chrdev_region(&dev1.dev_num,0,1,"HELLO");  
  20.            if(ret<0){
  21.                 goto err_chrdev;
  22.            }
  23.            printk("alloc_chrdev_region ok\n");  
  24.            dev1.major_num =MAJOR(dev1.dev_num); //将主设备号取出来
  25.            dev1.minor_num = MINOR(dev1.dev_num);//将次设备号取出来
  26.            printk("major_num = %d\n", dev1.major_num);//打印传入进来的主设备号
  27.            printk("minor_num = %d\n", dev1.minor_num);//打印传入进来的次设备号
  28.            
  29.            dev1.cdev_test.owner = THIS_MODULE;
  30.            cdev_init(dev1.cdev_test, &cdev_file_operations);
  31.            
  32.            ret = cdev_add(&dev1.cdev_test, dev1.dev_num, 1);
  33.            if(ret<0){
  34.                 goto err_chradd;
  35.            }
  36.            
  37.           dev1.class = class_creat(THIS_MODULE, "test");
  38.            /* 判断创建类有没有失败 */
  39.            if(IS_ERR(dev1,device)){
  40.                ret = PTR_ERR(dev1,device);
  41.                goto err_class_creat;           
  42.            }
  43.            
  44.            dev1.device = device_creat( dev1.class,NULL, dev1.dev_num,,NULL,"test")  
  45.             /* 判断创建类有没有失败 */
  46.            if(IS_ERR(dev1.device)){
  47.                ret = PTR_ERR(dev1,device);
  48.                goto err_device_creat;           
  49.            }                    
  50.            return 0;
  51.            
  52.            dev1.vir_gpio_dr = ioremap(GPIO_DR, 4);
  53.             if(IS_ERR(dev1.vir_gpio_dr)){
  54.                ret = PTR_ERR(dev1.vir_gpio_dr);
  55.                goto err_ioremap;           
  56.            }                    
  57. err_ioremap:
  58.     iounmap(GPIO_DR); //要取消虚拟映射的地址
  59. err_device_creat:  //设备添加失败,意味着设备类添加成功,就要把这个类删掉
  60.     class_destroy( dev1.class);
  61. err_class_creat: //类添加失败,意味着字符设备添加成功,就要把这个字符设备删掉
  62.     cdev_del(& dev1.cdev_test);  //销毁字符设备        
  63. err_chradd: //添加cdev失败,意味着添加设备号成功,就要释放这个设备号
  64.     unregister_chrdev_region( dev1.dev_num,DEVICE_NUMBER);//注销设备号
  65. err_chrdev:
  66.      return ret;
  67. }
复制代码
关键:
  1. static ssize_t cdev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
  2. {
  3.     struct device_test *test_dev = (struct device_test *)file->private_data;
  4.     test_dev->kbuf = {0};
  5.     if(copy_from_user( test_dev->kbuf, buf ,sizeof(buf))!= 0);
  6.     {
  7.        printk("copy_from_user error !\n");
  8.        return -1;
  9.     }
  10.     if(test_dev -> kbuf[0] == 1){
  11.         *(test_dev->vir_gpio_dr) = 0x8000c040;
  12.         else if{
  13.         *(test_dev->vir_gpio_dr) = 0x80004040;        
  14.         }   
  15.     }
  16.     return 0;            
  17. }
  18. static void hello_exit(void)
  19. {
  20.   unregister_chrdev_region( dev1.dev_num,DEVICE_NUMBER);//注销设备号
  21.   cdev_del(& dev1.cdev_test);  //销毁字符设备
  22.   
  23.   device_destroy( dev1.class, dev1.dev_num);
  24.   class_destroy( dev1.class);
  25.   iounmap(GPIO_DR);
  26.   printk("gooodbye! \n");
  27. }
复制代码
【APP】

  1. int main(int argc, char *argv[])
  2. {
  3.    int fd;
  4.    char buf[32] = {0};
  5.    
  6.    fd1 = open("/dev/test", HELLO);  /* 打开设备节点1 */
  7.    if(fd < 0)
  8.    {
  9.        perror("open error \n");
  10.        return fd;   
  11.    }   
  12.    buf[0] = atoi(argv[1]);
  13.    write(fd, buf, sizeof(buf));
  14.    close(fd);  
  15.    return 0;  
  16. }
复制代码
【实行效果】

./a.out 1 可以实现点灯
./a.out 0 可以实现灭灯

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

风雨同行

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表