Edit online

非命令队列模式

非命令队列模式,即 normal 模式。

在 normal 模式下,当用户态通过 open 函数打开/dev/ge 设备节点,会调用到驱动中的 open, 当用户通过 close 关闭驱动的时候,会调用到驱动中的 release。在 open 中主要是实现了模块 clock 的打开操作, 在 release 中实现了模块 clock 的关闭操作。当用户态有多个用户打开 GE 驱动的时候,对驱动打开次数进行引用计数, 至少有一个用户打开 GE 驱动时打开 GE 的 clock, 当所有的用户都关闭 GE 驱动时关闭 GE 的 clock。

../../images/ge_sw_normal_0.png
1. normal 模式架构图
static int ge_open(struct inode *inode, struct file *file)
{
    mutex_lock(&g_data->lock);
    if (g_data->refs == 0) {
        ge_clk_enable(g_data);
    }
    g_data->refs++;
    mutex_unlock(&g_data->lock);

    return nonseekable_open(inode, file);
}

static int ge_release(struct inode *inode, struct file *file)
{
    mutex_lock(&g_data->lock);
    if (g_data->refs == 1) {
        ge_clk_disable(g_data);
    }
    g_data->refs--;
    mutex_unlock(&g_data->lock);
    return 0;
}
normal 模式用户态可用 ioctl
  • IOC_GE_VERSION

  • IOC_GE_MODE

  • IOC_GE_FILLRECT

  • IOC_GE_BITBLT

  • IOC_GE_ROTATE

对于接口 FILLRECT、IOC_GE_BITBLT、IOC_GE_ROTATE 在 normal 模式下调用是同步的, 硬件执行任务完成后接口调用才会返回,在 normal 模式下,无需调用 SYNC 接口

关键流程设计

在 normal 模式下,GE 驱动各种功能都是通过ioctrl调用来实现,每一次ioctrl的调用都包括 GE 参数配置、GE 模块中断开启, GE 启动,GE 等中断(阻塞等待中断服务程序通知中断到来),硬件完成任务后,关闭中断。ioctrl通过 mutex 保护, 支持多用户同时打开驱动设备节点,并调用ioctrl

../../images/ge_sw_normal_11.png
2. normal 模式中断流程
等待中断流程:
  • 在 probe 时候初始化等待队列: init_waitqueue_head(&data->wait);

  • 在 ioctl 中调用如下函数,使当前进程在等待队列中睡眠:

    wait_event_timeout(data->wait, data->status, msecs_to_jiffies(GE_TIMEOUT_MS));
  • 在中断服务程序中调用 wake_up(&data->wait),唤醒等待队列中的睡眠进程