kernel: remove k_alert API
This API was used in only one place in non-test code. See whether we can remove it. Closes #12232 Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
b026a34026
commit
bfad9721d2
20 changed files with 2 additions and 1266 deletions
|
@ -109,16 +109,6 @@ with basic priority inheritance.
|
|||
.. doxygengroup:: mutex_apis
|
||||
:project: Zephyr
|
||||
|
||||
Alerts
|
||||
******
|
||||
|
||||
Alerts enable an application to perform asynchronous signaling,
|
||||
somewhat akin to Unix-style signals.
|
||||
(See :ref:`alerts_v2`.)
|
||||
|
||||
.. doxygengroup:: alert_apis
|
||||
:project: Zephyr
|
||||
|
||||
FIFOs
|
||||
*****
|
||||
|
||||
|
|
|
@ -166,12 +166,8 @@ processing to a thread.
|
|||
* An ISR can signal a helper thread to do interrupt-related processing
|
||||
using a kernel object, such as a fifo, lifo, or semaphore.
|
||||
|
||||
* An ISR can signal an alert which causes the system workqueue thread
|
||||
to execute an associated alert handler function.
|
||||
(See :ref:`alerts_v2`.)
|
||||
|
||||
* An ISR can instruct the system workqueue thread to execute a work item.
|
||||
(See TBD.)
|
||||
(See :ref:`workqueues_v2`.)
|
||||
|
||||
When an ISR offloads work to a thread, there is typically a single context
|
||||
switch to that thread when the ISR completes, allowing interrupt-related
|
||||
|
|
|
@ -1,240 +0,0 @@
|
|||
.. _alerts_v2:
|
||||
|
||||
Alerts
|
||||
######
|
||||
|
||||
An :dfn:`alert` is a kernel object that allows an application to perform
|
||||
asynchronous signaling when a condition of interest occurs.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
Concepts
|
||||
********
|
||||
|
||||
Any number of alerts can be defined. Each alert is referenced by
|
||||
its memory address.
|
||||
|
||||
An alert has the following key properties:
|
||||
|
||||
* An **alert handler**, which specifies the action to be taken
|
||||
when the alert is signaled. The action may instruct the system workqueue
|
||||
to execute a function to process the alert, mark the alert as pending
|
||||
so it can be processed later by a thread, or ignore the alert.
|
||||
|
||||
* An **pending count**, which records the number of pending alerts
|
||||
that have yet to be received.
|
||||
|
||||
* An **count limit**, which specifies the maximum number of pending alerts
|
||||
that will be recorded.
|
||||
|
||||
An alert must be initialized before it can be used. This establishes
|
||||
its alert handler and sets the pending count to zero.
|
||||
|
||||
Alert Lifecycle
|
||||
===============
|
||||
|
||||
An ISR or a thread signals an alert by **sending** the alert
|
||||
when a condition of interest occurs that cannot be handled by the detector.
|
||||
|
||||
Each time an alert is sent, the kernel examines its alert handler
|
||||
to determine what action to take.
|
||||
|
||||
* :c:macro:`K_ALERT_IGNORE` causes the alert to be ignored.
|
||||
|
||||
* :c:macro:`K_ALERT_DEFAULT` causes the pending count to be incremented,
|
||||
unless this would exceed the count limit.
|
||||
|
||||
* Any other value is assumed to be the address of an alert handler function,
|
||||
and is invoked by the system workqueue thread. If the function returns
|
||||
zero, the signal is deemed to have been consumed; otherwise the pending
|
||||
count is incremented, unless this would exceed the count limit.
|
||||
|
||||
The kernel ensures that the alert handler function is executed once
|
||||
for each time an alert is sent, even if the alert is sent multiple times
|
||||
in rapid succession.
|
||||
|
||||
A thread accepts a pending alert by **receiving** the alert.
|
||||
This decrements the pending count. If the pending count is currently zero,
|
||||
the thread may choose to wait for the alert to become pending.
|
||||
Any number of threads may wait for a pending alert simultaneously;
|
||||
when the alert is pended it is accepted by the highest priority thread
|
||||
that has waited longest.
|
||||
|
||||
.. note::
|
||||
A thread must processes pending alerts one at a time. The thread
|
||||
cannot receive multiple pending alerts in a single operation.
|
||||
|
||||
Comparison to Unix-style Signals
|
||||
================================
|
||||
|
||||
Zephyr alerts are somewhat akin to Unix-style signals, but have a number of
|
||||
significant differences. The most notable of these are:
|
||||
|
||||
* A Zephyr alert cannot be blocked; it is always delivered to its alert
|
||||
handler immediately.
|
||||
|
||||
* A Zephyr alert pends *after* it has been delivered to its alert handler,
|
||||
and only if an alert handler function does not consume the alert.
|
||||
|
||||
* Zephyr has no predefined alerts or actions. All alerts are application
|
||||
defined, and all have a default action that pends the alert.
|
||||
|
||||
Implementation
|
||||
**************
|
||||
|
||||
Defining an Alert
|
||||
=================
|
||||
|
||||
An alert is defined using a variable of type :c:type:`struct k_alert`.
|
||||
It must then be initialized by calling :cpp:func:`k_alert_init()`.
|
||||
|
||||
The following code defines and initializes an alert. The alert allows
|
||||
up to 10 unreceived alert signals to pend before it begins to ignore
|
||||
new pending alerts.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
extern int my_alert_handler(struct k_alert *alert);
|
||||
|
||||
struct k_alert my_alert;
|
||||
|
||||
k_alert_init(&my_alert, my_alert_handler, 10);
|
||||
|
||||
Alternatively, an alert can be defined and initialized at compile time
|
||||
by calling :c:macro:`K_ALERT_DEFINE`.
|
||||
|
||||
The following code has the same effect as the code segment above.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
extern int my_alert_handler(struct k_alert *alert);
|
||||
|
||||
K_ALERT_DEFINE(my_alert, my_alert_handler, 10);
|
||||
|
||||
Signaling an Alert
|
||||
==================
|
||||
|
||||
An alert is signaled by calling :cpp:func:`k_alert_send()`.
|
||||
|
||||
The following code illustrates how an ISR can signal an alert
|
||||
to indicate that a key press has occurred.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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);
|
||||
...
|
||||
}
|
||||
|
||||
Handling an Alert
|
||||
=================
|
||||
|
||||
An alert handler function is used when a signaled alert should not be ignored
|
||||
or immediately pended. It has the following form:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 */
|
||||
...
|
||||
}
|
||||
|
||||
The following code illustrates an alert handler function that processes
|
||||
key presses detected by an ISR (as shown in the previous section).
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Accepting an Alert
|
||||
==================
|
||||
|
||||
A pending alert is accepted by a thread by calling :cpp:func:`k_alert_recv()`.
|
||||
|
||||
The following code is an alternative to the code in the previous section.
|
||||
It uses a dedicated thread to do very complex processing
|
||||
of key presses that would otherwise monopolize the system workqueue.
|
||||
The alert handler function is now used only to filter out unwanted key press
|
||||
alerts, allowing the dedicated thread to wake up and process key press alerts
|
||||
only when a numeric key is pressed.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 */
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
Suggested Uses
|
||||
**************
|
||||
|
||||
Use an alert to minimize ISR processing by deferring interrupt-related
|
||||
work to a thread to reduce the amount of time interrupts are locked.
|
||||
|
||||
Use an alert to allow the kernel's system workqueue to handle an alert,
|
||||
rather than defining an application thread to handle it.
|
||||
|
||||
Use an alert to allow the kernel's system workqueue to preprocess an alert,
|
||||
prior to letting an application thread handle it.
|
||||
|
||||
Configuration Options
|
||||
*********************
|
||||
|
||||
Related configuration options:
|
||||
|
||||
* None.
|
||||
|
||||
APIs
|
||||
****
|
||||
|
||||
The following alert APIs are provided by :file:`kernel.h`:
|
||||
|
||||
* :c:macro:`K_ALERT_DEFINE`
|
||||
* :cpp:func:`k_alert_init()`
|
||||
* :cpp:func:`k_alert_send()`
|
||||
* :cpp:func:`k_alert_recv()`
|
|
@ -11,4 +11,3 @@ of different threads, or the operation of an ISR and a thread.
|
|||
|
||||
semaphores.rst
|
||||
mutexes.rst
|
||||
alerts.rst
|
||||
|
|
|
@ -20,7 +20,6 @@ extern struct k_mem_slab *_trace_list_k_mem_slab;
|
|||
extern struct k_mem_pool *_trace_list_k_mem_pool;
|
||||
extern struct k_sem *_trace_list_k_sem;
|
||||
extern struct k_mutex *_trace_list_k_mutex;
|
||||
extern struct k_alert *_trace_list_k_alert;
|
||||
extern struct k_fifo *_trace_list_k_fifo;
|
||||
extern struct k_lifo *_trace_list_k_lifo;
|
||||
extern struct k_stack *_trace_list_k_stack;
|
||||
|
|
145
include/kernel.h
145
include/kernel.h
|
@ -115,7 +115,6 @@ typedef struct {
|
|||
struct k_thread;
|
||||
struct k_mutex;
|
||||
struct k_sem;
|
||||
struct k_alert;
|
||||
struct k_msgq;
|
||||
struct k_mbox;
|
||||
struct k_pipe;
|
||||
|
@ -3071,150 +3070,6 @@ static inline unsigned int _impl_k_sem_count_get(struct k_sem *sem)
|
|||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup alert_apis Alert APIs
|
||||
* @ingroup kernel_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef k_alert_handler_t
|
||||
* @brief Alert handler function type.
|
||||
*
|
||||
* An alert's alert handler function is invoked by the system workqueue
|
||||
* when the alert is signaled. The alert handler function is optional,
|
||||
* and is only invoked if the alert has been initialized with one.
|
||||
*
|
||||
* @param alert Address of the alert.
|
||||
*
|
||||
* @return 0 if alert has been consumed; non-zero if alert should pend.
|
||||
*/
|
||||
typedef int (*k_alert_handler_t)(struct k_alert *alert);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*/
|
||||
|
||||
#define K_ALERT_DEFAULT NULL
|
||||
#define K_ALERT_IGNORE ((k_alert_handler_t)0xFFFFFFFF)
|
||||
|
||||
struct k_alert {
|
||||
k_alert_handler_t handler;
|
||||
atomic_t send_count;
|
||||
struct k_work work_item;
|
||||
struct k_sem sem;
|
||||
|
||||
_OBJECT_TRACING_NEXT_PTR(k_alert)
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
extern void _alert_deliver(struct k_work *work);
|
||||
|
||||
#define _K_ALERT_INITIALIZER(obj, alert_handler, max_num_pending_alerts) \
|
||||
{ \
|
||||
.handler = (k_alert_handler_t)alert_handler, \
|
||||
.send_count = ATOMIC_INIT(0), \
|
||||
.work_item = _K_WORK_INITIALIZER(_alert_deliver), \
|
||||
.sem = _K_SEM_INITIALIZER(obj.sem, 0, max_num_pending_alerts), \
|
||||
_OBJECT_TRACING_INIT \
|
||||
}
|
||||
|
||||
#define K_ALERT_INITIALIZER DEPRECATED_MACRO _K_ALERT_INITIALIZER
|
||||
|
||||
/**
|
||||
* INTERNAL_HIDDEN @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup alert_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def K_ALERT_DEFINE(name, alert_handler, max_num_pending_alerts)
|
||||
*
|
||||
* @brief Statically define and initialize an alert.
|
||||
*
|
||||
* The alert can be accessed outside the module where it is defined using:
|
||||
*
|
||||
* @code extern struct k_alert <name>; @endcode
|
||||
*
|
||||
* @param name Name of the alert.
|
||||
* @param alert_handler Action to take when alert is sent. Specify either
|
||||
* the address of a function to be invoked by the system workqueue
|
||||
* thread, K_ALERT_IGNORE (which causes the alert to be ignored), or
|
||||
* K_ALERT_DEFAULT (which causes the alert to pend).
|
||||
* @param max_num_pending_alerts Maximum number of pending alerts.
|
||||
*
|
||||
* @req K-ALERT-001
|
||||
*/
|
||||
#define K_ALERT_DEFINE(name, alert_handler, max_num_pending_alerts) \
|
||||
struct k_alert name \
|
||||
__in_section(_k_alert, static, name) = \
|
||||
_K_ALERT_INITIALIZER(name, alert_handler, \
|
||||
max_num_pending_alerts)
|
||||
|
||||
/**
|
||||
* @brief Initialize an alert.
|
||||
*
|
||||
* This routine initializes an alert object, prior to its first use.
|
||||
*
|
||||
* @param alert Address of the alert.
|
||||
* @param handler Action to take when alert is sent. Specify either the address
|
||||
* of a function to be invoked by the system workqueue thread,
|
||||
* K_ALERT_IGNORE (which causes the alert to be ignored), or
|
||||
* K_ALERT_DEFAULT (which causes the alert to pend).
|
||||
* @param max_num_pending_alerts Maximum number of pending alerts.
|
||||
*
|
||||
* @return N/A
|
||||
* @req K-ALERT-002
|
||||
*/
|
||||
extern void k_alert_init(struct k_alert *alert, k_alert_handler_t handler,
|
||||
unsigned int max_num_pending_alerts);
|
||||
|
||||
/**
|
||||
* @brief Receive an alert.
|
||||
*
|
||||
* This routine receives a pending alert for @a alert.
|
||||
*
|
||||
* @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT.
|
||||
*
|
||||
* @param alert Address of the alert.
|
||||
* @param timeout Waiting period to receive the alert (in milliseconds),
|
||||
* or one of the special values K_NO_WAIT and K_FOREVER.
|
||||
*
|
||||
* @retval 0 Alert received.
|
||||
* @retval -EBUSY Returned without waiting.
|
||||
* @retval -EAGAIN Waiting period timed out.
|
||||
* @req K-ALERT-002
|
||||
*/
|
||||
__syscall int k_alert_recv(struct k_alert *alert, s32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Signal an alert.
|
||||
*
|
||||
* This routine signals @a alert. The action specified for @a alert will
|
||||
* be taken, which may trigger the execution of an alert handler function
|
||||
* and/or cause the alert to pend (assuming the alert has not reached its
|
||||
* maximum number of pending alerts).
|
||||
*
|
||||
* @note Can be called by ISRs.
|
||||
*
|
||||
* @param alert Address of the alert.
|
||||
*
|
||||
* @return N/A
|
||||
* @req K-ALERT-002
|
||||
*/
|
||||
__syscall void k_alert_send(struct k_alert *alert);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup msgq_apis Message Queue APIs
|
||||
* @ingroup kernel_apis
|
||||
|
|
|
@ -83,13 +83,6 @@
|
|||
_k_mutex_list_end = .;
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
SECTION_DATA_PROLOGUE(_k_alert_area, (OPTIONAL), SUBALIGN(4))
|
||||
{
|
||||
_k_alert_list_start = .;
|
||||
KEEP(*(SORT_BY_NAME("._k_alert.static.*")))
|
||||
_k_alert_list_end = .;
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
SECTION_DATA_PROLOGUE(_k_queue_area, (OPTIONAL), SUBALIGN(4))
|
||||
{
|
||||
_k_queue_list_start = .;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# kernel is a normal CMake library and not a zephyr_library because it
|
||||
# should not be --whole-archive'd
|
||||
add_library(kernel
|
||||
alert.c
|
||||
device.c
|
||||
errno.c
|
||||
idle.c
|
||||
|
|
110
kernel/alert.c
110
kernel/alert.c
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief kernel alerts.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
#include <debug/object_tracing_common.h>
|
||||
#include <atomic.h>
|
||||
#include <init.h>
|
||||
#include <toolchain.h>
|
||||
#include <linker/sections.h>
|
||||
#include <syscall_handler.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern struct k_alert _k_alert_list_start[];
|
||||
extern struct k_alert _k_alert_list_end[];
|
||||
|
||||
#ifdef CONFIG_OBJECT_TRACING
|
||||
|
||||
struct k_alert *_trace_list_k_alert;
|
||||
|
||||
/*
|
||||
* Complete initialization of statically defined alerts.
|
||||
*/
|
||||
static int init_alert_module(struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
struct k_alert *alert;
|
||||
|
||||
for (alert = _k_alert_list_start; alert < _k_alert_list_end; alert++) {
|
||||
SYS_TRACING_OBJ_INIT(k_alert, alert);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(init_alert_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
|
||||
|
||||
#endif /* CONFIG_OBJECT_TRACING */
|
||||
|
||||
void _alert_deliver(struct k_work *work)
|
||||
{
|
||||
struct k_alert *alert = CONTAINER_OF(work, struct k_alert, work_item);
|
||||
|
||||
while (true) {
|
||||
if ((alert->handler)(alert) == 0) {
|
||||
/* do nothing -- handler has processed the alert */
|
||||
} else {
|
||||
/* pend the alert */
|
||||
k_sem_give(&alert->sem);
|
||||
}
|
||||
if (atomic_dec(&alert->send_count) == 1) {
|
||||
/* have finished delivering alerts */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void k_alert_init(struct k_alert *alert, k_alert_handler_t handler,
|
||||
unsigned int max_num_pending_alerts)
|
||||
{
|
||||
alert->handler = handler;
|
||||
alert->send_count = ATOMIC_INIT(0);
|
||||
alert->work_item = (struct k_work)_K_WORK_INITIALIZER(_alert_deliver);
|
||||
k_sem_init(&alert->sem, 0, max_num_pending_alerts);
|
||||
SYS_TRACING_OBJ_INIT(k_alert, alert);
|
||||
|
||||
_k_object_init(alert);
|
||||
}
|
||||
|
||||
void _impl_k_alert_send(struct k_alert *alert)
|
||||
{
|
||||
if (alert->handler == K_ALERT_IGNORE) {
|
||||
/* ignore the alert */
|
||||
} else if (alert->handler == K_ALERT_DEFAULT) {
|
||||
/* pend the alert */
|
||||
k_sem_give(&alert->sem);
|
||||
} else {
|
||||
/* deliver the alert */
|
||||
if (atomic_inc(&alert->send_count) == 0) {
|
||||
/* add alert's work item to system work queue */
|
||||
k_work_submit_to_queue(&k_sys_work_q,
|
||||
&alert->work_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_SYSCALL_HANDLER1_SIMPLE_VOID(k_alert_send, K_OBJ_ALERT, struct k_alert *);
|
||||
#endif
|
||||
|
||||
int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
|
||||
{
|
||||
return k_sem_take(&alert->sem, timeout);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_SYSCALL_HANDLER(k_alert_recv, alert, timeout)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_OBJ(alert, K_OBJ_ALERT));
|
||||
return _impl_k_alert_recv((struct k_alert *)alert, timeout);
|
||||
}
|
||||
#endif
|
|
@ -17,7 +17,6 @@ from elf_helper import ElfHelper, kobject_to_enum
|
|||
# available in all configurations.
|
||||
|
||||
kobjects = {
|
||||
"k_alert": None,
|
||||
"k_mem_slab": None,
|
||||
"k_msgq": None,
|
||||
"k_mutex": None,
|
||||
|
|
|
@ -671,7 +671,7 @@ class SizeCalculator:
|
|||
"_k_memory_pool", "exceptions", "initshell",
|
||||
"_static_thread_area", "_k_timer_area",
|
||||
"_k_mem_slab_area", "_k_mem_pool_area", "sw_isr_table",
|
||||
"_k_sem_area", "_k_mutex_area", "_k_alert_area",
|
||||
"_k_sem_area", "_k_mutex_area",
|
||||
"_k_fifo_area", "_k_lifo_area", "_k_stack_area",
|
||||
"_k_msgq_area", "_k_mbox_area", "_k_pipe_area",
|
||||
"net_if", "net_if_dev", "net_stack", "net_l2_data",
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
/* event_b.c */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "master.h"
|
||||
|
||||
#ifdef EVENT_BENCH
|
||||
|
||||
/* #define EVENT_CHECK */
|
||||
#ifdef EVENT_CHECK
|
||||
static const char event_signal_err[] = "----------- Error signalling event.\n";
|
||||
static const char event_test_err[] = "----------- Error testing event.\n";
|
||||
static const char event_handler_err[] = "----------- Error in event handler\n";
|
||||
#endif
|
||||
|
||||
/* global Event value */
|
||||
volatile int nevent_value;
|
||||
|
||||
/*
|
||||
* Function prototypes.
|
||||
*/
|
||||
int example_handler (struct k_alert *alert);
|
||||
|
||||
/*
|
||||
* Function declarations.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Event signal speed test
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void event_test(void)
|
||||
{
|
||||
int nreturn = 0;
|
||||
int ncounter;
|
||||
u32_t et; /* elapsed time */
|
||||
|
||||
PRINT_STRING(dashline, output_file);
|
||||
et = BENCH_START();
|
||||
for (ncounter = 0; ncounter < NR_OF_EVENT_RUNS; ncounter++) {
|
||||
k_alert_send(&TEST_EVENT);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_signal_err, output_file);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
}
|
||||
et = TIME_STAMP_DELTA_GET(et);
|
||||
check_result();
|
||||
|
||||
PRINT_F(output_file, FORMAT, "Signal enabled event",
|
||||
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_EVENT_RUNS));
|
||||
|
||||
et = BENCH_START();
|
||||
for (ncounter = 0; ncounter < NR_OF_EVENT_RUNS; ncounter++) {
|
||||
k_alert_send(&TEST_EVENT);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_signal_err, output_file);
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
k_alert_recv(&TEST_EVENT, K_NO_WAIT);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_test_err, output_file);
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
}
|
||||
et = TIME_STAMP_DELTA_GET(et);
|
||||
check_result();
|
||||
|
||||
PRINT_F(output_file, FORMAT, "Signal event & Test event",
|
||||
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_EVENT_RUNS));
|
||||
|
||||
et = BENCH_START();
|
||||
for (ncounter = 0; ncounter < NR_OF_EVENT_RUNS; ncounter++) {
|
||||
k_alert_send(&TEST_EVENT);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_signal_err, output_file);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
k_alert_recv(&TEST_EVENT, K_FOREVER);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_test_err, output_file);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
}
|
||||
et = TIME_STAMP_DELTA_GET(et);
|
||||
check_result();
|
||||
|
||||
PRINT_F(output_file, FORMAT, "Signal event & TestW event",
|
||||
SYS_CLOCK_HW_CYCLES_TO_NS_AVG(et, NR_OF_EVENT_RUNS));
|
||||
|
||||
PRINT_STRING("| Signal event with installed handler"
|
||||
" |\n", output_file);
|
||||
TEST_EVENT.handler = example_handler;
|
||||
if (nreturn != 0) {
|
||||
PRINT_F(output_file,
|
||||
"-------- Error installing event handler.\n");
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
|
||||
for (ncounter = 0; ncounter < NR_OF_EVENT_RUNS; ncounter++) {
|
||||
k_alert_send(&TEST_EVENT);
|
||||
#ifdef EVENT_CHECK
|
||||
if (nreturn != 0) {
|
||||
PRINT_STRING(event_signal_err, output_file);
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
if (nevent_value != TEST_EVENT.send_count + 1) {
|
||||
PRINT_STRING(event_handler_err, output_file);
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
#endif /* EVENT_CHECK */
|
||||
nevent_value = 0;
|
||||
}
|
||||
|
||||
TEST_EVENT.handler = NULL;
|
||||
if (nreturn != 0) {
|
||||
PRINT_F(output_file, "Error removing event handler.\n");
|
||||
k_sleep(1);
|
||||
return; /* error */
|
||||
}
|
||||
|
||||
PRINT_STRING("| Handler responds OK"
|
||||
" |\n",
|
||||
output_file);
|
||||
|
||||
return; /* success */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Event handler for the tests
|
||||
*
|
||||
* The event handler for the test. Sets up nEventValue global variable.
|
||||
* This variable is used in the main test.
|
||||
*
|
||||
* @return 1
|
||||
*/
|
||||
int example_handler (struct k_alert *alert)
|
||||
{
|
||||
ARG_UNUSED(alert);
|
||||
nevent_value = alert->send_count + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* EVENT_BENCH */
|
|
@ -63,8 +63,6 @@ K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4);
|
|||
|
||||
K_MEM_POOL_DEFINE(DEMOPOOL, 16, 16, 1, 4);
|
||||
|
||||
K_ALERT_DEFINE(TEST_EVENT, NULL, 1);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -138,7 +136,6 @@ void main(void)
|
|||
mutex_test();
|
||||
memorymap_test();
|
||||
mempool_test();
|
||||
event_test();
|
||||
mailbox_test();
|
||||
pipe_test();
|
||||
PRINT_STRING("| END OF TESTS "
|
||||
|
|
|
@ -122,12 +122,6 @@ extern void pipe_test(void);
|
|||
#define pipe_test dummy_test
|
||||
#endif
|
||||
|
||||
#ifdef EVENT_BENCH
|
||||
extern void event_test(void);
|
||||
#else
|
||||
#define event_test dummy_test
|
||||
#endif
|
||||
|
||||
/* kernel objects needed for benchmarking */
|
||||
extern struct k_mutex DEMO_MUTEX;
|
||||
|
||||
|
@ -153,8 +147,6 @@ extern struct k_pipe PIPE_BIGBUFF;
|
|||
|
||||
extern struct k_mem_slab MAP1;
|
||||
|
||||
extern struct k_alert TEST_EVENT;
|
||||
|
||||
extern struct k_mem_pool DEMOPOOL;
|
||||
|
||||
|
||||
|
|
|
@ -61,11 +61,6 @@ static pfunc func_array[] = {
|
|||
(pfunc)k_mem_slab_num_free_get,
|
||||
|
||||
#ifdef TEST_max
|
||||
/* alerts */
|
||||
(pfunc)k_alert_init,
|
||||
(pfunc)k_alert_send,
|
||||
(pfunc)k_alert_recv,
|
||||
|
||||
/* message queues */
|
||||
(pfunc)k_msgq_init,
|
||||
(pfunc)k_msgq_put,
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.13.1)
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(alert_api)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
|
@ -1,2 +0,0 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_IRQ_OFFLOAD=y
|
|
@ -1,524 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <ztest.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
#define TIMEOUT 100
|
||||
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
|
||||
#define PENDING_MAX 2
|
||||
#define SEM_INITIAL 0
|
||||
#define SEM_LIMIT 1
|
||||
|
||||
K_SEM_DEFINE(sync_sema, SEM_INITIAL, SEM_LIMIT);
|
||||
|
||||
static int alert_handler0(struct k_alert *);
|
||||
static int alert_handler1(struct k_alert *);
|
||||
|
||||
/**TESTPOINT: init via K_ALERT_DEFINE*/
|
||||
K_ALERT_DEFINE(kalert_pending, alert_handler1, PENDING_MAX);
|
||||
K_ALERT_DEFINE(kalert_consumed, alert_handler0, PENDING_MAX);
|
||||
|
||||
enum handle_type {
|
||||
HANDLER_IGNORE,
|
||||
HANDLER_DEFAULT,
|
||||
HANDLER_0,
|
||||
HANDLER_1
|
||||
};
|
||||
|
||||
static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
|
||||
static K_THREAD_STACK_DEFINE(sync_tstack, STACK_SIZE);
|
||||
__kernel struct k_thread tdata;
|
||||
__kernel struct k_thread sync_tdata;
|
||||
__kernel struct k_alert thread_alerts[4];
|
||||
static struct k_alert *palert;
|
||||
static enum handle_type htype;
|
||||
static volatile u32_t handler_executed;
|
||||
static volatile u32_t handler_val;
|
||||
|
||||
|
||||
/*handlers*/
|
||||
static int alert_handler0(struct k_alert *alt)
|
||||
{
|
||||
handler_executed++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alert_handler1(struct k_alert *alt)
|
||||
{
|
||||
handler_executed++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void alert_send(void)
|
||||
{
|
||||
/**TESTPOINT: alert send*/
|
||||
for (int i = 0; i < PENDING_MAX; i++) {
|
||||
k_alert_send(palert);
|
||||
}
|
||||
}
|
||||
|
||||
static void alert_recv(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (htype) {
|
||||
case HANDLER_0:
|
||||
zassert_equal(handler_executed, PENDING_MAX, NULL);
|
||||
/* Fall through */
|
||||
case HANDLER_IGNORE:
|
||||
ret = k_alert_recv(palert, TIMEOUT);
|
||||
zassert_equal(ret, -EAGAIN, NULL);
|
||||
break;
|
||||
case HANDLER_1:
|
||||
zassert_equal(handler_executed, PENDING_MAX, NULL);
|
||||
/* Fall through */
|
||||
case HANDLER_DEFAULT:
|
||||
for (int i = 0; i < PENDING_MAX; i++) {
|
||||
/**TESTPOINT: alert recv*/
|
||||
ret = k_alert_recv(palert, K_NO_WAIT);
|
||||
zassert_false(ret, NULL);
|
||||
}
|
||||
/**TESTPOINT: alert recv -EAGAIN*/
|
||||
ret = k_alert_recv(palert, TIMEOUT);
|
||||
zassert_equal(ret, -EAGAIN, NULL);
|
||||
/**TESTPOINT: alert recv -EBUSY*/
|
||||
ret = k_alert_recv(palert, K_NO_WAIT);
|
||||
zassert_equal(ret, -EBUSY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
alert_recv();
|
||||
}
|
||||
|
||||
static void thread_alert(void)
|
||||
{
|
||||
handler_executed = 0U;
|
||||
/**TESTPOINT: thread-thread sync via alert*/
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry, NULL, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0),
|
||||
K_USER | K_INHERIT_PERMS,
|
||||
0);
|
||||
alert_send();
|
||||
k_sleep(TIMEOUT);
|
||||
k_thread_abort(tid);
|
||||
}
|
||||
|
||||
static void tisr_entry(void *p)
|
||||
{
|
||||
alert_send();
|
||||
}
|
||||
|
||||
static void sync_entry(void *p)
|
||||
{
|
||||
k_alert_send(palert);
|
||||
}
|
||||
|
||||
static void isr_alert(void)
|
||||
{
|
||||
handler_executed = 0U;
|
||||
/**TESTPOINT: thread-isr sync via alert*/
|
||||
irq_offload(tisr_entry, NULL);
|
||||
k_sleep(TIMEOUT);
|
||||
alert_recv();
|
||||
}
|
||||
|
||||
int event_handler(struct k_alert *alt)
|
||||
{
|
||||
return handler_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests for the Alert kernel object
|
||||
* @defgroup kernel_alert_tests Alerts
|
||||
* @ingroup all_tests
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Test thread alert default
|
||||
*
|
||||
* Checks k_alert_init(), k_alert_send(), k_alert_recv() Kernel APIs.
|
||||
*
|
||||
* Initializes an alert and creates a thread that signals an alert with
|
||||
* k_alert_send() and then calls k_alert_recv() with K_NO_WAIT to receive the
|
||||
* alerts. Checks if k_alert_recv() returns appropriate error values when
|
||||
* alerts are not received.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_default(void)
|
||||
{
|
||||
palert = &thread_alerts[HANDLER_DEFAULT];
|
||||
htype = HANDLER_DEFAULT;
|
||||
thread_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test thread alert ignore
|
||||
*
|
||||
* Checks k_alert_init(), k_alert_send(), k_alert_recv() Kernel APIs - creates
|
||||
* a thread that signals an alert using k_alert_send() and then calls
|
||||
* k_alert_recv() with TIMEOUT of 100ms which is the waiting period for
|
||||
* receiving the alert.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_ignore(void)
|
||||
{
|
||||
palert = &thread_alerts[HANDLER_IGNORE];
|
||||
htype = HANDLER_IGNORE;
|
||||
thread_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test thread alert consumed
|
||||
*
|
||||
* Checks k_alert_init(), k_alert_send(), k_alert_recv() Kernel APIs.
|
||||
*
|
||||
* Creates a thread that signals an alert using k_alert_send(). Now
|
||||
* k_alert_send() for this case is initialized with an address of the handler
|
||||
* function, which increases handler_executed count each time it is called.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_consumed(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler return 0*/
|
||||
palert = &thread_alerts[HANDLER_0];
|
||||
htype = HANDLER_0;
|
||||
thread_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test thread alert pending
|
||||
*
|
||||
* Checks k_alert_init(), k_alert_send(), k_alert_recv() Kernel APIs
|
||||
*
|
||||
* Creates a thread that signals an alert using k_alert_send().
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_pending(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler return 1*/
|
||||
palert = &thread_alerts[HANDLER_1];
|
||||
htype = HANDLER_1;
|
||||
thread_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test default isr alert
|
||||
*
|
||||
* Similar to test_thread_alert_default(), but verifies kernel objects and
|
||||
* APIs work correctly in interrupt context with the help of irq_offload()
|
||||
* function.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_isr_alert_default(void)
|
||||
{
|
||||
struct k_alert alert;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, K_ALERT_DEFAULT, PENDING_MAX);
|
||||
|
||||
/**TESTPOINT: alert handler default*/
|
||||
palert = &alert;
|
||||
htype = HANDLER_DEFAULT;
|
||||
isr_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test isr alert ignore
|
||||
*
|
||||
* Similar to test_thread_alert_ignore(), but verifies kernel objects and
|
||||
* APIs work correctly in interrupt context with the help of irq_offload()
|
||||
* function.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_isr_alert_ignore(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler ignore*/
|
||||
struct k_alert alert;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, K_ALERT_IGNORE, PENDING_MAX);
|
||||
palert = &alert;
|
||||
htype = HANDLER_IGNORE;
|
||||
isr_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test isr alert consumed
|
||||
*
|
||||
* Similar to test_thread_alert_consumed, but verifies kernel objects
|
||||
* and APIs work correctly in interrupt context with the help of irq_offload()
|
||||
* function.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_isr_alert_consumed(void)
|
||||
{
|
||||
struct k_alert alert;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, alert_handler0, PENDING_MAX);
|
||||
|
||||
/**TESTPOINT: alert handler return 0*/
|
||||
palert = &alert;
|
||||
htype = HANDLER_0;
|
||||
isr_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test isr alert pending
|
||||
*
|
||||
* Similar to test_thread_alert_pending(), but verifies kernel objects and
|
||||
* APIs work correctly in interrupt context with the help of irq_offload()
|
||||
* function.
|
||||
*
|
||||
* @see k_alert_init(), k_alert_send(), k_alert_recv()
|
||||
*/
|
||||
void test_isr_alert_pending(void)
|
||||
{
|
||||
struct k_alert alert;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, alert_handler1, PENDING_MAX);
|
||||
|
||||
/**TESTPOINT: alert handler return 0*/
|
||||
palert = &alert;
|
||||
htype = HANDLER_1;
|
||||
isr_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test thread kinit alert
|
||||
*
|
||||
* Tests consumed and pending thread alert cases (reference line numbers 4 and
|
||||
* 5), but handles case where alert has been defined via #K_ALERT_DEFINE(x) and not
|
||||
* k_alert_init()
|
||||
*
|
||||
* @see #K_ALERT_DEFINE(x)
|
||||
*/
|
||||
void test_thread_kinit_alert(void)
|
||||
{
|
||||
palert = &kalert_consumed;
|
||||
htype = HANDLER_0;
|
||||
thread_alert();
|
||||
palert = &kalert_pending;
|
||||
htype = HANDLER_1;
|
||||
thread_alert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test isr kinit alert
|
||||
*
|
||||
* Checks consumed and pending isr alert cases but alert has been defined via
|
||||
* #K_ALERT_DEFINE(x) and not k_alert_init()
|
||||
*
|
||||
* @see #K_ALERT_DEFINE(x)
|
||||
*/
|
||||
void test_isr_kinit_alert(void)
|
||||
{
|
||||
palert = &kalert_consumed;
|
||||
htype = HANDLER_0;
|
||||
isr_alert();
|
||||
palert = &kalert_pending;
|
||||
htype = HANDLER_1;
|
||||
isr_alert();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test alert_recv(timeout)
|
||||
*
|
||||
* This test checks k_alert_recv(timeout) against the following cases:
|
||||
* 1. The current task times out while waiting for the event.
|
||||
* 2. There is already an event waiting (signaled from a task).
|
||||
* 3. The current task must wait on the event until it is signaled
|
||||
* from either another task or an ISR.
|
||||
*
|
||||
* @see k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_timeout(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler ignore*/
|
||||
struct k_alert alert;
|
||||
int ret, i;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, K_ALERT_DEFAULT, PENDING_MAX);
|
||||
|
||||
palert = &alert;
|
||||
|
||||
ret = k_alert_recv(&alert, TIMEOUT);
|
||||
|
||||
zassert_equal(ret, -EAGAIN, NULL);
|
||||
|
||||
k_alert_send(&alert);
|
||||
|
||||
ret = k_alert_recv(&alert, TIMEOUT);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
|
||||
k_sem_give(&sync_sema);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ret = k_alert_recv(&alert, TIMEOUT);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test k_alert_recv() against different cases
|
||||
*
|
||||
* This test checks k_alert_recv(K_FOREVER) against
|
||||
* the following cases:
|
||||
* 1. There is already an event waiting (signaled from a task and ISR).
|
||||
* 2. The current task must wait on the event until it is signaled
|
||||
* from either another task or an ISR.
|
||||
*
|
||||
* @see k_alert_recv()
|
||||
*/
|
||||
void test_thread_alert_wait(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler ignore*/
|
||||
struct k_alert alert;
|
||||
int ret, i;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, K_ALERT_DEFAULT, PENDING_MAX);
|
||||
|
||||
palert = &alert;
|
||||
|
||||
k_alert_send(&alert);
|
||||
|
||||
ret = k_alert_recv(&alert, K_FOREVER);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
|
||||
irq_offload(sync_entry, NULL);
|
||||
|
||||
ret = k_alert_recv(&alert, K_FOREVER);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
|
||||
k_sem_give(&sync_sema);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ret = k_alert_recv(&alert, K_FOREVER);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test thread alert handler
|
||||
*
|
||||
* This test checks that the event handler is set up properly when
|
||||
* k_alert_init() is called with an event handler. It shows that event
|
||||
* handlers are tied to the specified event and that the return value from the
|
||||
* handler affects whether the event wakes a task waiting upon that event.
|
||||
*
|
||||
* @see k_alert_init()
|
||||
*/
|
||||
void test_thread_alert_handler(void)
|
||||
{
|
||||
/**TESTPOINT: alert handler ignore*/
|
||||
struct k_alert alert;
|
||||
int ret;
|
||||
|
||||
/**TESTPOINT: init via k_alert_init*/
|
||||
k_alert_init(&alert, event_handler, PENDING_MAX);
|
||||
|
||||
palert = &alert;
|
||||
|
||||
k_sem_give(&sync_sema);
|
||||
|
||||
ret = k_alert_recv(&alert, TIMEOUT);
|
||||
|
||||
zassert_equal(ret, -EAGAIN, NULL);
|
||||
|
||||
k_sem_give(&sync_sema);
|
||||
|
||||
ret = k_alert_recv(&alert, TIMEOUT);
|
||||
|
||||
zassert_equal(ret, 0, NULL);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Signal various events to a waiting task
|
||||
*/
|
||||
void signal_task(void *p1, void *p2, void *p3)
|
||||
{
|
||||
k_sem_init(&sync_sema, 0, 1);
|
||||
|
||||
k_sem_take(&sync_sema, K_FOREVER);
|
||||
k_alert_send(palert);
|
||||
irq_offload(sync_entry, NULL);
|
||||
|
||||
k_sem_take(&sync_sema, K_FOREVER);
|
||||
k_alert_send(palert);
|
||||
irq_offload(sync_entry, NULL);
|
||||
|
||||
k_sem_take(&sync_sema, K_FOREVER);
|
||||
handler_val = 0U;
|
||||
k_alert_send(palert);
|
||||
|
||||
k_sem_take(&sync_sema, K_FOREVER);
|
||||
handler_val = 1U;
|
||||
k_alert_send(palert);
|
||||
}
|
||||
|
||||
/*test case main entry*/
|
||||
void test_main(void)
|
||||
{
|
||||
k_thread_access_grant(k_current_get(), &kalert_pending,
|
||||
&kalert_consumed, &tdata, &tstack,
|
||||
&thread_alerts[HANDLER_DEFAULT],
|
||||
&thread_alerts[HANDLER_IGNORE],
|
||||
&thread_alerts[HANDLER_0],
|
||||
&thread_alerts[HANDLER_1]);
|
||||
|
||||
k_alert_init(&thread_alerts[HANDLER_DEFAULT], K_ALERT_DEFAULT,
|
||||
PENDING_MAX);
|
||||
k_alert_init(&thread_alerts[HANDLER_IGNORE], K_ALERT_IGNORE,
|
||||
PENDING_MAX);
|
||||
k_alert_init(&thread_alerts[HANDLER_0], alert_handler0, PENDING_MAX);
|
||||
k_alert_init(&thread_alerts[HANDLER_1], alert_handler1, PENDING_MAX);
|
||||
|
||||
/**TESTPOINT: thread-thread sync via alert*/
|
||||
k_thread_create(&sync_tdata, sync_tstack, STACK_SIZE,
|
||||
signal_task, NULL, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), 0, 0);
|
||||
|
||||
ztest_test_suite(alert_api,
|
||||
ztest_unit_test(test_thread_alert_timeout),
|
||||
ztest_unit_test(test_thread_alert_wait),
|
||||
ztest_unit_test(test_thread_alert_handler),
|
||||
ztest_user_unit_test(test_thread_alert_default),
|
||||
ztest_user_unit_test(test_thread_alert_ignore),
|
||||
ztest_user_unit_test(test_thread_alert_consumed),
|
||||
ztest_user_unit_test(test_thread_alert_pending),
|
||||
ztest_unit_test(test_isr_alert_default),
|
||||
ztest_unit_test(test_isr_alert_ignore),
|
||||
ztest_unit_test(test_isr_alert_consumed),
|
||||
ztest_unit_test(test_isr_alert_pending),
|
||||
ztest_user_unit_test(test_thread_kinit_alert),
|
||||
ztest_unit_test(test_isr_kinit_alert));
|
||||
ztest_run_test_suite(alert_api);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
tests:
|
||||
kernel.alert:
|
||||
tags: kernel userspace
|
|
@ -13,7 +13,6 @@ enum obj_name {
|
|||
MEM_SLAB,
|
||||
SEM,
|
||||
MUTEX,
|
||||
ALERT,
|
||||
STACK,
|
||||
MSGQ,
|
||||
MBOX,
|
||||
|
@ -30,16 +29,10 @@ static inline void stop_dummy_fn(struct k_timer *timer)
|
|||
ARG_UNUSED(timer);
|
||||
}
|
||||
|
||||
static inline void alert_handler_dummy(struct k_alert *alert)
|
||||
{
|
||||
ARG_UNUSED(alert);
|
||||
}
|
||||
|
||||
K_TIMER_DEFINE(ktimer, expiry_dummy_fn, stop_dummy_fn);
|
||||
K_MEM_SLAB_DEFINE(kmslab, 4, 2, 4);
|
||||
K_SEM_DEFINE(ksema, 0, 1);
|
||||
K_MUTEX_DEFINE(kmutex);
|
||||
K_ALERT_DEFINE(kalert, alert_handler_dummy, 1);
|
||||
K_STACK_DEFINE(kstack, 512);
|
||||
K_MSGQ_DEFINE(kmsgq, 4, 2, 4);
|
||||
K_MBOX_DEFINE(kmbox);
|
||||
|
@ -50,7 +43,6 @@ static struct k_timer timer;
|
|||
static struct k_mem_slab mslab;
|
||||
static struct k_sem sema;
|
||||
static struct k_mutex mutex;
|
||||
static struct k_alert alert;
|
||||
static struct k_stack stack;
|
||||
static struct k_msgq msgq;
|
||||
static struct k_mbox mbox;
|
||||
|
@ -142,23 +134,6 @@ static void get_obj_count(int obj_type)
|
|||
}
|
||||
zassert_equal(obj_found, 2, "Didn't find mutex objects");
|
||||
break;
|
||||
case ALERT:
|
||||
k_alert_init(&alert, K_ALERT_IGNORE, 1);
|
||||
|
||||
obj_list = SYS_TRACING_HEAD(struct k_alert, k_alert);
|
||||
while (obj_list != NULL) {
|
||||
if (obj_list == &kalert || obj_list == &alert) {
|
||||
obj_found++;
|
||||
if (obj_found == 2) {
|
||||
TC_PRINT("Found alert objects\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
obj_list = SYS_TRACING_NEXT(struct k_alert, k_alert,
|
||||
obj_list);
|
||||
}
|
||||
zassert_equal(obj_found, 2, "Didn't find alert objects");
|
||||
break;
|
||||
case STACK:
|
||||
k_stack_init(&stack, sdata, NUM_BLOCKS);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue