突然有想法把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是一样的。哈哈,自己写着玩,不要见笑!