菜单

Cobalt/Event flag group services

Inter-task notification mechanism based on discrete flags.


详细描述

基于离散标志的任务间通知机制。

事件标志组是一个由长字结构表示的同步对象;这个字中的每一个可用位都代表一个用户定义的事件标志。

当一个位被设置时,表示相关联的事件已经发生。xkernel任务可以使用这种机制向其他任务标志特定事件的发生。

任务可以以合取方式(所有等待的事件都必须发生才能满足等待请求)或析取方式(至少有一个等待的事件发生才能满足等待请求)等待事件的发生。


函数文档

rt_event_bind

int rt_event_bind (RT_EVENT *event, const char *name, RTIME timeout);

绑定到一个事件标志组。

此例程创建一个新的描述符来引用由其符号名称标识的现有事件标志组。如果对象在进入时不存在,调用者可能会阻塞,直到创建具有给定名称的事件标志组。

参数

  • event 由操作填充的事件标志组描述符的地址。失败时,此内存的内容未定义。
  • name 一个有效的以NULL结尾的名称,用于标识要绑定的事件标志组。此字符串应与传递给 rt_event_create() 的对象名称参数匹配。
  • timeout 等待注册发生的时钟滴答数(见注释)。传递 TM_INFINITE 会导致调用者无限期阻塞,直到对象被注册。传递 TM_NONBLOCK 会导致服务在对象在进入时未注册的情况下立即返回,而不等待。

返回值

成功时返回零。否则:

  • 如果在检索完成之前为当前任务调用了 rt_task_unblock(),则返回 -EINTR。
  • 如果 timeout 等于 TM_NONBLOCK 并且在进入时未注册搜索的对象,则返回 -EWOULDBLOCK。
  • 如果无法在指定的时间内检索到对象,则返回 -ETIMEDOUT。
  • 如果此服务应阻塞,但未从 xkernel 线程调用,则返回 -EPERM。

标签

xthread-nowait, switch-primary

注意

超时值被解释为 Alchemy 时钟分辨率的倍数(参见 alchemy-clock-resolution 选项,默认为1纳秒)。

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    RT_EVENT event_signal;

    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒

    
    ret = rt_event_bind(&event_signal, "MyEvent",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to bind event: %s\n", strerror(-ret));
        return;
    }

    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }

    rt_event_unbind(&event_signal);
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_create

int rt_event_create (RT_EVENT *event, const char *name, unsigned long ivalue, int mode);

创建一个事件标志组。

事件组通过允许一组标志(或"事件")被原子性地等待和发布,为任务同步提供了支持。一个事件组包含了已接收事件的掩码;在单个操作中,可以挂起或发布任意集合的事件标志。

参数

  • event 一个事件描述符的地址,此调用成功后,可以用来唯一地标识创建的对象。
  • name 一个代表事件符号名称的ASCII字符串。当非NULL且非空时,此字符串的副本用于将创建的事件索引到对象注册表中。
  • ivalue 组的事件掩码的初始值。
  • mode 事件组创建模式。以下标志可以被OR到此位掩码中:

EV_FIFO 使任务按FIFO顺序在事件标志组上挂起。
EV_PRIO 使任务按优先级顺序在事件标志组上挂起。

返回值

成功时返回零。否则:

  • 如果 mode 无效,则返回 -EINVAL。
  • 如果系统无法从主堆获取内存以创建事件标志组,则返回 -ENOMEM。
  • 如果名称与已注册的事件标志组冲突,则返回 -EEXIST。
  • 如果此服务是从无效的上下文调用的,例如中断或非xkernel线程,则返回 -EPERM。

标签

xthread-only, mode-unrestricted, switch-secondary

注意

事件标志组可以由属于同一xkernel会话的多个进程共享。

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_delete

int rt_event_delete (RT_EVENT *event);

删除一个事件标志组。

此例程删除由 rt_event_create() 调用先前创建的事件标志组。

参数

  • event 事件描述符。

返回值

成功时返回零。否则:

  • 如果 event 不是有效的事件标志组描述符,则返回 -EINVAL。
  • 如果此服务是从异步上下文调用的,则返回 -EPERM。

标签

mode-unrestricted, switch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_inquire

int rt_event_inquire (RT_EVENT *event, RT_EVENT_INFO *info);

查询事件标志组状态。

此例程返回关于事件的状态信息。

参数

  • event 事件描述符。
  • info 一个指向返回缓冲区的指针,用于复制信息。

返回值

成功时返回零,并将状态信息写入由 info 指向的结构。否则:

  • 如果 event 不是有效的事件标志组描述符,则返回 -EINVAL。

标签

mode-unrestricted, switch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    RT_EVENT event_signal;
    RT_EVENT_INFO info_signal;

    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒

    
    ret = rt_event_bind(&event_signal, "MyEvent",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to bind event: %s\n", strerror(-ret));
        return;
    }

    ret = rt_event_inquire(&event_signal,&info_signal);
    if (ret) {
        fprintf(stderr, "Failed to get event info: %s\n", strerror(-ret));
        return;
    }
    printf("Event Info:\n");
    printf("    Name %s\n",info_signal.value,info_signal.nwaiters,info_signal.name);

    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }

    rt_event_unbind(&event_signal);
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_signal

int rt_event_signal (RT_EVENT *event, unsigned int mask);

发出一个事件信号。

向事件标志组发布一组标志。所有因此操作而满足其等待请求的任务都会立即准备就绪。

参数

  • event 事件描述符。
  • mask 要发布的事件集。

返回值

成功时返回零。否则:

  • 如果 event 不是事件标志组描述符,则返回 -EINVAL。

标签

unrestricted, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_unbind

int rt_event_unbind (RT_EVENT *event);

解除与事件标志组的绑定。

此例程释放先前与事件标志组的绑定。此调用返回后,描述符不再适用于引用此对象。

参数

  • event 事件描述符。

标签

thread-unrestricted

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    RT_EVENT event_signal;

    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒

    
    ret = rt_event_bind(&event_signal, "MyEvent",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to bind event: %s\n", strerror(-ret));
        return;
    }

    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }

    rt_event_unbind(&event_signal);
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_wait

int rt_event_wait (RT_EVENT *event, unsigned int mask, unsigned int *mask_r, int mode, RTIME timeout);

等待任意集合的事件(具有相对标量超时)。

此例程是 rt_event_wait_timed() 的一个变体,接受以标量值表示的相对超时规范。

参数

  • event 事件描述符。
  • mask 等待的位集。
  • mask_r 任务准备就绪时的事件掩码值。
  • mode 挂起模式。
  • timeout 以时钟滴答表示的延迟。传递 TM_INFINITE 会导致调用者无限期阻塞,直到满足请求。传递 TM_NONBLOCK 会导致服务在无法立即满足请求的情况下立即返回,而不会阻塞。

标签

xthread-nowait, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 1 seconds before sending signal\n");
    rt_task_sleep(1000000000);  // 休眠1秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask;
    
    printf("Wait Task: Waiting for event\n");
    ret = rt_event_wait(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
    } else {
        printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_wait_timed

int rt_event_wait_timed (RT_EVENT *event, unsigned int mask, unsigned int *mask_r, int mode, const struct timespec *abs_timeout);

等待任意集合的事件。

等待在事件中发出一个或多个事件,或者直到超时。

参数

  • event 事件描述符。
  • mask 等待的位集。传递零会使此服务立即返回成功值;事件掩码的当前值也复制到 mask_r。
  • mask_r 任务准备就绪时的事件掩码值。
  • mode 挂起模式。以下标志可以被 OR 到此位掩码中,每个都会影响操作:
    • EV_ANY 使任务在析取模式下挂起(即 OR);这意味着当在当前事件掩码中设置了至少一个位到 mask 时,请求就会被满足。
    • EV_ALL 使任务在合取模式下挂起(即 AND);这意味着当在当前事件掩码中设置了所有位到 mask 时,请求就会被满足。
  • abs_timeout 一个以秒/纳秒表示的绝对日期,基于 Alchemy 时钟,指定等待请求满足的时间限制。传递 NULL 会导致调用者无限期阻塞,直到满足请求。传递 { .tv_sec = 0, .tv_nsec = 0 } 会导致服务在无法立即满足请求的情况下立即返回,而不会阻塞。

返回值

成功时返回零。否则:

  • 如果在满足请求之前达到 abs_timeout,则返回 -ETIMEDOUT。
  • 如果 abs_timeout 是 { .tv_sec = 0, .tv_nsec = 0 } 并且在进入调用时未设置请求的标志,则返回 -EWOULDBLOCK。
  • 如果在满足请求之前为当前任务调用了 rt_task_unblock(),则返回 -EINTR。
  • 如果 mode 无效,或者 event 不是有效的事件标志组描述符,则返回 -EINVAL。
  • 如果在调用者睡眠时删除了事件,则返回 -EIDRM。在这种情况下,此服务返回时,事件不再有效。
  • 如果此服务应阻塞,但未从 xkernel 线程调用,则返回 -EPERM。

标签

xthread-nowait, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 3 seconds before sending signal\n");
    rt_task_sleep(3000000000);  // 休眠 3 秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask = 0;

    while(!received_mask){
        printf("Wait Task: Waiting for event\n");

        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        ts.tv_sec += 2; // 超时时间2秒

        ret = rt_event_wait_timed(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, &ts);
        if (ret == -ETIMEDOUT) {
            printf("Wait Task: Event Timeout\n");
        }
        else if (ret) {
            fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
        } else {
            printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
        }
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

rt_event_wait_until

int rt_event_wait_until (RT_EVENT *event, unsigned int mask, unsigned int *mask_r, int mode, RTIME timeout);

等待任意一组事件(带绝对标量超时)。

此例程是 rt_event_wait_timed() 的变体,接受以标量值表示的绝对超时规范。

参数

  • event: 事件描述符。
  • mask: 要等待的位集合。
  • mask_r: 任务准备就绪时事件掩码的值。
  • mode: 挂起模式。
  • abs_timeout: 以时钟周期表示的绝对时间。传递 TM_INFINITE 会导致调用者无限期阻塞,直到请求得到满足。传递 TM_NONBLOCK 会在请求无法立即满足的情况下返回而不阻塞。

标签

xthread-nowait, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/event.h>

#define TASK_PRIO 20
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0

#define EVENT_FLAG 0x99  // 定义使用的事件标志

RT_EVENT event_desc;

void signal_task(void *arg)
{
    int ret;
    
    printf("Signal Task: Sleeping for 3 seconds before sending signal\n");
    rt_task_sleep(3000000000);  // 休眠 3 秒
    
    printf("Signal Task: Sending signal\n");
    ret = rt_event_signal(&event_desc, EVENT_FLAG);
    if (ret) {
        fprintf(stderr, "Signal Task: Failed to signal event, code %d\n", ret);
    } else {
        printf("Signal Task: Event signaled successfully\n");
    }
}

void wait_task(void *arg)
{
    int ret;
    unsigned int received_mask = 0;

    while(!received_mask){
        printf("Wait Task: Waiting for event\n");

        RTIME timeout = rt_timer_read() + 2000000000; // 超时时间2秒

        ret = rt_event_wait_until(&event_desc, EVENT_FLAG, &received_mask, EV_ANY, timeout);
        if (ret == -ETIMEDOUT) {
            printf("Wait Task: Event Timeout\n");
        }
        else if (ret) {
            fprintf(stderr, "Wait Task: Failed to wait for event, code %d\n", ret);
        } else {
            printf("Wait Task: Event received, mask: 0x%x\n", received_mask);
        }
    }
}

int main(int argc, char *argv[])
{
    RT_TASK signal_task_desc, wait_task_desc;
    int ret;

    // 创建事件标志组
    ret = rt_event_create(&event_desc, "MyEvent", 0, EV_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create event flag group, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建等待任务
    ret = rt_task_create(&wait_task_desc, "WaitTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create wait task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 创建信号任务
    ret = rt_task_create(&signal_task_desc, "SignalTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (ret) {
        fprintf(stderr, "Failed to create signal task, code %d\n", ret);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&wait_task_desc, &wait_task, NULL);
    rt_task_start(&signal_task_desc, &signal_task, NULL);

    // 等待任务结束并清理
    rt_task_join(&wait_task_desc);
    rt_task_join(&signal_task_desc);
    rt_event_delete(&event_desc);
    return EXIT_SUCCESS;
}

最近修改: 2025-09-30