一、一个简单的驱动程序实例

led_drv.c 驱动文件:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>

#define DEVICE_MAJOR 111
#define DRIVER_NAME "led_drv"

int led_open(struct inode *inode, struct file *file)
{
  printk(KERN_EMERG "led_drv_open.\n");
  return 0;
}

int led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
  printk(KERN_EMERG "led_drv_write.\n");
  return 0;
}

int led_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
  printk(KERN_EMERG "led_drv_read.\n");
  return 0;
}

static struct file_operations led_fopt = {
  .open = led_open,
  .write = led_write,
  .read = led_read,
};

int __init led_init()
{
  int ret;
  ret = register_chrdev(DEVICE_MAJOR, DRIVER_NAME, &led_fopt);      //注册驱动
  if(ret<0)
  {
    printk(KERN_EMERG "can't register major number.\n");
    return ret;
  }
  return 0;
}

void __exit led_exit()
{
  unregister_chrdev(DEVICE_MAJOR, DRIVER_NAME);               //卸载驱动
}

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");

Makefile 文件:

obj-m += led_drv.o

KERN_DIR = /work/system/linux-2.6.22.6

all:
  make -C $(KERN_DIR) M=`pwd` modules

clean:
  make -C $(KERN_DIR) M=`pwd` modules clean
  rm -rf modules.order

使用 make 命令编译,生成 led_drv.ko, 拷贝 led_drv.ko 至 U 盘, 使用 mount /dev/sda1 /mnt/usb 命令加载 U 盘( mnt 下无 usb 目录需提前新建 )

加载模块 insmod led_drv.ko

卸载模块 rmmod led_drv 

led_app 测试文件:  

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
  int fd;
  int val = 1;
  fd = open("/dev/led_dev", O_RDWR);
  if(fd<0)
  {
    printf("can not open \n");
  }

  write(fd, &val, 4);
  read(fd, &val, 4);
  return 0;
}

使用 arm-linux-gcc -o led_app led_app.c 命令编译 ( 这里只有一个文件就不写 Makefile 了 ), 生成 led_app 拷贝至 U 盘, 并加载  U 盘

重新加载模块 insmod led_drv.ko

运行 ./led_app 发现控制台打印 can not open, 这是因为虽然有了设备驱动, 但是没有设备文件, 所以 open 失败, 因此要先创建设备文件

创建设备文件:

    mknod /dev/led_dev c 111 0

  其中led_dev为设备文件(设备节点)的名称, c表示次设备为字符设备, 111表示该设备所对应的主设备号为111, 0表示该设备的次设备号为0

  运行 ./led_app, 控制台输出:

    led_drv_open.

    led_drv_write.

    led_drv_read.

       

Linux 驱动——从宏观上掌握基本框架的更多相关文章

  1. 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】

    转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...

  2. 【SpringMVC学习01】宏观上把握SpringMVC框架

    springmvc是一个基于mvc的web框架,是spring框架的一个模块,所以springmvc和spring无需通过中间整合层进行整合.我们先来看下spring的一个架构模型,看springmv ...

  3. 【MyBatis学习01】宏观上把握MyBatis框架

    今天开始学习mybatis框架,博客主要记录学习过程中的一些总结,如有错误之处,欢迎留言指正~先用mybatis的鸟鸟来镇个楼,咳咳~~ mybatis框架是一个持久层框架,是Apache下的顶级项目 ...

  4. Linux驱动修炼之道-RTC子系统框架与源码分析【转】

    转自:http://helloyesyes.iteye.com/blog/1072433 努力成为linux kernel hacker的人李万鹏原创作品,为梦而战.转载请标明出处 http://bl ...

  5. Gt9xx芯片,在规格书+Linux驱动的基础上,移植为USB裸机经验。直接用开发板,不去碰硬件的坑。

    1,用内核代码和规格书来印证数据格式: //命令3字节,IC地址 u8 end_cmd[] = {GTP_READ_COOR_ADDR >> , GTP_READ_COOR_ADDR &a ...

  6. Linux内核(17) - 高效学习Linux驱动开发

    这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到 ...

  7. Linux 驱动框架---input子系统

    input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...

  8. linux驱动学习(八) i2c驱动架构(史上最全) davinc dm368 i2c驱动分析【转】

    转自:http://blog.csdn.net/ghostyu/article/details/8094049 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 预备知识 lin ...

  9. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

随机推荐

  1. Java 创建文本内容

    Java 创建文本内容 import java.io.FileWriter; import java.io.IOException; public class TestFile { public st ...

  2. go 编译:交叉编译&编译执行过程

    1. 交叉编译 编译Windows程序和mac程序 GOOS=windows GOARCH-amd64 go build main.go 转自:https://www.cnblogs.com/mafe ...

  3. 算法(第四版)C# 习题题解——1.2

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 这一节内容可能会用到的库文件有 ...

  4. weblogic10补丁升级与卸载

    1.首先将补丁包解压放在weblogic的utils/bsu/cache_dir文件夹下,如果没有该文件夹,则手动创建. 2.回到bsu目录,执行安装命令 C:\Oracle\Middleware\u ...

  5. Spring 学习——Spring AOP——AOP概念篇

    AOP AOP的定义:AOP,Aspect Oriented Programming的缩写,意为面向切面编程,是通过预编译或运行期动态代理实现程序功能处理的统一维护的一种技术 实现方式 预编译 Asp ...

  6. react-router 4.0(四)跳转404

    import React from 'react' import ReactDOM from 'react-dom' import { HashRouter, Route, Link, Prompt, ...

  7. SpringBoot执行定时任务

    1.在启动类中加入@EnableScheduling来开启定时任务. package com.example.demo; import org.springframework.boot.SpringA ...

  8. 使用Docker方式创建3节点的Etcd集群

    一.简要说明 二.运行容器 三.验证集群 四.运行截图 五.参考链接 一.简要说明     参考etcd官网文档, 在node1.node2.node3三个节点上,分别运行etcd容器,创建etcd集 ...

  9. 力扣(LeetCode)561. 数组拆分 I

    给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大. 示例 ...

  10. 加快Gradle的构建过程

    Gradle配置文件中加入守护进程 org.gradle.daemon=true 这个守护进程是在第一次编译时才开启进程进行编译,之后的编译将不再开启进程重新编译,这样以减小编译的速度