📄 ipc.c.svn-base
字号:
rt_hw_interrupt_enable(level); return thread->error;}rt_err_t rt_event_control (rt_event_t event, rt_uint8 cmd, void* arg){ return RT_EOK;}#endif /* end of RT_USING_EVENT */#ifdef RT_USING_MAILBOXrt_err_t rt_mb_init(rt_mailbox_t mb, const char* name, void* msgpool, rt_size_t size, rt_uint8 flag){ RT_ASSERT(mb != RT_NULL); /* init object */ rt_object_init(&(mb->parent.parent), RT_Object_Class_MailBox, name); /* set parent flag */ mb->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(mb->parent)); /* init mailbox */ mb->msg_pool = msgpool; mb->size = size; mb->in_offset = 0; mb->out_offset = 0; return RT_EOK;}rt_err_t rt_mb_detach(rt_mailbox_t mb){ /* parameter check */ RT_ASSERT(mb != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all(&(mb->parent)); /* detach mailbox object */ rt_object_detach(&(mb->parent.parent)); return RT_EOK;}rt_mailbox_t rt_mb_create (const char* name, rt_size_t size, rt_uint8 flag){ rt_mailbox_t mb; /* allocate object */ mb = (rt_mailbox_t) rt_object_allocate(RT_Object_Class_MailBox, name); if (mb == RT_NULL) return mb; /* set parent */ mb->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(mb->parent)); /* init mailbox */ mb->size = size; mb->msg_pool = rt_malloc(mb->size); if (mb->msg_pool == RT_NULL) { /* delete mailbox object */ rt_object_delete(&(mb->parent.parent)); return RT_NULL; } mb->in_offset = 0; mb->out_offset = 0; return mb;}rt_err_t rt_mb_delete (rt_mailbox_t mb){ /* parameter check */ RT_ASSERT(mb != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all(&(mb->parent)); /* free mailbox pool */ rt_free(mb->msg_pool); /* delete mailbox object */ rt_object_delete(&(mb->parent.parent)); return RT_EOK;}rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32 value){ register rt_ubase_t temp; /* parameter check */ RT_ASSERT(mb != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* mailbox is full */ if (mb->entry == mb->size) { /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_EFULL; } /* set ptr */ mb->msg_pool[mb->in_offset] = value; /* increase input offset */ mb->in_offset = (++ mb->in_offset) % mb->size; /* increase message entry */ mb->entry ++; /* resume suspended thread */ if (mb->parent.suspend_thread_count > 0) { rt_ipc_object_resume(&(mb->parent)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); rt_schedule(); return RT_EOK;}rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32* value, rt_int32 timeout){ struct rt_thread *thread; register rt_ubase_t temp; /* parameter check */ RT_ASSERT(mb != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* mailbox is empty */ if (mb->entry == 0) { /* get current thread */ thread = rt_thread_self(); /* reset error number in thread */ thread->error = RT_EOK; /* no waiting, return timeout */ if (timeout == 0) { /* enable interrupt */ rt_hw_interrupt_enable(temp); thread->error = -RT_ETIMEOUT; return -RT_ETIMEOUT; } /* suspend current thread */ rt_ipc_object_suspend(&(mb->parent), thread); /* has waiting time, start thread timer */ if (timeout > 0) {#ifdef IPC_DEBUG rt_kprintf("set thread:%s to timer list\n", thread->name);#endif /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); /* re-schedule */ rt_schedule(); /* recv message */ if (thread->error != RT_EOK) /* maybe return RT_ETIMEOUT */ return thread->error; /* disable interrupt */ temp = rt_hw_interrupt_disable(); } /* fill ptr */ *value = mb->msg_pool[mb->out_offset]; /* increase output offset */ mb->out_offset = (++ mb->out_offset) % mb->size; /* decrease message entry */ mb->entry --; /* enable interrupt */ rt_hw_interrupt_enable(temp); return RT_EOK;}rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8 cmd, void* arg){ return RT_EOK;}#endif /* end of RT_USING_MAILBOX */#ifdef RT_USING_MESSAGEQUEUEstruct rt_mq_message{ struct rt_mq_message* next;};rt_err_t rt_mq_init(rt_mq_t mq, const char* name, void *msgpool, rt_size_t msg_size, rt_size_t pool_size, rt_uint8 flag){ struct rt_mq_message* head; register rt_base_t temp; /* parameter check */ RT_ASSERT(mq != RT_NULL); /* init object */ rt_object_init(&(mq->parent.parent), RT_Object_Class_MessageQueue, name); /* set parent flag */ mq->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(mq->parent)); /* set messasge pool */ mq->msg_pool = msgpool; /* get correct message size */ mq->msg_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE); mq->max_msgs = pool_size / (mq->msg_size + sizeof(struct rt_mq_message)); /* init message list */ mq->msg_queue_head = RT_NULL; mq->msg_queue_tail = RT_NULL; /* init message empty list */ mq->msg_queue_free = RT_NULL; for (temp = 0; temp < mq->max_msgs; temp ++) { head = (struct rt_mq_message*)((rt_uint8*)mq->msg_pool + temp * (mq->msg_size + sizeof(struct rt_mq_message))); head->next = mq->msg_queue_free; mq->msg_queue_free = head; } /* the initial entry is zero */ mq->entry = 0; return RT_EOK;}rt_err_t rt_mq_detach(rt_mq_t mq){ /* parameter check */ RT_ASSERT(mq != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all((struct rt_ipc_object*)mq); /* detach message queue object */ rt_object_detach(&(mq->parent.parent)); return RT_EOK;}rt_mq_t rt_mq_create (const char* name, rt_size_t msg_size, rt_size_t max_msgs, rt_uint8 flag){ struct rt_messagequeue* mq; struct rt_mq_message* head; register rt_base_t temp; /* allocate object */ mq = (rt_mq_t) rt_object_allocate(RT_Object_Class_MessageQueue, name); if (mq == RT_NULL) return mq; /* set parent */ mq->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(mq->parent)); /* init message queue */ /* get correct message size */ mq->msg_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE); mq->max_msgs = max_msgs; /* allocate message pool */ mq->msg_pool = rt_malloc(mq->msg_size * mq->max_msgs); if (mq->msg_pool == RT_NULL) { rt_mq_delete(mq); return RT_NULL; } /* init message list */ mq->msg_queue_head = RT_NULL; mq->msg_queue_tail = RT_NULL; /* init message empty list */ mq->msg_queue_free = RT_NULL; for (temp = 0; temp < mq->max_msgs; temp ++) { head = (struct rt_mq_message*)((rt_uint8*)mq->msg_pool + temp * (mq->msg_size + sizeof(struct rt_mq_message))); head->next = mq->msg_queue_free; mq->msg_queue_free = head; } /* the initial entry is zero */ mq->entry = 0; return mq;}rt_err_t rt_mq_delete (rt_mq_t mq){ /* parameter check */ RT_ASSERT(mq != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all(&(mq->parent)); /* free mailbox pool */ rt_free(mq->msg_pool); /* delete mailbox object */ rt_object_delete(&(mq->parent.parent)); return RT_EOK;}rt_err_t rt_mq_send (rt_mq_t mq, void* buffer, rt_size_t size){ register rt_ubase_t temp; struct rt_mq_message *msg; /* greater than one message size */ if (size > mq->msg_size) return -RT_ERROR; /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* get a free list, there must be an empty item */ msg = (struct rt_mq_message*)mq->msg_queue_free; /* message queue is full */ if (msg == RT_NULL) { /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_EFULL; } /* move free list pointer */ mq->msg_queue_free = msg->next; /* copy buffer */ rt_memcpy(msg + 1, buffer, size); /* link msg to message queue */ if (mq->msg_queue_tail != RT_NULL) { /* if the tail exists, */ ((struct rt_mq_message*)mq->msg_queue_tail)->next = msg; } /* the msg is the new tail of list, the next shall be NULL */ msg->next = RT_NULL; /* set new tail */ mq->msg_queue_tail = msg; /* if the head is empty, set head */ if (mq->msg_queue_head == RT_NULL)mq->msg_queue_head = msg; /* increase message entry */ mq->entry ++; /* resume suspended thread */ if (mq->parent.suspend_thread_count > 0) { rt_ipc_object_resume(&(mq->parent)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); rt_schedule(); return RT_EOK;}rt_err_t rt_mq_urgent(rt_mq_t mq, void* buffer, rt_size_t size){ register rt_ubase_t temp; struct rt_mq_message *msg; /* greater than one message size */ if (size > mq->msg_size) return -RT_ERROR; /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* get a free list, there must be an empty item */ msg = (struct rt_mq_message*)mq->msg_queue_free; /* message queue is full */ if (msg == RT_NULL) { /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_EFULL; } /* move free list pointer */ mq->msg_queue_free = msg->next; /* copy buffer */ rt_memcpy(msg + 1, buffer, size); /* link msg to the beginning of message queue */ msg->next = mq->msg_queue_head; mq->msg_queue_head = msg; /* if there is no tail */ if (mq->msg_queue_tail == RT_NULL) mq->msg_queue_tail = msg; /* increase message entry */ mq->entry ++; /* resume suspended thread */ if (mq->parent.suspend_thread_count > 0) { rt_ipc_object_resume(&(mq->parent)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); rt_schedule(); return RT_EOK;}rt_err_t rt_mq_recv (rt_mq_t mq, void* buffer, rt_size_t size, rt_int32 timeout){ struct rt_thread *thread; register rt_ubase_t temp; struct rt_mq_message *msg; /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* mailbox is empty */ if (mq->entry == 0) { /* get current thread */ thread = rt_thread_self(); /* reset error number in thread */ thread->error = RT_EOK; /* no waiting, return timeout */ if (timeout == 0) { /* enable interrupt */ rt_hw_interrupt_enable(temp); thread->error = -RT_ETIMEOUT; return -RT_ETIMEOUT; } /* suspend current thread */ rt_ipc_object_suspend(&(mq->parent), thread); /* has waiting time, start thread timer */ if (timeout > 0) {#ifdef IPC_DEBUG rt_kprintf("set thread:%s to timer list\n", thread->name);#endif /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); /* re-schedule */ rt_schedule(); /* recv message */ if (thread->error != RT_EOK) /* maybe return a RT_ETIMEOUT */ return thread->error; /* disable interrupt */ temp = rt_hw_interrupt_disable(); } /* get message from queue */ msg = (struct rt_mq_message*) mq->msg_queue_head; /* move message queue head */ mq->msg_queue_head = msg->next; /* reach queue tail, set to NULL */ if (mq->msg_queue_tail == msg) mq->msg_queue_tail = RT_NULL; /* copy message */ rt_memcpy(buffer, msg + 1, size > mq->msg_size? mq->msg_size : size); /* put message to free list */ msg->next = (struct rt_mq_message*)mq->msg_queue_free; mq->msg_queue_free = msg; /* decrease message entry */ mq->entry --; /* enable interrupt */ rt_hw_interrupt_enable(temp); return RT_EOK;}rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8 cmd, void* arg){ return RT_EOK;}#endif /* end of RT_USING_MESSAGEQUEUE *//** * @brief init operating system IPC module * * This function will init IPC module. * * @note This function shall be invoked in system init */void rt_system_ipc_init(){}/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -