1、模块参数
  应用编程:
      int main(int argc, char *argv[])
      {
         
      }
      ./a.out xxx yyy zzz
  内核编程:
      
      insmod xxx.ko  参数信息    
      
  希望在安装内核模块时也可以给其传递参数,需要使用模块参数
 
 
  模块参数的实现步骤:
     1)在模块中定义全局变量
     2)使用
        module_param(name,type,perm);或者
        module_param_array(name,type,nump,perm);
        将该变量声明为模块参数
        
  module_param(name,type,perm);
     name, 全局变量的名称
     type, 变量的类型
           内核支持声明为模块参数的变量类型 int short long charp
     perm, 访问权限
  module_param_array(name,type,nump,perm);  
     作用:将一个数组声明为模块参数
     name, 数组名称
     type, 数组成员变量的数据类型
     nump, 数组元素个数指针
     perm, 访问权限     
   
  实验步骤:
    insmod moduleparam.ko
    rmmod  moduleparam
    
    insmod moduleparam.ko irq=100  str="hello" fish=1,2,3,4,5   
   
    ls /sys/module/moduleparam/parameters/       无显示
    cd /sys/module/moduleparam/parameters/   
    cat fish
    cat irq
    echo 1234 >irq
    echo 11,22,33,44,55,66 >fish
    cd /
    rmmod moduleparam
  模块参数的使用场景:
    调试代码时使用
    
    REG1=irq;
    
    insmod xxx.ko irq= 100
    rmmod xxx.ko
    insmod xxx.ko irq=101;

2、系统调用
   谈谈对系统调用的理解?
   
   什么是系统调用?
       是操作系统提供应用编程者调用的一组特殊函数
   系统调用的作用?
       保护内核的安全
       保证用户空间以安全的方式调用内核中的函数
   系统调用是如何实现的
       
       在用户空间指定系统调用号
       产生软中断异常 陷入内核态执行
       执行异常向量表 跳转到软中断异常处理代码
       在软中断异常处理代码中根据系统调用号
       找到内核中的对应函数
       并且执行该函数
       执行完毕后将结果原路返回给用户空间
       
       
       系统调用号:arch/arm/include/asm/unistd.h
       软中断指令:
                   arm, swi/svc
                   intel, int
       异常向量表:arch/arm/kernel/entry-armv.S
       软中断异常处理代码:arch/arm/kernel/entry-common.S
       系统调用表:calls.S
  增加一个新的系统调用
     cd /home/tarena/driver/kernel/
     vi arch/arm/kernel/sys_arm.c
        asmlinkage int sys_add(int x, int y)
    {
        printk("<1>" "enter %s\n", __func__);
        return x+y;
    }
     vi arch/arm/include/asm/unistd.h //增加新的系统调用号
        #define __NR_add   (__NR_SYSCALL_BASE+378)
     vi arch/arm/kernel/calls.S//更新系统调用表
        390                 CALL(sys_add)   
   make uImage
   让开发板使用新内核
   
   vi test.c
       
      open=("a.txt", O_RDWR) 等价于
      syscall(5, "a.txt", O_RDWR)
      
      read(fd, buf,len) 等价于
      syscall(3,fd,buf,len)
   arm-cortex_a9-linux-gnueabi-gcc test.c -o test
   cp test ../../rootfs
   
   ./test //注意使用新旧内核的区别

3、字符设备驱动编程

linux是使用C编程实现的
  但是内核实现过程中大量运用了面向对象的编程思想
 
 
  在linux中实现一个字符设备(例如 按键 鼠标 触摸屏 LCD 。。。)
  驱动程序,其实质就是实例化一个struct cdev类型的对象
 
  struct cdev
  {
     //设备号
     dev_t dev;
     const struct file_operations *ops;   
     ...
  }
 3.1 设备号
     本质是一个32bit的无符号数据
     
     设备号=主设备号(高12bit) + 次设备号(低20bit)
     
     主设备号,用于区分不同类型的设备
     次设备号,用于区分同一类设备中的不同个体
     
     ls /dev/ttySAC* -l
     
     设备号的申请与注册有两种方式 :
         1)静态方式
         2)动态方式
   3.1.1 静态方式
        查看已经有哪些主设备号被占用
            cat /proc/devices
        
        从没被占用的主设备号挑一个为我所用      
         
        int register_chrdev_region(dev_t from, unsigned count,
                                   const char *name)
            作用:注册连续的多个设备号
            from, 要注册的起始设备号
            count, 要注册的个数
            name, 名称
            返回值,0 成功
                    <0 失败
        void unregister_chrdev_region(dev_t from, unsigned count)            
                    
        实验步骤:
            insmod led_drv.ko
            cat /proc/devices
            rmmod led_drv.ko
            cat /proc/devices
    3.1.2 动态方式
         由内核动态分配一个未被使用主设备号
         
         int alloc_chrdev_region(dev_t *dev,
                  unsigned baseminor, unsigned count,
            const char *name)       
            dev,传出参数   
                用于返回分配得到的第一个设备号
            baseminor,起始次设备号
            count,申请的连续设备号的个数
            name, 名称
            
         注销:unregister_chrdev_region       
  3.2 操作(驱动)函数集合
      实现一个字符设备硬件的驱动程序
      实则就是实例化一个struct cdev对象
      在实例化struct cdev对象过程中主要的编码工作
      集中在了struct file_operations   
      
      struct file_operations
      {
          owner
          open
          read
          write
          mmap
          release
          unlocked_ioctl
          poll
          ...
      }
      具体某个特定的字符设备硬件,只需要实现其中的部分函数即可
  3.3 内核中提供的关于cdev的API  
      void cdev_init(struct cdev *cdev,
               const struct file_operations *fops)
      {
          cdev->ops = fops;
          ...
          
      }
      
      //注册cdev 将一条学生记录插入到数据库中
      cdev_add(struct cdev *p, dev_t dev, unsigned count)
      {
          p->dev = dev;
          ...
      }
      //注销cdev 将一条学生的记录从数据库中删除
      void cdev_del(struct cdev *p)    
          
     实验步骤:
         1)insmod led_drv.ko
            找到该驱动使用的主设备号 和 次设备号
         2)在开发板上创建设备文件
            mknod /dev/myleds c 244  5
         3)vi test.c
            
            fd = open("/dev/myleds", O_RDWR);  
         4) arm-cortex_a9-linux-gnueabi-gcc test.c -o test
         5) 板子上执行test
            cp test ../../rootfs
            
            ./test
     总结:
         linux下一切皆文件  除了socket

//模块传参
#include "../../global.h"
int irq = ;
char *str = "tarena";
int fish[] = {};
/*保存fish元素个数*/
int num_fish = ; module_param(irq, int, );
module_param(str, charp, );
module_param_array(fish, int, &num_fish,);
int __init moduleparam_init(void)
{
int i = ;
printk("<1>" "irq=%d\n", irq);
printk("<1>" "str=%s\n", str); for(; i<num_fish; i++)
{
printk("<1>" "fish[%d]=%d\n", i, fish[i]);
}
return ;
}
void __exit moduleparam_exit(void)
{
int i = ;
printk("<1>" "irq=%d\n", irq);
printk("<1>" "str=%s\n", str); for(; i<num_fish; i++)
{
printk("<1>" "fish[%d]=%d\n", i, fish[i]);
}
}
module_init(moduleparam_init);
module_exit(moduleparam_exit);
//设备号的注册。
#include "../../global.h"
#include <linux/fs.h> unsigned int major = ;
unsigned int minor = ;
dev_t dev ; //设备号 int __init led_drv_init(void)
{
//dev = major<<20|minor;
dev = MKDEV(major, minor); register_chrdev_region(dev, , "myleds"); return ;
}
void __exit led_drv_exit(void)
{
unregister_chrdev_region(dev, );
}
module_init(led_drv_init);
module_exit(led_drv_exit);
//设备号的动态注册
1 #include "../../global.h"
#include <linux/fs.h> unsigned int major = ;
unsigned int minor = ;
dev_t dev ; //设备号 int __init led_drv_init(void)
{
if(major) //静态
{
//dev = major<<20|minor;
dev = MKDEV(major, minor); register_chrdev_region(dev, , "myleds");
}
else //动态注册
{
alloc_chrdev_region(&dev, minor, , "myleds");
printk("<1>" "major=%d minor=%d\n",
MAJOR(dev), MINOR(dev));
}
return ;
}
void __exit led_drv_exit(void)
{
unregister_chrdev_region(dev, );
}
module_init(led_drv_init);
module_exit(led_drv_exit);
#include "../../global.h"
#include <linux/fs.h>
#include <linux/cdev.h> unsigned int major = ;
unsigned int minor = ;
dev_t dev ; //设备号 /*1 定义一个struct cdev变量*/
struct cdev led_cdev; static int led_open(struct inode *inode,
struct file *filp)
{
printk("<1>" "enter %s\n", __func__);
return ;
}
static int led_close(struct inode *inode,
struct file *filp)
{
printk("<1>" "enter %s\n", __func__);
return ;
} struct file_operations led_fops =
{
.owner = THIS_MODULE,
.open = led_open,
.release = led_close,
};
int __init led_drv_init(void)
{
if(major) //静态
{
//dev = major<<20|minor;
dev = MKDEV(major, minor); register_chrdev_region(dev, , "myleds");
}
else //动态注册
{
alloc_chrdev_region(&dev, minor, , "myleds");
printk("<1>" "major=%d minor=%d\n",
MAJOR(dev), MINOR(dev));
}
/*2 初始化cdev变量*/
cdev_init(&led_cdev, &led_fops);
/*3 注册cdev变量*/
cdev_add(&led_cdev, dev, ); return ;
}
void __exit led_drv_exit(void)
{
/*4 注销cdev*/
cdev_del(&led_cdev); unregister_chrdev_region(dev, );
}
module_init(led_drv_init);
module_exit(led_drv_exit);

模块参数,系统调用,字符设备编程重要数据结构,设备号的申请与注册,关于cdev的API的更多相关文章

  1. pygame模块参数汇总(python游戏编程)

    一.HelloWorld pygame.init() #初始函数,使用pygame的第一步: pygame.display.set_mod((600,500),0,32) #生成主屏幕screen:第 ...

  2. MPU6050带字符驱动的i2c从设备驱动1

    开干: 1.闲言碎语 这个驱动,越写觉的越简单,入门难,入门之后感觉还好.Linux开发还是比较友好的. 2.编写MPU6050带字符驱动的i2c从设备驱动 要实现的功能就是,将MPU6050作为字符 ...

  3. Linux设备驱动程序 之 模块参数

    模块支持参数的方法 内核允许驱动程序指定参数,这些参数可在运行insmod或者modprobe命令装载模块时赋值,modprobe还可以从它的配置文件(/etc/modporb.conf)中读取参数值 ...

  4. 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联

    转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...

  5. Linux设备驱动编程之复杂设备驱动

    这里所说的复杂设备驱动涉及到PCI.USB.网络设备.块设备等(严格意义而言,这些设备在概念上并不并列,例如与块设备并列的是字符设备,而PCI.USB设备等都可能属于字符设备),这些设备的驱动中又涉及 ...

  6. [kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联

    转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动 ...

  7. insmod module_param 模块参数

    模块参数 引导模块时,可以向它传递参数.要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模 ...

  8. linux模块参数

    驱动需要知道的几个参数因不同的系统而不同. 从使用的设备号( 如我们在下一章见到的 ) 到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列 的使用, IDE 驱动 ...

  9. windows核心编程---第九章 同步设备IO与异步设备IO之同步IO

    同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...

随机推荐

  1. 如何在github上下载单个文件夹?

    前言:在查看源码的过程中,相信很多人都像我一样,遇到某个公司或个人的repository是几个项目的集合整理,而我只要其中某个项目文件夹.那不依赖其他软件,怎么通过git去下载呢??? 下面直接给个例 ...

  2. 深入了解opacity和rgba

    1. rgba 首先它是一个属性值,语法为rgba(r,g,b,a) - r为红色值, 正整数 | 百分数 - g为绿色值,正整数 | 百分数 - b为蓝色值,正整数 | 百分数 - a为alpha( ...

  3. 《java编程思想》P22-P37(第二章一切都是对象)

    1.JAVA操纵的标识符实际上是对象的一个"引用";如String s;里的s是String类的引用并非对象. 2.程序运行时,有五个不同的地区可以存储数据. (1)寄存器:最快的 ...

  4. 微信小程序发起请求

    一.示例代码 wx.request({ url: 'test.php', // 仅为示例,并非真实的接口地址 data: { x: '', y: '' }, header: { 'content-ty ...

  5. Windows 服务程序(一)

    Windows 服务程序简介: Windows服务应用程序是一种需要长期运行的应用程序,它对于服务器环境特别适合. 它没有用户界面,并且也不会产生任何可视输出.任何用户消息都会被写进Windows事件 ...

  6. [JOYOI1326] 剑人合一

    题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目描述 他们飘呀飘,飘呀飘,飘呀飘,飘呀飘~~~经过七七八十一天的漂泊,残雪.夏夜和水手2 ...

  7. HDU 3371 Connect the Cities(并查集+Kruskal)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先 ...

  8. redis应用场景总结redis平时我们用到的地方蛮多的,下面就了解的应用场景做个总结:

    redis常见应用场景 1.热点数据的缓存 由于redis访问速度块.支持的数据类型比较丰富,所以redis很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作,这 ...

  9. java架构之路-(Redis专题)简单聊聊redis分布式锁

    这次我们来简单说说分布式锁,我记得过去我也过一篇JMM的内存一致性算法,就是说拿到锁的可以继续操作,没拿到的自旋等待. 思路与场景 我们在Zookeeper中提到过分布式锁,这里我们先用redis实现 ...

  10. 仿写vue UI 组件总结 (自己练习,仿照现有的UI组件)

    UI组件 Vue开发插件流程 本来是昨天要写总结的,感觉自己写不好,就放弃了.今天看到了iview和element有一些摩擦,是关于代码借鉴的问题(哈哈),不做评价.谁下生会写组件,我仿(chao)写 ...