Device IPC-2

目录

1、completion

1.1、完成量控制块

1.2、completion接口

1.2.1、rt_completion_init()函数

1.2.2、rt_completion_wait()函数

1.2.3、rt_completion_done()函数

2、waitqueue

2.1、等待队列控制块

2.2、waitqueue接口

2.2.1、rt_wqueue_add()函数

2.2.2、rt_wqueue_remove()函数

2.2.3、__wqueue_default_wake()函数

2.2.4、rt_wqueue_wait()函数

2.2.5、rt_wqueue_wakeup()函数

3、workqueue

3.1、workqueue控制块

3.1.1、工作项标志

3.2、workqueue接口

3.2.1、rt_workqueue_create()函数

3.2.2、rt_workqueue_destroy()函数

 3.2.3、rt_workqueue_cancel_all_work()函数

3.3、系统工作队列接口

3.3.1、rt_work_init()函数

3.3.2、rt_work_submit()函数

3.3.3、rt_work_urgent()函数

3.3.4、rt_work_cancel()函数

3.4、指定工作队列接口

3.4.1、rt_workqueue_dowork()函数

3.4.2、rt_workqueue_urgent_work()函数

3.4.3、rt_workqueue_cancel_work()函数

3.4.4、rt_workqueue_cancel_work_sync()函数


1、completion

completion称为完成信号量,是一种轻量级的线程间(IPC)同步机制。有点类似条件变量,存在先后关系。completion使用场景比较广泛,如设备驱动serial、serial_v2、can中都有使用到。

1.1、完成量控制块

struct rt_completion
{
    rt_uint32_t flag; //标志

    rt_list_t suspended_list; //挂起链表 
};

flag表示当前完成量对象的状态。

#define RT_COMPLETED    1
#define RT_UNCOMPLETED  0

1)当 flag 值为 RT_COMPLETED 时,表征当前完成量对象已完成了某一个工作,可以继续下一个工作;

2)当 flag 值为 RT_UNCOMPLETED 时,表征当前需要等待某一个工作结束才能继续下一个工作。

1.2、completion接口

1.2.1、rt_completion_init()函数

该接口用于初始化完成量,设置 flag 为 RT_UNCOMPLETED,然后初始化完成量对象的 suspend 线程链表。

void rt_completion_init(struct rt_completion *completion)

注:完成量的创建只支持静态对象初始化,不支持动态生成对象,在调用初始化接口时,需要传递一个静态的完成量对象的指针。

1.2.2、rt_completion_wait()函数

该接口用于等待某一个动作完成,根据 timeout 不同参数,做超时退出,或者永久等待的处理。

rt_err_t rt_completion_wait(struct rt_completion *completion,
                            rt_int32_t            timeout)

1.2.3、rt_completion_done()函数

该接口用于指示某一个动作已经完成,指示完成后,其他的线程可以获取到该完成状态,并继续运行。

void rt_completion_done(struct rt_completion *completion)

2、waitqueue

等待队列是一种基于资源状态的线程管理的机制,它可以使线程在资源不满足的情况下处于休眠状态,让出CPU资源,而资源状态满足时唤醒线程,使其继续进行业务的处理。如设备驱动serial_v2、pipe中兼容POSIX时有使用到。

等待队列用于使线程等待某一特定的事件发生而无需频繁的轮询,线程在等待期间挂起,在某件事发生时由内核自动唤醒。

2.1、等待队列控制块

struct rt_wqueue
{
    rt_uint32_t flag;
    rt_list_t waiting_list;
};
typedef struct rt_wqueue rt_wqueue_t;

struct rt_wqueue_node
{
    rt_thread_t polling_thread; //等待队列轮询线程
    rt_list_t   list; //等待队列链表

    rt_wqueue_func_t wakeup; //唤醒回调函数
    rt_uint32_t key; //唤醒条件
};

2.2、waitqueue接口

2.2.1、rt_wqueue_add()函数

该接口向等待队列插入一个节点。

void rt_wqueue_add(rt_wqueue_t *queue, struct rt_wqueue_node *node)

2.2.2、rt_wqueue_remove()函数

该接口将从等待队列中删除一个节点。

void rt_wqueue_remove(struct rt_wqueue_node *node)

2.2.3、__wqueue_default_wake()函数

该接口是默认的唤醒函数,但实际上它不做任何事情。它总是返回0,用户应该定义自己的唤醒函数。

int __wqueue_default_wake(struct rt_wqueue_node *wait, void *key)

2.2.4、rt_wqueue_wait()函数

该接口将一个线程加入到指定的等待队列,该线程将在指定的等待队列上挂起等待或超时返回。调用此接口时,唤醒条件key为0,唤醒函数为__wqueue_default_wake()

int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)

注:condition是与POSIX标准接口兼容的参数(目前无意义,只需传入0)。

2.2.5、rt_wqueue_wakeup()函数

该接口将唤醒满足条件key的指定等待队列上的挂起线程。

void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key)

3、workqueue

工作队列是一种转移任务执行环境的工具,例如当系统产生一个中断时,可以在中断处理函数里做一些紧急地操作,然后将另外一些不那么紧急,而且需要一定时间的任务封装成函数交给工作队列执行,此时该函数的执行环境就从中断环境变成了线程环境,这就是 Linux 里经常提及的中断处理 “下半部”。

工作队列内部有一个工作链表(worklist),链表上有多个工作项(work item)节点。工作队列内有个线程一直在轮询工作链表,每次都从工作链表中取出一个工作项,并执行其相关联的函数。当工作队列为空时,线程会被挂起。

注:工作项(work item)里最好不要有会导致线程阻塞的代码,否则会影响后续工作项的执行。

3.1、workqueue控制块

struct rt_workqueue
{
    rt_list_t      work_list; //工作队列链表
    rt_list_t      delayed_list; //延时(定时)链表
    struct rt_work *work_current; //当前工作

    struct rt_semaphore sem; //用于同步的信号量
    rt_thread_t    work_thread; //工作队列处理线程
};

struct rt_work
{
    rt_list_t list; //用于将该工作项挂载到工作链表上去

    void (*work_func)(struct rt_work *work, void *work_data); //工作项绑定的函数指针
    void *work_data; //用户自定义数据
    rt_uint16_t flags; //标志。RT_WORK_STATE_PENDING、RT_WORK_STATE_SUBMITTING
    rt_uint16_t type; //当前版本暂时没用到?!
    struct rt_timer timer; //定时器
    struct rt_workqueue *workqueue; //工作队列指针
};

3.1.1、工作项标志

1)当工作项无延迟时,将flag与上RT_WORK_STATE_PENDING标志。

2)当工作项需要延迟时,会开启一个单次软件定时器。并将flag与上RT_WORK_STATE_SUBMITTING标志。当定时器超时时,去掉RT_WORK_STATE_SUBMITTING标志,并与上RT_WORK_STATE_PENDING标志。

3.2、workqueue接口

3.2.1、rt_workqueue_create()函数

该接口用于创建一个包含线程的工作队列(除了使用系统工作队列,也可以创建属于自己的工作队列)。

struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority)

3.2.2、rt_workqueue_destroy()函数

该接口用于销毁指定工作队列。

rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue)

 3.2.3、rt_workqueue_cancel_all_work()函数

该接口用于取消指定工作队列queue中的所有工作项。

rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue)

3.3、系统工作队列接口

3.3.1、rt_work_init()函数

该接口用于初始化工作项,绑定回调函数。

void rt_work_init(struct rt_work *work,
                  void (*work_func)(struct rt_work *work, void *work_data),
                  void *work_data)

3.3.2、rt_work_submit()函数

该接口用于向系统工作队列提交一个有延迟的工作项。

rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t ticks)

3.3.3、rt_work_urgent()函数

该接口用于向系统工作队列提交一个紧急的工作项(将工作项插入链表头)。

rt_err_t rt_work_urgent(struct rt_work *work)

3.3.4、rt_work_cancel()函数

该接口用于取消系统工作队列中的工作项。

rt_err_t rt_work_cancel(struct rt_work *work)

3.4、指定工作队列接口

3.4.1、rt_workqueue_dowork()函数

该接口用于向指定工作队列queue提交一个无延迟的工作项。

rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work)

3.4.2、rt_workqueue_urgent_work()函数

该接口用于向指定工作队列queue提交一个紧急的工作项(将工作项插入链表头)。

rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *work)

3.4.3、rt_workqueue_cancel_work()函数

该接口用于取消指定工作队列queue中的工作项。

static rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work)

3.4.4、rt_workqueue_cancel_work_sync()函数

该接口用于取消指定工作队列queue中的工作项。如果工作项正在执行,则此函数将阻塞,直到完成为止。

rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值