⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//----------------------------------------------------
//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 + -