自己编程实现简单的字符设备架构

来源:互联网 发布:手机号码搜索软件 编辑:程序博客网 时间:2024/06/07 08:41

突然有想法把stm32的程序结构根据linux驱动结构来做,能做一个结构体,然后注册,然后之后调用都是标准的open,read,write接口,思考了一下,就用结构体和函数指针实现。

下面是内核源文件:

#include <stdio.h>

#include "BSP_Core.h"

Drv drv_table[32];

unsigned int init_drv_list(Drv *table)
{
    return 1;
}

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

//  (1)register_dev
//  (2)open_dev to init in the process

/***************************************/
    
unsigned int register_dev(Drv dev)
{   
    unsigned int id;
    id = dev.drv_id;
    drv_table[id] = dev;
    return 1;
}   
    
unsigned int open_dev(unsigned int id , unsigned char* buff, unsigned int num)
{
    drv_table[id].open_drv( buff, num);
    return 1;
}

unsigned int read_dev(unsigned int id , unsigned char* buff, unsigned int num)
{   
    drv_table[id].read_drv( buff, num);
    return 1;
}

unsigned int write_dev(unsigned int id , unsigned char* buff, unsigned int num)
{
    drv_table[id].open_drv( buff, num);
    return 1;
}

unsigned int close_dev(unsigned int id , unsigned char* buff, unsigned int num)
{
    drv_table[id].open_drv( buff, num);
    return 1;
}

下面是内核头文件:

ifndef _BSP_Core_H
#define _BSP_Core_H

typedef struct {

   unsigned int drv_id;
   unsigned int (*open_drv) (unsigned char* , unsigned int);
   unsigned int (*read_drv) (unsigned char* , unsigned int);
   unsigned int (*write_drv)(unsigned char* , unsigned int);
   unsigned int (*close_drv)(unsigned char* , unsigned int);
   unsigned int flag_tail;
} Drv;

extern Drv drv_table[32];

unsigned int init_drv_list(Drv *table);

unsigned int register_dev(Drv dev);

unsigned int open_dev(unsigned int id , unsigned char* buff, unsigned int num);

unsigned int read_dev(unsigned int id , unsigned char* buff, unsigned int num);

unsigned int write_dev(unsigned int id , unsigned char* buff, unsigned int num);

unsigned int close_dev(unsigned int id , unsigned char* buff, unsigned int num);

#define LED 0

#endif


下面是一个驱动文件:

#include <stdio.h>
#include "BSP_Core.h"
#include "led.h"

extern Drv drv_table[32];

unsigned int open_temp(unsigned char *x,unsigned int num)
{
    printf("x is %d\n",*x);
    return sizeof(x);
}

unsigned int read_temp(unsigned char *x,unsigned int num)
{
    printf("x is %d\n",*x);
    return sizeof(x);
}

unsigned int write_temp(unsigned char *x,unsigned int num)
{
    printf("x is %d\n",*x);
    return sizeof(x);
}


void init_led(void)
{
    Drv led;
    led.drv_id = LED;
    led.open_drv = & open_temp;
    led.read_drv = & read_temp;
    led.write_drv = & write_temp;
    register_dev(led);
}

下面是驱动文件的头文件:

#ifndef _led_H
#define _led_H

void init_led(void);

#endif

下面是一个测试文件:

#include <stdio.h>
#include "BSP_Core.h"
#include "led.h"

void main()
{
    unsigned char x[1];
    x[0] = 1;
    init_led();
    open_dev( LED , x , 1 );
    x[0]++;
    read_dev(LED,x,1);
    x[0]++;
    write_dev(LED,x,1);
}

我来讲一讲这套框架的用法:

(1)驱动文件的写法:

         和linux一样,也需要一个入口函数,不过这个入口函数将在用户程序中直接做调用。这个函数中,要完成如下几个部分:

       1.定义一个驱动结构体

       2.写好open,read,write,close,然后复制给该结构体;

       3.注册一个驱动; register_dev(led);

为了方便可以把设备号提前define 在BSP_Core.h中。

(2)用户文件的写法:

         调用入口函数,之后的和linux是一样的。哈哈,自己写着玩,不要见笑!




1 0
原创粉丝点击