📄 driver.c
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009, lst.
//版权所有 (C), 2004-2009, lst.
//所属模块:泛设备管理模块
//作者:lst
//版本:V1.0.0
//文件描述:提供泛设备管理功能
//其他说明:
//修订历史:
// 2. 日期:2009-03-03
// 作者:lst
// 新版本号:1.0.1
// 修改说明: 修正了dev_close_left函数和dev_close_right函数的错误,该bug由
// 网友sniper提交
// 1. 日期:
// 作者:
// 新版本号:
// 修改说明:
//------------------------------------------------------
#include "inc_os.h"
#include <string.h>
static struct pan_device *pg_device_root;
static struct pan_device tg_mem_of_device[cn_device_limit+1];//泛设备控制块内存池
static struct dev_handle tg_mem_of_handle[cn_handle_limit]; //泛设备句柄内存池
static struct mem_cell_pool *pg_pan_device_pool; //设备控制块内存池头指针
static struct mem_cell_pool *pg_device_handle_pool; //设备句柄内存池头指针
static struct mutex_LCB tg_dev_mutex; //保护设备资源树的并发访问安全
//----初始化泛设备驱动---------------------------------------------------------
//功能:1.在资源管理链中增加名为"dev"的根结点.
// 2.初始化泛设备控制块内存池
// 3.初始化泛设备句柄内存池
//参数:无
//返回:无
//-----------------------------------------------------------------------------
bool_t module_driver_init(void)
{
static struct pan_device root;
pg_device_root = (struct pan_device *)
rsc_add_root_node(&root.node,sizeof(struct pan_device),"dev");
//初始化泛设备控制块内存池
pg_pan_device_pool = mb_create((void*)tg_mem_of_device,
cn_device_limit,
sizeof(struct pan_device),
"泛设备控制块池");
//初始化泛设备句柄内存池.
pg_device_handle_pool = mb_create((void*)tg_mem_of_handle,
cn_handle_limit,
sizeof(struct dev_handle),
"泛设备句柄池");
__mutex_createe_knl(&tg_dev_mutex,true,"device driver");
return true;
}
//----添加根设备---------------------------------------------------------------
//功能: 添加一个根设备,根设备是pg_device_root的子设备,本函数直接调用
// dev_add_device实现,纯粹是为了保护全局变量不被pg_device_root别人访问而
// 设立。
//参数: 见dev_add_device的说明
//返回:新加入的设备的资源结点指针.资源不足则返回NULL
//本函数由泛设备driver作者调用,不建议应用程序使用
//-----------------------------------------------------------------------------
struct pan_device *dev_add_root_device(char *name,
struct semaphore_LCB *right_semp,
struct semaphore_LCB *left_semp,
dev_write_func right_write ,
dev_read_func right_read,
dev_ctrl_func right_ctrl ,
dev_write_func left_write ,
dev_read_func left_read ,
dev_ctrl_func left_ctrl )
{
return dev_add_device(pg_device_root,name,
right_semp,left_semp,
right_write,right_read,right_ctrl,
left_write,left_read,left_ctrl);
}
//----添加设备-----------------------------------------------------------------
//功能: 新设备加入到兄弟设备的尾部,
//参数: parent_device,待添加设备的父设备
// name,新设备的名字
// right_semp,设备右手接口信号量指针
// left_semp,设备左手接口信号量指针
// right_write,右手写函数指针
// right_read,右手读函数指针
// right_ctrl,右手控制函数指针
// left_write,左手写函数指针
// left_read,左手读函数指针
// left_ctrl,左手控制函数指针
//返回:新加入的设备的资源结点指针.资源不足则返回NULL
//本函数由泛设备driver作者调用,不建议应用程序使用,故不使用struct dev_handle
//而是用struct pan_device类型参数
//-----------------------------------------------------------------------------
struct pan_device *dev_add_device(struct pan_device *parent_device,
char *name,
struct semaphore_LCB *right_semp,
struct semaphore_LCB *left_semp,
dev_write_func right_write ,
dev_read_func right_read,
dev_ctrl_func right_ctrl ,
dev_write_func left_write ,
dev_read_func left_read ,
dev_ctrl_func left_ctrl )
{
struct pan_device *new_device,*result;
if((parent_device == NULL) || (name == NULL))
return NULL; //设备不能没有名字
if(strchr(name,'\\')) //名字中不能包含字符 \.
return NULL;
mutex_pend(&tg_dev_mutex,cn_timeout_forever);
if(rsc_search_son(&parent_device->node,name) != NULL)
{
y_error_login(enum_drv_homonymy,"设备重名");
result = NULL;
}else
{
if(parent_device != NULL)
{
//分配泛设备控制块给新设备
new_device = mb_malloc(pg_pan_device_pool,0);
if(new_device != NULL)
{
//新设备添加到父设备下成为满子结点
rsc_add_son(&parent_device->node,&new_device->node,
sizeof(struct pan_device),name);
new_device->left_semp = left_semp;
new_device->right_semp = right_semp;
if(right_write != NULL)
new_device->right_hand.io_write = right_write;
else
new_device->right_hand.io_write = (dev_write_func)NULL_func;
if(right_read != NULL)
new_device->right_hand.io_read = right_read;
else
new_device->right_hand.io_read = (dev_read_func)NULL_func;
if(right_ctrl != NULL)
new_device->right_hand.io_ctrl = right_ctrl;
else
new_device->right_hand.io_ctrl = (dev_ctrl_func)NULL_func;
if(left_write != NULL)
new_device->left_hand.io_write = left_write;
else
new_device->left_hand.io_write = (dev_write_func)NULL_func;
if(left_read != NULL)
new_device->left_hand.io_read = left_read;
else
new_device->left_hand.io_read = (dev_read_func)NULL_func;
if(left_ctrl != NULL)
new_device->left_hand.io_ctrl = left_ctrl;
else
new_device->left_hand.io_ctrl = (dev_ctrl_func)NULL_func;
result = new_device;
}else
{
y_error_login(enum_mem_tried,"内存不足");
result = NULL;
}
}else
result = NULL;
}
mutex_post(&tg_dev_mutex);
return result;
}
//----卸载设备------------------------------------------------------------------
//功能: 把设备从设备链表中删除,并释放其占用的内存.该设备需符合以下条件:
// 1.该设备没有子设备.
// 2.正在使用该设备的用户数为0.
//参数: device,待释放的设备
//返回: 成功释放返回true,否则返回false
//与对称函数dev_add_device一样,本函数由泛设备driver作者调用,不建议应用程序
//使用,故不使用struct dev_handle而是用struct pan_device类型参数
//-----------------------------------------------------------------------------
bool_t dev_delete_device(struct pan_device * device)
{
struct rsc_node *node;
bool_t en_del = true;
mutex_pend(&tg_dev_mutex,cn_timeout_forever);
if(device->left_semp != NULL)
if(semp_query_used(device->left_semp) != 0)
en_del = false;
if(device->right_semp != NULL)
if(semp_query_used(device->right_semp) != 0)
en_del = false;
if(en_del)
{ //如果没有用户使用设备,则可以删除.不能使用左右相加==0来判断,因为相加的
//和刚好溢出时等于0.
node = &device->node;
if(rsc_del_node(node) == true)
{
mutex_post(&tg_dev_mutex);
mb_free(pg_pan_device_pool,device);
return(true); //成功卸载设备
}
}
mutex_post(&tg_dev_mutex);
y_error_login(enum_drv_dev_del,NULL);
return false;
}
//----打开设备左手接口---------------------------------------------------------
//功能: 根据设备名打开设备的左手接口,搜索整个设备资源树,找到名称与name匹配的
// 资源结点,然后从泛设备句柄池中分配控制块,把左手接口指针赋值给句柄后,
// 返回该句柄指针。
//参数: name,设备名字符串,包含路径名,但不必包含'dev\'这4个字符
// timeout,超时设置,单位是毫秒,cn_timeout_forever=无限等待,0则立即按
// 超时返回。非0值将被向上调整为cn_tick_ms的整数倍
//返回: 成功打开设备(含经过等待后打开)返回设备句柄,否则返回NULL.
//-----------------------------------------------------------------------------
struct dev_handle *dev_open_left(char *name,uint32_t timeout)
{
struct pan_device *pan;
struct dev_handle *handle;
struct dev_handle *result;
if( ! mutex_pend(&tg_dev_mutex,timeout)) //这是保护设备树的互斥量
return NULL;
//在设备树中搜索设备
pan = (struct pan_device *)rsc_search(&pg_device_root->node,name);
if(pan == NULL) //如果没有找到name设备,返回空
{
result = NULL;
goto end_of_dev_open_left;
}
if(semp_pend(pan->left_semp,timeout)==false)//获取信号量,这是保护设备的
{
result = NULL;
goto end_of_dev_open_left;
}
//在分配内存之前判断信号量,可避免在没有信号的情况下长时间占用内存
handle = mb_malloc(pg_device_handle_pool,0); //从池中分配句柄内存块
if(handle != NULL)
{//成功分配句柄
handle->dev_interfase = pan;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -