用 keil 实现 linux里的 MOUDLE_INIT 功能

初学LINUX,发现LINUX里驱动初始化函数只要用MOUDLE_INIT修饰一下,在程序运行的时候就会自动调用初始化函数执行,非常炫酷。

那么使用keil编译器写单片机程序的话能不能这样呢?

于是花了点时间写了一个小小的框架,可以在keil的单片机模拟LINUX包括file_operations,open,write这些功能。

下面贴下我的框架代码。

#ifndef _VFS_H
#define _VFS_H

  
typedef struct
{
	int is_exist;
	void (* init)(void);
	int lvl;
}initlist_t;


//用MOUDLE_INIT修饰的驱动初始化函数,将在应用初始化的时候被执行
#define MOUDLE_INIT(fn,rank) const initlist_t __init_##fn __attribute__((at(0x08001000  + rank * 16))) = { \
.is_exist = 1, \
.init = fn, \
.lvl = rank, \
 } 

 
//驱动程序通过实现这个结构体里提供的函数来实现对硬件的操控
typedef struct
{
	unsigned char is_registered ;
	char * name;
	
	void (*task_always)(void);
	void (*task_d5ms)(void);
	void (*task_2ms)(void);
	void (*task_10ms)(void);
	void (*task_2000ms)(void);
	
	void (*open)(void);
  int (*write)(unsigned int offset,unsigned int size ,unsigned int *val);
	int (*read)(unsigned int offset,unsigned int size ,unsigned int *val);
	
}file_operations;


//驱动程序调用这两个函数来解除注册和注册模组
int register_moudle(file_operations new_moudle);
int unregister_moudle(int fd);



//应用程序调用这些函数来对驱动进操作
int open(char * name);
int write(int fd , unsigned int offset,unsigned int size ,unsigned int *val);
int read(int fd , unsigned int offset,unsigned int size ,unsigned int *val);

//应用程序初始化的时候需要调用这个函数来初始化驱动
void init_register(void);




#endif





#include "string.h"
#include "VFS.h"
#define MOUDLE_NUMBER_MAX 30


/*
 * 指导思想,
 * 为上提供相同应用接口,根据文件名称来对硬件进行操作
 * 相下提供注册接口,硬件调用注册接口,将程序挂接到文件系统中
 */
file_operations moudle[MOUDLE_NUMBER_MAX];


/*
 * 根据设备名称查询文件索引号并返回
 */
int open(char * name)
{
	for(unsigned int i = 0 ; i < MOUDLE_NUMBER_MAX ; i ++)
	{
		if(strcmp(name , moudle[i].name) == 0)
		{
			moudle[i].open();
			return i;
		}
	}
	return -1;
}
/*
 * 根据文件索引来写入参数
 */
int write(int fd , unsigned int index,unsigned int size ,unsigned int *val)
{
	if(moudle[fd].write == 0)
		return -1;
	
	return moudle[fd].write(index,size,val);
}

/*
 * 根据文件索引来读取参数
 */
int read(int fd , unsigned int index,unsigned int size ,unsigned int *val)
{
	if(moudle[fd].read == 0)
		return -1;
	
	return moudle[fd].read(index,size,val);
}


/*
 * 注册模组
 */
int register_moudle(file_operations new_moudle)
{
	for(unsigned short i = 0 ; i <  MOUDLE_NUMBER_MAX ; i ++)
	{
		if(moudle[i].is_registered == 0)
		{
			moudle[i] = new_moudle;
			moudle[i].is_registered = 1;
			return i ;
		}
	}
	
	return -1;
}

/*
 * 解除注册模组
 */
int unregister_moudle(int fd)
{
	if(moudle[fd].is_registered == 1)
	{
		moudle[fd].is_registered = 0 ;
		return 1;
	}
	else
    return -1;
}


/*
 * 初始化注册模组
 */
void init_register()
{
	initlist_t * p_initlist;

	for( int i = 0 ; i < MOUDLE_NUMBER_MAX ; i ++)
	{
		p_initlist = (initlist_t *)(0x08001000 + i * 16);
    if(p_initlist->is_exist == 1)
		{
			p_initlist->init();
		}
	}
}



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值