2 rt-thread之IPC分析

欢迎来到 rt-thread 学习园地
———————————————————————————————————————————————

IPC定义

/**
 * Base structure of IPC object
 */
struct zs_ipc_object
{
    struct zs_object parent;         ///< inherit from rt_object
    zs_list_t suspend_thread;        ///< threads pended on this resource
};

在这里插入图片描述

IPC初始化

/**
 * This function will initialize an IPC object
 *
 * @param ipc the IPC object
 *
 * @return the operation status, ZS_EOK on successful
 */
zs_inline zs_err_t zs_ipc_object_init(struct zs_ipc_object *ipc)
{
    /* initialize ipc object */
    zs_list_init(&(ipc->suspend_thread));   ///> (1)

    return ZS_EOK;
}

代码段 (1):初始化一个ipc双向链表,首地址指向 ipc->suspend_thread。

在IPC总线上挂起线程

/**
 * This function will suspend a thread to a specified list. IPC object or some
 * double-queue object (mailbox etc.) contains this kind of list.
 *
 * @param list the IPC suspended thread list
 * @param thread the thread object to be suspended
 * @param flag the IPC object flag,
 *        which shall be RT_IPC_FLAG_FIFO/RT_IPC_FLAG_PRIO.
 *
 * @return the operation status, RT_EOK on successful
 */
rt_inline rt_err_t rt_ipc_list_suspend(rt_list_t        *list,
                                       struct rt_thread *thread,
                                       rt_uint8_t        flag)
{
    /* suspend thread */
    rt_thread_suspend(thread);                              ///> (1)
    switch (flag)
    {
    case RT_IPC_FLAG_FIFO:                                  ///> (2)
        rt_list_insert_before(list, &(thread->tlist));      ///> (3)
        break;
    case RT_IPC_FLAG_PRIO:                                  ///> (4)
        {
            struct rt_list_node *n;
            struct rt_thread *sthread;
            /* find a suitable position */
            for (n = list->next; n != list; n = n->next)
            {
                sthread = rt_list_entry(n, struct rt_thread, tlist);    ///> (5)

                /* find out */
                if (thread->current_priority < sthread->current_priority)   ///> (6)
                {
                    /* insert this thread before the sthread */
                    rt_list_insert_before(&(sthread->tlist), &(thread->tlist)); 
                    break;
                }
            }
            /*
             * not found a suitable position,
             * append to the end of suspend_thread list
             */
            if (n == list)                                          ///> (7)
                rt_list_insert_before(list, &(thread->tlist));      ///> (8)
        }
        break;
    }
    return RT_EOK;
}

代码段(1):挂起线程。
代码段(2):使用 RT_IPC_FLAG_FIFO 先进先出 flag创建的 IPC 对象,在多个线程等待资源时,将按照先来先得的顺序获得资源。
代码段(3):在 例如 sem对象的 sem->parent.suspend_thread 插入 当前线程的链表节点。
代码段(4):使用 RT_IPC_FLAG_PRIO 优先级 flag 创建的 IPC 对象,在多个线程等待资源时,将由优先级高的线程优先获得资源。
代码段(5):根据结构体成员,找到当前线程结构体首地址。
代码段(6):如果 thread 的优先级小于 sthread 的优先级,将 thread 插入到 sthread 的前面。
代码段(7):如果 list 地址等于 list->next 地址,表示 例如 sem对象的 sem->parent.suspend_thread 没有合适的位置插入。就将例如 sem对象的 sem->parent.suspend_thread插入在链表最前面。

解挂在IPC上的线程

/**
 * This function will resume the first thread in the list of a IPC object:
 * - remove the thread from suspend queue of IPC object
 * - put the thread into system ready queue
 *
 * @param list the thread list
 *
 * @return the operation status, RT_EOK on successful
 */
rt_inline rt_err_t rt_ipc_list_resume(rt_list_t *list)
{
    struct rt_thread *thread;
    /* get thread entry */
    thread = rt_list_entry(list->next, struct rt_thread, tlist);    ///> (1)
    /* resume it */
    rt_thread_resume(thread);       ///> (2)
    return RT_EOK;
}

代码段(1):根据 例如 sem 对象的 sem->parent.suspend_thread ,确定当前线程的结构体地址。
代码段(2):从挂起的队列中移除,插入到就绪的列表中。

解挂在IPC上的所有线程

/**
 * This function will resume all suspended threads in a list, including
 * suspend list of IPC object and private list of mailbox etc.
 *
 * @param list of the threads to resume
 *
 * @return the operation status, RT_EOK on successful
 */
rt_inline rt_err_t rt_ipc_list_resume_all(rt_list_t *list)
{
    struct rt_thread *thread;
    register rt_ubase_t temp;
    /* wakeup all suspended threads */
    while (!rt_list_isempty(list))          ///> (1)
    {
        /* disable interrupt */
        temp = rt_hw_interrupt_disable();   ///> (2)
        /* get next suspended thread */
        thread = rt_list_entry(list->next, struct rt_thread, tlist);    ///> (3)
        /* set error code to RT_ERROR */
        thread->error = -RT_ERROR;
        /*
         * resume thread
         * In rt_thread_resume function, it will remove current thread from
         * suspended list
         */
        rt_thread_resume(thread);       ///> (4)
        /* enable interrupt */
        rt_hw_interrupt_enable(temp);   ///> (5)
    }
    return RT_EOK;
}

代码段:(1)检查例如 sem 对象的 sem->parent.suspend_thread 挂起列表是否为空,不为空继续执行 while 内数据。
代码段:(2)使能中断嵌套。
代码段:(3)根据 例如 sem 对象的 sem->parent.suspend_thread ,确定当前线程的结构体地址。
代码段:(4)从挂起的队列中移除,插入到就绪的列表中。
spend_thread 挂起列表是否为空,不为空继续执行 while 内数据。
代码段:(2)使能中断嵌套。
代码段:(3)根据 例如 sem 对象的 sem->parent.suspend_thread ,确定当前线程的结构体地址。
代码段:(4)从挂起的队列中移除,插入到就绪的列表中。
代码段:(5)失能中断嵌套。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值