arm驱动程序——点亮led-利用次设备号(韦东山的视频总结及针对linux-2.6.30)

相关代码在资源中下载。

主设备号标识设备对应的驱动程序;而次设备号则用来标识同一类设备中的某个唯一的设备。

利用到的函数及结构在上面几节中都有说出,在此不再叙述。

驱动设备:

 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/device.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <linux/poll.h>
 #include <asm/hardirq.h>
 /*不同的linux版本,同文件会有所不同*/

 static int major;

 /*定义类*/
 static struct class *first_class;

 /*类下定义一个设备*/
 static struct device *first_dev[4];
 
 volatile int long *GPBCON = NULL;
 volatile int long *GPBDAT = NULL;
 int myfirst_led_open(struct inode *inode, struct file *file)
 {
       *GPBCON &= ~((3<<10) | (3<<12) | (3<<14) | (3<<16));
       *GPBCON |= (1<<10) | (1<<12) | (1<<14) | (1<<16); 
       *GPBDAT = 0x1e0;
       return 0;
 }
 ssize_t myfirst_led_write(struct file *file, const char __user *user_buffer, 
                           size_t count, loff_t *ppos)
 {
       int minor;
       int val;

       /*得到用户空间的数据*/
       copy_from_user(&val,user_buffer,count);

       /*获取次设备号*/
       minor = MINOR(file->f_dentry->d_inode->i_rdev);
       switch (minor){
    case 0:
      *GPBDAT = 0x1e0;
      *GPBDAT &= (val<<5)&(0x1e0);
      break;
    case 1:
      *GPBDAT = 0x1e0;
      *GPBDAT &= (val<<6)&(0x1e0);
              break;
    case 2:
      *GPBDAT = 0x1e0;
      *GPBDAT &= (val<<7)&(0x1e0);
      break;
    case 3:
      *GPBDAT = 0x1e0;
      *GPBDAT &= (val<<8)&(0x1e0);
      break;
    default:
      break;

        }
     return count;
 }

  /*定义file_operations结构*/
 static struct file_operations myfirst_fops = {
       .owner = THIS_MODULE,
       .write = myfirst_led_write,
       .open = myfirst_led_open,
 };
 static int myfirst_init(void)
 {
       int i;

        /*注册*/
       major = register_chrdev(0,"first_led_minor",&myfirst_fops);

        /*物理地址映射到虚拟地址*/
       GPBCON = (volatile int long *)ioremap(0x56000010,16);
       GPBDAT = GPBCON + 1;

        /*创建类*/
       first_class = class_create(THIS_MODULE,"first_led_minor");
       for(i=0;i<4;i++)
       {    /*创建设备*/
           first_dev[i] = 
           device_create(first_class,NULL,MKDEV(major,i),NULL,"led%d",i);
}
        return 0;
 }
 static void myfirst_exit(void)
 {
       int i;

        /*注销*/
       unregister_chrdev(major,"first_led_minor");

        /*注销虚拟地址*/
       iounmap(GPBCON);
       for(i=0;i<4;i++)

           /*注销设备*/

           device_unregister(first_dev[i]);

       /*销毁定义的类*/
       class_destroy(first_class);

 }
 MODULE_LICENSE("GPL");
 module_init(myfirst_init);
 module_exit(myfirst_exit);

 应用程序:

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
int main(int argc ,char **argv){
    int val;
    char *p;
    int fd;
    if(argc != 3){
         printf("USAGE:file <dev> <on|off>");
     }
     p = argv[1];
     fd = open(p,O_RDWR);
     if(fd < 0)
         printf("can't open!");
     if(strcmp(argv[2],"on") == 0 )
         val = 0;
     else
         val = 1;
     write(fd,&val,1);
     return 0;

}

下面就是检测驱动程序是否正确了,由于led中处于亮的状态,可以用off进行检测。

1.1 课程内容嵌入式软件工程师的学习路线一般是:单片机、RTOS、Linux。当你掌握单片机开发后,如果要进一步提升编程水平,建议学习RTOS(Real Time Operating System,实时操作系统)。有很多优秀的RTOS,比如FreeRTOS、RT-Thread、UCOS等等。FreeRTOS使用范围最广泛,RT-Thread生态丰富,UCOS是收费的并且很少使用了。对于初学者,建议先学习FreeRTOS。只要学会了任意一款RTOS,肯定就会使用其他RTOS了。我们在2022年已经推出了“FreeRTOS快速入门”课程。为何还要重新制作“FreeRTOS入门与工程实践”?“FreeRTOS快速入门”只是讲解FreeRTOS的各类API的理论、用法、示例,这些实验是基于Keil自带的STM32F103模拟器。没有使用更多的硬件模块、不能体现工作中的实际场景。在“FreeRTOS入门与工程实践”,将引入更多的硬件模块,并展示实际工程示例中的用法。另外,基于RTOS的程序一般都比较复杂,涉及的源文件非常多,在工作中一般都基于“面向对象”的思想来写程序。所以,本课程会涉及如下内容:讲解FreeRTOS的常用API:理论、用法选择合适的硬件模块,展示这些API的实例实现合适的小项目,展示工作中的编程方法1.2 讲课方式对于每一个实验,我们会精心设计:要解决什么问题;然后讲解FreeRTOS提供的解决方法。讲解FreeRTOS的API及内部原理(不深入讲解内部源码,只是进行原理性介绍)讲解实验过程使用的模块的接口函数(只讲使用,不讲内部实现,模块的源码实现单独开课讲解)讲解原理时,配合着文档、现场画图进行讲解,跟学校老师写黑板一样最后现场从0编写程序并调试一切都是现场操作,绝对不会照着PPT念,绝对不会照着现成的代码讲解。只有现场从0操作,学员才能身临其境地学习,跟着教程:碰到问题、解决问题。1.3 硬件平台本课程基于DshanMCU-103开发套件进行开发,它由3部分组成:STM32F103C8T6的最小系统板、扩展底板、各类模块。如下图所示:  上述硬件再加一个ST-Link即可学完本课程所有内容。主板DshanMCU-103是基于STM32F103C8T6的最小系统板。之所以选择最小系统板,而不是把所有模块都放在一个整体的电路板上,目的如下:低成本尝试:嵌入式软件开发并不一定适合你,可以购买最小系统板进行体验、及时放弃按需购买:用到再买,讲究一个性价比 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值