前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zephyr笔记 2.4.3 Alerts

zephyr笔记 2.4.3 Alerts

作者头像
twowinter
发布2020-04-17 11:19:12
5730
发布2020-04-17 11:19:12
举报
文章被收录于专栏:twowintertwowinter

1 前言

alert是一个内核对象,允许应用程序在关注的条件发生时执行异步信号传输。

我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总

2 概念

可以定义任意数量的 alert。 每个 alert 都由其内存地址引用。

alert 具有以下关键属性:

  • alert处理程序,用于指定在发出警报时要执行的操作。 该操作可以指示系统工作队列执行处理警报的函数,将警报标记为挂起,以便稍后可以由线程处理,或忽略警报。
  • 挂起计数,记录尚未收到的挂起 alert 的数量。
  • 计数限制,指定要记录的 挂起 alert 的最大数量。

alert 必须初始化才能使用。 这将建立其警报处理程序并将挂起的计数设置为零。

2.1 alert 生命周期

当检测到无法处理感兴趣的条件时,ISR或线程通过发送 alert 来发出信号。

每次发送 alert 时,内核都会检查 alert 处理程序以确定要采取的操作。

  • K_ALERT_IGNORE 导致 alert 被忽略。
  • K_ALERT_DEFAULT 会导致挂起计数递增,除非这会超出计数限制。
  • 任何其他值都假定为 alert 处理函数的地址,并由系统工作队列线程调用。如果函数返回零,则认为信号已被消耗;否则挂起的计数会增加,除非这会超过计数限制。 内核确保每次发送 alert 时都会执行一次 alert 处理程序函数,即使快速连续发送多次 alert 也是如此。

线程通过接收 alert 接受 挂起 alert。这会减少挂起的计数。如果挂起计数为零,则线程将等待 alert 挂起。任何数量的线程可能会同时等待一个挂起的 alert;当 alert 被挂起时,它被等待时间最长的最高优先级线程所接受。

代码语言:javascript
复制
一个线程必须一次处理一个挂起alert。 该线程无法通过单个操作接收多个挂起alert。

2.2 与Unix风格的信号进行比较

Zephyr alert 有点类似于Unix风格的信号,但有很多显着差异。 其中最值得注意的是:

  • Zephyr alert 不能被阻止; 它总是立即交付给警报处理程序。
  • Zephyr alert 在它被传递到它的 alert 处理程序之后,并且只有在 alert 处理程序函数没有使用 alert 时才会停止。
  • Zephyr没有预定义的 alert 或操作。 所有 alert 都是应用程序定义的,并且都有一个默认操作来挂起 alert。

3 操作

3.1 定义 alert

alert 是使用 struct k_alert 类型的变量定义的。 它必须通过调用 k_alert_init() 来初始化。

以下代码定义并初始化一个 alert。 该警报允许多达10个未接收到的 alert 信号挂起,之后就开始忽略新的挂起 alert。

代码语言:javascript
复制
extern int my_alert_handler(struct k_alert *alert);

struct k_alert my_alert;

k_alert_init(&my_alert, my_alert_handler, 10);

或者,可以在编译时通过调用 K_ALERT_DEFINE 来定义和初始化 alert。

以下代码与上面的代码段具有相同的效果。

代码语言:javascript
复制
extern int my_alert_handler(struct k_alert *alert);

K_ALERT_DEFINE(my_alert, my_alert_handler, 10);

3.2 发出 alert

alert 通过调用 k_alert_send() 来发送。

以下代码说明了ISR如何发出 alert 来指示按键已经发生。

代码语言:javascript
复制
extern int my_alert_handler(struct k_alert *alert);

K_ALERT_DEFINE(my_alert, my_alert_handler, 10);

void keypress_interrupt_handler(void *arg)
{
    ...
    k_alert_send(&my_alert);
    ...
}

3.3 处理 alert

aert 处理函数用于不应忽视或立即挂起的信号alert。 它有以下形式:

代码语言:javascript
复制
int <function_name>(struct k_alert *alert)
{
    /* catch the alert signal; return zero if the signal is consumed, */
    /* or non-zero to let the alert pend                              */
    ...
}

以下代码说明了一个处理由ISR检测到的按键处理的 alert 处理函数(如前一部分所示)。

代码语言:javascript
复制
int my_alert_handler(struct k_alert *alert_id_is_unused)
{
    /* determine what key was pressed */
    char c = get_keypress();

    /* do complex processing of the keystroke */
    ...

    /* signaled alert has been consumed */
    return 0;
}

3.4 接受 alert

线程通过调用 k_alert_recv() 来接受挂起 alert。

以下代码是上一节中代码的替代方法。 它使用专用线程来执行非常复杂的按键处理,否则会独占系统工作队列。 alert 处理函数现在仅用于过滤不需要的按键警报,允许专用线程唤醒并仅在按下数字键时处理按键警报。

代码语言:javascript
复制
int my_alert_handler(struct k_alert *alert_id_is_unused)
{
    /* determine what key was pressed */
    char c = get_keypress();

    /* signal thread only if key pressed was a digit */
    if ((c >= '0') && (c <= '9')) {
        /* save key press information */
        ...
        /* signaled alert should be pended */
        return 1;
    } else {
        /* signaled alert has been consumed */
        return 0;
    }
}

void keypress_thread(void *unused1, void *unused2, void *unused3)
{
    /* consume numeric key presses */
    while (1) {

        /* wait for a key press alert to pend */
        k_alert_recv(&my_alert, K_FOREVER);

        /* process saved key press, which must be a digit */
        ...
    }
}

4 建议用法

通过将与中断相关的工作推迟到线程来减少中断被锁定的时间,使用 alert 来最小化ISR处理。

使用 alert 来允许内核的系统工作队列处理警报,而不是定义应用程序线程来处理 alert。

在让应用程序线程处理它之前,使用 alert 来允许内核的系统工作队列预处理警报。

5 配置选项

6 APIs

下列 alert API,都在 kernel.h 中提供了:

代码语言:javascript
复制
K_ALERT_DEFINE
k_alert_init()
k_alert_send()
k_alert_recv()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 概念
    • 2.1 alert 生命周期
      • 2.2 与Unix风格的信号进行比较
      • 3 操作
        • 3.1 定义 alert
          • 3.2 发出 alert
            • 3.3 处理 alert
              • 3.4 接受 alert
              • 4 建议用法
              • 5 配置选项
              • 6 APIs
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档