代码拉取完成,页面将自动刷新
#include <rtthread.h>
#include <rthw.h>
rt_inline rt_err_t rt_ipc_object_init(struct rt_ipc_object *ipc)
{
rt_list_init(&(ipc->suspend_thread));
return RT_EOK;
}
rt_inline rt_err_t rt_ipc_list_suspend(rt_list_t *list, struct rt_thread *thread, rt_uint8_t flag){
struct rt_list_node *n;
struct rt_thread *sthread;
rt_thread_suspend(thread);
switch (flag){
case RT_IPC_FLAG_FIFO:
rt_list_insert_before(list, &(thread->tlist));
break;
case RT_IPC_FLAG_PRIO:
for(n = list->next; n != list; n = n->next){
sthread = rt_list_entry(n, struct rt_thread, tlist);
if(thread->current_priority < sthread->current_priority){
rt_list_insert_before(&(sthread->tlist), &(thread->tlist));
break;
}
}
if(n == list)
rt_list_insert_before(list, &(thread->tlist));
break;
}
return RT_EOK;
}
rt_inline rt_err_t rt_ipc_list_resume(rt_list_t *list){
struct rt_thread *thread;
thread = rt_list_entry(list->next, struct rt_thread, tlist);
rt_thread_resume(thread);
return RT_EOK;
}
rt_inline rt_err_t rt_ipc_list_resume_all(rt_list_t *list)
{
struct rt_thread *thread;
register rt_ubase_t temp;
while(!rt_list_isempty(list)){
temp = rt_hw_interrupt_disable();
thread = rt_list_entry(list->next, struct rt_thread, tlist);
rt_thread_resume(thread);
rt_hw_interrupt_enable(temp);
}
return RT_EOK;
}
rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag)
{
rt_object_init(&(sem->parent.parent), RT_Object_Class_Semaphore, name);
rt_ipc_object_init(&(sem->parent));
sem->value = (rt_uint16_t)value;
sem->parent.parent.flag = flag;
return RT_EOK;
}
rt_err_t rt_sem_detach(rt_sem_t sem)
{
rt_ipc_list_resume_all(&(sem->parent.suspend_thread));
rt_object_detach(&(sem->parent.parent));
return RT_EOK;
}
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag){
rt_sem_t sem;
sem = (rt_sem_t)rt_object_allocate(RT_Object_Class_Semaphore, name);
if(sem == RT_NULL){
return RT_NULL;
}
rt_ipc_object_init(&sem->parent);
sem->value = (rt_uint16_t)value;
sem->parent.parent.flag = flag;
return sem;
}
rt_err_t rt_sem_delete(rt_sem_t sem){
RT_ASSERT(sem != RT_NULL);
rt_ipc_list_resume_all(&(sem->parent.suspend_thread));
rt_object_delete((rt_object_t)sem);
return RT_EOK;
}
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time){
struct rt_thread *thread;
register rt_ubase_t temp;
RT_ASSERT(sem != RT_NULL);
RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore);
temp = rt_hw_interrupt_disable();
if(sem->value > 0){
sem->value--;
rt_hw_interrupt_enable(temp);
}else{
if(time == 0){
rt_hw_interrupt_enable(temp);
return -RT_ETIMEOUT;
}else{
thread = rt_thread_self();
thread->error = RT_EOK;
rt_ipc_list_suspend(&(sem->parent.suspend_thread), thread, sem->parent.parent.flag);
if(time > 0){
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
rt_timer_start(&(thread->thread_timer));
}
rt_hw_interrupt_enable(temp);
rt_schedule();
/* 当线程恢复后,thread->error 不等于 RT_EOK 说明出错或超时 */
if(thread->error != RT_EOK){
return thread->error;
}
}
}
return RT_EOK;
}
rt_err_t rt_sem_trytake(rt_sem_t sem){
return rt_sem_take(sem, 0);
}
rt_err_t rt_sem_release(rt_sem_t sem){
rt_ubase_t temp;
rt_bool_t need_schedule;
RT_ASSERT(sem != RT_NULL);
need_schedule = RT_FALSE;
temp = rt_hw_interrupt_disable();
if(!rt_list_isempty(&(sem->parent.suspend_thread))){ // 判断是否有挂起线程
rt_ipc_list_resume(&(sem->parent.suspend_thread)); // 有,则唤起一个
need_schedule = RT_TRUE;
}else{
sem->value++;
}
rt_hw_interrupt_enable(temp);
if(need_schedule)
rt_schedule();
return RT_EOK;
}
rt_err_t rt_sem_contrl(rt_sem_t sem, int cmd, void *arg){
rt_ubase_t tmp;
RT_ASSERT(sem != RT_NULL);
if(cmd == RT_IPC_CMD_RESET){
tmp = rt_hw_interrupt_disable();
rt_ipc_list_resume_all(&(sem->parent.suspend_thread));
sem->value = (rt_uint16_t)arg;
rt_hw_interrupt_enable(tmp);
rt_schedule();
return RT_EOK;
}
return -RT_ERROR;
}
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag){
RT_ASSERT(mutex != RT_NULL);
rt_object_init(&mutex->parent.parent, RT_Object_Class_Mutex, name);
rt_ipc_object_init(&mutex->parent);
mutex->parent.parent.flag = flag;
mutex->value = 1;
mutex->original_priority = RT_THREAD_PRIORITY_MAX - 1;
mutex->hold = 0;
mutex->owner = RT_NULL;
return RT_EOK;
}
rt_err_t rt_mutex_detach(rt_mutex_t mutex){
rt_thread_t thread;
rt_ubase_t tmp;
RT_ASSERT(mutex != RT_NULL);
rt_ipc_list_resume_all(&mutex->parent.suspend_thread);
rt_object_detach((rt_object_t)mutex);
return RT_EOK;
}
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag){
rt_mutex_t mutex;
RT_ASSERT(mutex != RT_NULL);
mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);
if(mutex == RT_NULL){
return mutex;
}
rt_ipc_object_init(&mutex->parent);
mutex->parent.parent.flag = flag;
mutex->value = 1;
mutex->original_priority = RT_THREAD_PRIORITY_MAX - 1;
mutex->hold = 0;
mutex->owner = RT_NULL;
return mutex;
}
rt_err_t rt_mutex_delete(rt_mutex_t mutex){
RT_ASSERT(mutex != RT_NULL);
rt_ipc_list_resume_all(&mutex->parent.suspend_thread);
rt_object_delete((rt_object_t)mutex);
return RT_EOK;
}
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time){
rt_thread_t thread;
rt_base_t tmp;
RT_ASSERT(mutex != RT_NULL);
thread = rt_thread_self();
tmp = rt_hw_interrupt_disable();
thread->error = RT_EOK;
if(mutex->owner == thread){
mutex->hold++;
}else{
if(mutex->value > 0){
mutex->value--;
mutex->owner = thread;
mutex->original_priority = thread->current_priority;
mutex->hold++;
}else{
if(time == 0){
thread->error = -RT_ETIMEOUT;
rt_hw_interrupt_enable(tmp);
return -RT_ETIMEOUT;
}
if(mutex->original_priority > thread->current_priority){
rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &thread->current_priority);
}
rt_ipc_list_suspend(&mutex->parent.suspend_thread, thread, mutex->parent.parent.flag);
if(time > 0){
rt_timer_control(&thread->thread_timer, RT_TIMER_CTRL_SET_TIME, &time);
rt_timer_start(&thread->thread_timer);
}
rt_hw_interrupt_enable(tmp);
rt_schedule();
if(thread->error != RT_EOK){
return thread->error;
}
tmp = rt_hw_interrupt_disable();
}
}
rt_hw_interrupt_enable(tmp);
return RT_EOK;
}
rt_err_t rt_mutex_release(rt_mutex_t mutex){
rt_thread_t thread;
rt_base_t tmp;
rt_bool_t need_schedule = RT_FALSE;
RT_ASSERT(mutex != RT_NULL);
thread = rt_thread_self();
tmp = rt_hw_interrupt_disable();
if(mutex->owner != thread){
thread->error = -RT_ERROR;
rt_hw_interrupt_enable(tmp);
return -RT_ERROR;
}
mutex->hold--;
if(mutex->hold == 0){
if(mutex->original_priority != mutex->owner->current_priority){
rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &(mutex->original_priority));
}
if(!rt_list_isempty(&mutex->parent.suspend_thread)){
thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist);
mutex->owner = thread;
mutex->original_priority = thread->current_priority;
mutex->hold++;
rt_ipc_list_resume(&mutex->parent.suspend_thread);
need_schedule = RT_TRUE;
}else{
mutex->value++;
mutex->owner = RT_NULL;
mutex->original_priority = RT_THREAD_PRIORITY_MAX - 1;
}
}
rt_hw_interrupt_enable(tmp);
if(need_schedule){
rt_schedule();
}
return RT_EOK;
}
rt_err_t rt_mutex_control(rt_mutex_t mutex, int cmd, void *arg){
RT_ASSERT(mutex != RT_NULL);
return -RT_ERROR;
}
rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag){
RT_ASSERT(event != RT_NULL);
rt_object_init(&event->parent.parent, RT_Object_Class_Event, name);
rt_ipc_object_init(&event->parent);
event->parent.parent.flag = flag;
event->set = 0;
return RT_EOK;
}
rt_err_t rt_event_detach(rt_event_t event){
RT_ASSERT(event != RT_NULL);
rt_ipc_list_resume_all(&event->parent.suspend_thread);
rt_object_detach(&event->parent.parent);
event->set = 0;
return RT_EOK;
}
rt_event_t rt_event_create(const char *name, rt_uint8_t flag){
rt_event_t event;
event = (rt_event_t)rt_object_allocate(RT_Object_Class_Event, name);
if(event == RT_NULL){
return event;
}
rt_ipc_object_init(&(event->parent));
event->parent.parent.flag = flag;
event->set = 0;
return event;
}
rt_err_t rt_event_delete(rt_event_t event){
RT_ASSERT(event != RT_NULL);
rt_ipc_list_resume_all(&event->parent.suspend_thread);
rt_object_delete(&event->parent.parent);
return RT_EOK;
}
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set){
rt_ubase_t tmp;
rt_thread_t thread;
struct rt_list_node *n;
rt_base_t status;
rt_bool_t need_schedule = RT_FALSE;
RT_ASSERT(event != RT_NULL);
if(set == 0){
return -RT_ERROR;
}
tmp = rt_hw_interrupt_disable();
event->set |= set;
if(!rt_list_isempty(&event->parent.suspend_thread)){
n = event->parent.suspend_thread.next;
while(n != &event->parent.suspend_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){
thread->event_set = thread->event_set & event->set;
status = RT_EOK;
}
}
n = n->next;
if(status == RT_EOK){
if(thread->event_info & RT_EVENT_FLAG_CLEAR){
event->set &= ~thread->event_set;
}
rt_thread_resume(thread); // 如果 n=n->next 放在后面,就改变了链表指向。
need_schedule = RT_TRUE;
}
}
}
rt_hw_interrupt_enable(tmp);
if(need_schedule == RT_TRUE){
rt_schedule();
}
return RT_EOK;
}
rt_err_t rt_event_recv(rt_event_t event, rt_uint32_t set, rt_uint8_t option,
rt_int32_t timeout, rt_uint32_t *recved){
rt_ubase_t tmp;
rt_thread_t thread;
rt_base_t status = -RT_ERROR;
RT_ASSERT(event != RT_NULL);
if (set == 0)
return -RT_ERROR;
thread = rt_thread_self();
thread->error = RT_EOK;
tmp = rt_hw_interrupt_disable();
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;
}
}
if(status == RT_EOK){
if(recved)
*recved = (event->set & set);
if(option & RT_EVENT_FLAG_CLEAR){
event->set &= ~set;
}
}else if(timeout == 0){
thread->error = -RT_ETIMEOUT;
}else{
thread->event_info = option;
thread->event_set = set;
rt_ipc_list_suspend(&event->parent.suspend_thread, thread, event->parent.parent.flag);
if(timeout > 0){
rt_timer_control(&thread->thread_timer, RT_TIMER_CTRL_SET_TIME, &timeout);
rt_timer_start(&thread->thread_timer);
}
rt_hw_interrupt_enable(tmp);
rt_schedule();
if(thread->error != RT_EOK){
return thread->error;
}
tmp = rt_hw_interrupt_disable();
if(recved)
*recved = thread->event_set;
}
rt_hw_interrupt_enable(tmp);
return thread->error;
}
rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg){
rt_ubase_t level;
RT_ASSERT(event != RT_NULL);
if (cmd == RT_IPC_CMD_RESET){
level = rt_hw_interrupt_disable();
rt_ipc_list_resume_all(&event->parent.suspend_thread);
event->set = 0;
rt_hw_interrupt_enable(level);
rt_schedule();
return RT_EOK;
}
return -RT_ERROR;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。