课程列表

基本问题

开源资源

好好学习天天向上

联大大纲—通信电子 ;教师介绍; 单片机课程学习经验- 学习路线图; 1.概述 -应用 -定义 -特点 -构成; 2.嵌入式处理器 —DIY CPU处理器ARM处理器Cortex-A8S5PV210讨论; 3.汇编语言 -作业 4.Bootloader -作业 5.Linux内核移植 6.嵌入式Linux程序设计 7.图形用户接口QT 8.其他框架介绍; 9.嵌入式物联网应用系统设计

文件路径:书附光盘\6应用例程\6Linux\driver\01_demo\demo.c

文件内容:

1.定义设备名- DEMO

#ifdef MODULE                               //需要编译为模块

#include <linux/module.h>

#ifdef CONFIG_DEVFS_FS

#include <linux/devfs_fs_kernel.h>

#endif

#include <linux/init.h>                     //初始化相关头文件

#include <linux/kernel.h>                        //printk()等函数有关的头文件

#include <linux/slab.h>                     //kmalloc()等函数有关的头文件

#include <linux/fs.h>                       //与文件系统有关的头文件everything...  

#include <linux/errno.h>                    //错误代码处理头文件error codes  

#include <linux/types.h>                    //数据类型头文件size_t  

#include <linux/proc_fs.h>                  //与进程调度相关的头文件

#include <linux/fcntl.h>                    //O_ACCMODE  

#include <linux/poll.h>                     //COPY_TO_USER  

#include <asm/system.h>                     //cli(), *_flags  

#define DEVICE_NAME "DEMO"                       //定义虚拟设备的名称为DEMO  

#define DEMORAW_MINOR 1

#define DEMO_Devfs_path "demo/0"

//定义全局变量

static int demoMajor = 0;              

static int MAX_BUF_LEN=1024;                //定义缓冲区最大长度

static char drv_buf[1024];                  //内核定义一缓冲区

static int WRI_LENGTH=0;

2static void do_write()

/************************************************************************************

名称:do_write()

功能:将数组drv_buf[]内容逆序重排,用于被demo_write()调用。

入口参数:  排序前数据存于数组drv_buf[],数组drv_buf[]为全局变量。

出口参数:  排序后数据存于数组drv_buf[]

************************************************************************************/

static void do_write(void)

{

    int     i;

    int     len = WRI_LENGTH;                    //WRI_LENGTH值来自demo_write()函数

    char    tmp;

    for(i = 0; i < (len>>1); i++,len--){

        tmp = drv_buf[len-1];

        drv_buf[len-1] = drv_buf[i];             //drv_buf[]数组进行逆序排列

        drv_buf[i] = tmp;}}

3demo_write()

/************************************************************************************

名称:demo_write()

功能:对应于应用层write系统调用。

将应用层用户定义缓冲区中数据复制到内核缓冲区drv_buf[]

调用do_write()函数对数组drv_buf[]进行逆序排列。

入口参数:  *filp 操作设备文件的ID,指向用户程序test_demo.c中打开的设备。

  *buffer 应用层用户定义缓冲区的起始地址

  count 应用层用户定义缓冲区的长度

出口参数:  返回排序数组长度

************************************************************************************/

static ssize_t demo_write(struct file *filp,const char *buffer, size_t count)

{

    if(count > MAX_BUF_LEN)                      //数据<1024,越界保护

    count = MAX_BUF_LEN;                   

    copy_from_user(drv_buf , buffer, count);         //复制用户buffer到内核空间drv_buf

    WRI_LENGTH = count;

    printk("user write data to driver\n");       //输出提示行

    do_write();                                  //调用排序函数

    return count;}

4demo_read

/************************************************************************************

名称:demo_read()

功能:对应于应用层read系统调用。

将内核缓冲区drv_buf[]中数据复制到应用层用户定义的缓冲区中。

入口参数:  *filp 操作设备文件的ID,指向用户程序test_demo.c中打开的设备。

*buffer 应用层用户定义缓冲区的起始地址

count 应用层用户定义缓冲区的长度

*ppos 用户在文件中进行存储操作的位置

出口参数:  返回排序数组长度

************************************************************************************/

static ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

{

    if(count > MAX_BUF_LEN)

    count=MAX_BUF_LEN;

    copy_to_user(buffer, drv_buf,count);    //内核排列后的drv_buf传递给用户buffer

    printk("user read data from driver\n"); //输出提示行

    return count;}

5demo_ioctl

/************************************************************************************

名称:demo_ioctl()

功能:对应于应用层ioctl系统调用。

展示对用户空间传递过来的命令的处理过程

入口参数:  *filp操作设备文件的ID,指向用户程序test_demo.c中打开的设备。

cmd 来自应用层参数

arg 来自应用传递过来的参数列表

出口参数:  正确返回0 ,错误命令返回default 的提示内容

************************************************************************************/

static int demo_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned                     long arg)

{

    switch(cmd){                                          //对来自应用层参数的处理

    case 1:printk("runing command 1 \n");break;

    case 2:printk("runing command 2 \n");break;

    default:

    printk("error cmd number\n");break;}

    return 0;}

6demo_open

//**********************************************************************

名称:static void demo_open()

功能:定义设备文件打开函数,对应于应用层open系统调用

入口参数:  设备文件节点,可附加参数(如O_RDWR表示以即读也写方式访问被打开文件)

出口参数: 

**********************************************************************/

static int demo_open(struct inode *inode, struct file *file)

{

    printk(KERN_DEBUG" device open sucess!\n");

    return 0;}

7demo_release

//**********************************************************************

名称:static void demo_ release ()

功能:设备文件释放函数,对应用应用层close系统调用,

入口参数:  设备文件节点

出口参数: 

**********************************************************************/

static int demo_release(struct inode *inode, struct file *filp)

{

    printk(KERN_DEBUG "device release\n");

    return 0;}

8demo_fops

//**********************************************************************

名称:demo_fops 设备文件结构

功能: 设备驱动文件结构体

       关联系统操作writereadioctlopenrelease与实体函数

**********************************************************************/

static struct file_operations demo_fops = {

    owner: THIS_MODULE,

    write: demo_write,

    read:demo_read,

    ioctl: demo_ioctl,

    open: demo_open,

    release: demo_release}

9demo_init (register)

//**********************************************************************

名称:static void demo_init ()

功能:设备注册函数,通过register_chrdev向内核字符设备链表注册该字符设备

入口参数: 

出口参数: 

**********************************************************************/

static int __init demo_init(void)

{

    int ret;

    ret = register_chrdev(0, DEVICE_NAME, &pxa270_fops);

    if (ret < 0) {

    printk(DEVICE_NAME "can't get major number\n");

    return ret;}

    demoMajor=ret;

    return 0;}

10demo_ exit (unregister)

//**********************************************************************************

名称:static void demo_ exit()

功能:设备注销函数,通过unregister_chrdev 向内核字符设备链表注销该字符设备

入口参数: 

出口参数: 

************************************************************************************/

#ifdef MODULE

static void __exit demo_exit(void)

{

    unregister_chrdev(demoMajor, DEVICE_NAME);

}

module_exit(demo_exit);

#endif

11Module_

module_init(demo_init);                          //模块初始化

MODULE_LICENSE("Dual BSD/GPL");                  //版权信息

#endif //MODULE