📄 ipc.c.svn-base
字号:
mutex->owner = thread; mutex->hold ++; /* set thread error */ thread->error = RT_EOK; } } } } /* enable interrupt */ rt_hw_interrupt_enable(temp); return RT_EOK;}rt_err_t rt_mutex_release(rt_mutex_t mutex){ register rt_base_t temp; struct rt_thread* thread; /* disable interrupt */ temp = rt_hw_interrupt_disable();#ifdef IPC_DEBUG rt_kprintf("mutex_release:mutex value: %d, hold: %d\n", mutex->value, mutex->hold);#endif /* get current thread */ thread = rt_thread_self(); /* mutex is only released by owner */ if (thread != mutex->owner) { thread->error = -RT_ERROR; /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_ERROR; } /* decrease hold */ mutex->hold --; /* if no hold */ if (mutex->hold == 0) { /* change the owner thread to original priority */ if (mutex->owner->init_priority != mutex->owner->current_priority) { rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &(mutex->owner->init_priority)); } /* wakeup suspended thread */ if (mutex->value <= 0 && mutex->parent.suspend_thread_count > 0) {#ifdef IPC_DEBUG rt_kprintf("mutex release: resume thread: %s\n", thread->name);#endif /* resume thread */ rt_ipc_object_resume(&(mutex->parent)); } /* increase value */ mutex->value ++; } /* enable interrupt */ rt_hw_interrupt_enable(temp); rt_schedule(); return RT_EOK;}rt_err_t rt_mutex_control(rt_mutex_t mutex, rt_uint8 cmd, void* arg){ return RT_EOK;}#endif /* end of RT_USING_MUTEX */#ifdef RT_USING_FASTEVENTrt_err_t rt_fast_event_init(rt_fast_event_t event, const char* name, rt_uint8 flag){ register rt_base_t offset; RT_ASSERT(event != RT_NULL); /* init object */ rt_object_init(&(event->parent), RT_Object_Class_FastEvent, name); /* set parent */ event->parent.flag = flag; /* clear event set */ event->set = 0x00; /* init thread list */ for (offset = 0; offset < 32; offset ++) { rt_list_init(&(event->thread_list[offset])); } return RT_EOK;}rt_err_t rt_fast_event_detach(rt_fast_event_t event){ register rt_base_t bit; struct rt_thread* thread; register rt_ubase_t level; RT_ASSERT(event != RT_NULL); for (bit = 0; bit < RT_EVENT_LENGTH; bit ++) { /* resume all suspend thread */ if (!rt_list_isempty(&(event->thread_list[bit]))) { /* wakeup all suspend threads */ while (!rt_list_isempty(&(event->thread_list[bit]))) { /* disable interrupt */ level = rt_hw_interrupt_disable(); /* get next suspend thread */ thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist); /* set error code to RT_ERROR */ thread->error = -RT_ERROR; /* resume thread */ rt_thread_resume(thread); /* enable interrupt */ rt_hw_interrupt_enable(level); } } } /* detach event object */ rt_object_detach(&(event->parent)); return RT_EOK;}rt_fast_event_t rt_fast_event_create (const char* name, rt_uint8 flag){ rt_fast_event_t event; register rt_base_t offset; /* allocate object */ event = (rt_fast_event_t) rt_object_allocate(RT_Object_Class_FastEvent, name); if (event == RT_NULL) return event; /* set parent */ event->parent.flag = flag; /* clear event set */ event->set = 0x00; /* init thread list */ for (offset = 0; offset < 32; offset ++) { rt_list_init(&(event->thread_list[offset])); } return event;}rt_err_t rt_fast_event_delete (rt_fast_event_t event){ register rt_base_t bit; struct rt_thread* thread; register rt_ubase_t level; RT_ASSERT(event != RT_NULL); for (bit = 0; bit < RT_EVENT_LENGTH; bit ++) { /* resume all suspend thread */ if (!rt_list_isempty(&(event->thread_list[bit]))) { /* wakeup all suspend threads */ while (!rt_list_isempty(&(event->thread_list[bit]))) { /* disable interrupt */ level = rt_hw_interrupt_disable(); /* get next suspend thread */ thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist); /* set error code to RT_ERROR */ thread->error = -RT_ERROR; /* resume thread */ rt_thread_resume(thread); /* enable interrupt */ rt_hw_interrupt_enable(level); } } } /* detach semaphore object */ rt_object_delete(&(event->parent)); return RT_EOK;}rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8 bit){ rt_uint32 offset; register rt_ubase_t level; struct rt_thread *thread; struct rt_list_node *n; /* parameter check */ RT_ASSERT(event != RT_NULL); RT_ASSERT(bit < RT_EVENT_LENGTH); offset = 1 << bit; /* disable interrupt */ level = rt_hw_interrupt_disable(); event->set |= offset; /* if thread list at offset is not empty */ n = event->thread_list[bit].next; while (n != &(event->thread_list[bit])) { /* get thread */ thread = rt_list_entry(n, struct rt_thread, tlist); /* move to next node */ n = n->next; /* clear bit or not */ if (thread->event_info & RT_EVENT_FLAG_CLEAR) event->set &= ~offset; /* resume thread */ rt_thread_resume(thread); } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do a schedule */ rt_schedule(); return RT_EOK;}rt_err_t rt_fast_event_recv(rt_fast_event_t event, rt_uint8 bit, rt_uint8 option, rt_int32 timeout){ rt_base_t offset; struct rt_thread* thread; register rt_ubase_t level; /* parameter check */ RT_ASSERT(event != RT_NULL); RT_ASSERT(bit < RT_EVENT_LENGTH); offset = 1 << bit; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* get current thread */ thread = rt_thread_self(); thread->error = RT_EOK; /* get event successfully */ if (event->set & offset) { if (option & RT_EVENT_FLAG_CLEAR) event->set &= ~ offset; /* enable interrupt */ rt_hw_interrupt_enable(level); return RT_EOK; } /* no event happen */ /* check waiting time */ if (timeout == 0) { /* no waiting */ thread->error = -RT_ETIMEOUT; } else { /* there are no event, suspend thread */ rt_thread_suspend(thread); /* set event info in thread */ thread->event_info = option; switch (event->parent.flag) { case RT_IPC_FLAG_FIFO: rt_list_insert_after(&(event->thread_list[bit]), &(thread->tlist)); break; case RT_IPC_FLAG_PRIO: { struct rt_list_node* n; struct rt_thread* sthread; /* find a suitable position */ for (n = event->thread_list[bit].next; n != &(event->thread_list[bit]); n = n->next) { sthread = rt_list_entry(n, struct rt_thread, tlist); /* find out */ if (thread->current_priority < sthread->current_priority) break; } /* insert thread */ rt_list_insert_before(&(event->thread_list[bit]), &(thread->tlist)); } break; } /* if there is timeout, active thread timer */ if (timeout > 0) { /* 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(level); /* do a schedule */ rt_schedule(); return thread->error;}rt_err_t rt_fast_event_control (rt_fast_event_t event, rt_uint8 cmd, void* arg){ return RT_EOK;}#endif#ifdef RT_USING_EVENTrt_err_t rt_event_init(rt_event_t event, const char* name, rt_uint8 flag){ RT_ASSERT(event != RT_NULL); /* init object */ rt_object_init(&(event->parent.parent), RT_Object_Class_Event, name); /* set parent flag */ event->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(event->parent)); /* init event */ event->set = 0; return RT_EOK;}rt_err_t rt_event_detach(rt_event_t event){ /* parameter check */ RT_ASSERT(event != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all(&(event->parent)); /* detach mailbox object */ rt_object_detach(&(event->parent.parent)); return RT_EOK;}rt_event_t rt_event_create (const char* name, rt_uint8 flag){ rt_event_t event; /* allocate object */ event = (rt_event_t) rt_object_allocate(RT_Object_Class_Event, name); if (event == RT_NULL) return event; /* set parent */ event->parent.parent.flag = flag; /* init ipc object */ rt_ipc_object_init(&(event->parent)); /* init event */ event->set = 0; return event;}rt_err_t rt_event_delete (rt_event_t event){ /* parameter check */ RT_ASSERT(event != RT_NULL); /* resume all suspended thread */ rt_ipc_object_resume_all(&(event->parent)); /* delete event object */ rt_object_delete(&(event->parent.parent)); return RT_EOK;}rt_err_t rt_event_send(rt_event_t event, rt_uint32 set){ struct rt_list_node *n; struct rt_thread *thread; register rt_ubase_t level; register rt_base_t status; /* parameter check */ RT_ASSERT(event != RT_NULL); if (set == 0) return -RT_ERROR; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* set event */ event->set |= set; if (event->parent.suspend_thread_count > 0) { /* search thread list to resume thread */ n = event->parent.suspend_thread.next; while (n != &(event->parent.suspend_thread)) { /* get thread */ thread = rt_list_entry(n, struct rt_thread, tlist); status = -RT_ERROR; if (thread->event_info & RT_EVENT_FLAG_AND) { if ((thread->event_set & event->set) == thread->event_set) { status = RT_EOK; } } else if (thread->event_info & RT_EVENT_FLAG_OR) { if (thread->event_set & event->set) { status = RT_EOK; } } /* move node to the nexe */ n = n->next; /* condition is satisfied, resume thread */ if (status == RT_EOK) { /* resume thread, and thread list breaks out */ rt_thread_resume(thread); /* decrease suspended thread count */ event->parent.suspend_thread_count--; if (thread->event_info & RT_EVENT_FLAG_CLEAR) event->set &= ~thread->event_set; } } } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do a schedule */ rt_schedule(); return RT_EOK;}rt_err_t rt_event_recv(rt_event_t event, rt_uint32 set, rt_uint8 option, rt_int32 timeout, rt_uint32* recved){ struct rt_thread *thread; register rt_ubase_t level; register rt_base_t status; /* parameter check */ RT_ASSERT(event != RT_NULL); if (set == 0) return -RT_ERROR; /* init status */ status = -RT_ERROR; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* check event set */ if (option & RT_EVENT_FLAG_AND) { if ((event->set & set) == set) status = RT_EOK; } else if (option & RT_EVENT_FLAG_OR) { if (event->set & set) status = RT_EOK; } /* get current thread */ thread = rt_thread_self(); /* reset thread error */ thread->error = RT_EOK; if (status == RT_EOK) { /* set received event */ *recved = event->set; /* received event */ if (option & RT_EVENT_FLAG_CLEAR) event->set &= ~set; } else if (timeout == 0) { /* no waiting */ thread->error = -RT_ETIMEOUT; } else { /* fill thread event info */ thread->event_set = set; thread->event_info = option; /* put thread to suspended thread list */ rt_ipc_object_suspend(&(event->parent), thread); /* if there is a waiting timeout, active thread timer */ if (timeout > 0) { /* 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(level); /* do a schedule */ rt_schedule(); if (thread->error != RT_EOK) return thread->error; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* get received event */ *recved = event->set; } /* enable interrupt */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -