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

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; }
-
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。

-
在 probe 时候初始化等待队列: init_waitqueue_head(&data->wait);
在 ioctl 中调用如下函数,使当前进程在等待队列中睡眠:
wait_event_timeout(data->wait, data->status, msecs_to_jiffies(GE_TIMEOUT_MS));-
在中断服务程序中调用 wake_up(&data->wait),唤醒等待队列中的睡眠进程