-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
suit: Add module to define SUIT processing events
Add a module that allows to synchronize SUIT processing among several threads. The primary use case is to control the main processor logic, based on SSF requests. Ref: NCSDK-29996 Signed-off-by: Tomasz Chyrowicz <[email protected]>
- Loading branch information
Showing
15 changed files
with
1,075 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
# SUIT Events API | ||
zephyr_interface_library_named(suit_events) | ||
target_include_directories(suit_events INTERFACE include) | ||
|
||
zephyr_library() | ||
zephyr_library_sources(src/suit_events.c) | ||
zephyr_library_link_libraries(suit_events) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
config SUIT_EVENTS | ||
bool "Enable SUIT events module" | ||
select EVENTS | ||
|
||
if SUIT_EVENTS | ||
|
||
config APP_LINK_WITH_SUIT_EVENTS | ||
bool | ||
default y | ||
|
||
endif # SUIT_EVENTS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#ifndef SUIT_EVENTS_H__ | ||
#define SUIT_EVENTS_H__ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
/* Pendable events that threads can wait for. */ | ||
|
||
/** Event indicating a successful execution of the suit-invoke command. */ | ||
#define SUIT_EVENT_INVOKE_SUCCESS BIT(0) | ||
|
||
/** Event indicating an unsuccessful execution of the suit-invoke command. */ | ||
#define SUIT_EVENT_INVOKE_FAIL BIT(1) | ||
|
||
/** Mask for events, related to the execution of the suit-invoke command. */ | ||
#define SUIT_EVENT_INVOKE_MASK (SUIT_EVENT_INVOKE_SUCCESS | SUIT_EVENT_INVOKE_FAIL) | ||
|
||
/** CPU ID indicating all supported CPU IDs */ | ||
#define SUIT_EVENT_CPU_ID_ANY 0xFF | ||
|
||
/** Special value of the timeout that represents infinite time. */ | ||
#define SUIT_WAIT_FOREVER 0xFFFFFFFF | ||
|
||
/** | ||
* @brief Post one or more events for a given CPU. | ||
* | ||
* This routine posts one or more events to an internal event object for a given CPU. | ||
* All tasks waiting using @ref suit_event_wait whose waiting conditions become met by this | ||
* posting immediately unpend. | ||
* | ||
* @note This API is a proxy for @ref k_event_post API that splits the event mask | ||
* into 8 distinct 4-bit pools for 8 different CPU IDs. | ||
* | ||
* @param cpu_id The CPU ID for which the events will be posted. | ||
* Use @ref SUIT_EVENT_CPU_ID_ANY to post an event for all of the CPUs. | ||
* @param events Set of events to post for a given CPU. | ||
* | ||
* @retval Previous value of the events for a given CPU. | ||
*/ | ||
uint32_t suit_event_post(uint8_t cpu_id, uint8_t events); | ||
|
||
/** | ||
* @brief Clear the events for given CPU. | ||
* | ||
* This routine clears (resets) the specified events for given CPU stored in | ||
* an event object. Use @ref SUIT_EVENT_CPU_ID_ANY to clear events for all CPUs. | ||
* | ||
* @note This API is a proxy for @ref k_event_clear API that splits the event mask | ||
* into 8 distinct 4-bit pools for 8 different CPU IDs. | ||
* | ||
* @param cpu_id The CPU ID for which the events will be cleared. | ||
* Use @ref SUIT_EVENT_CPU_ID_ANY to clear events for all of the CPUs. | ||
* @param events Set of events to clear for a given CPU. | ||
* | ||
* @retval Previous value of the events for a given CPU. | ||
*/ | ||
uint32_t suit_event_clear(uint8_t cpu_id, uint8_t events); | ||
|
||
/** | ||
* @brief Wait for any of the specified events assigned to a given CPU. | ||
* | ||
* This routine waits on internal @a event object untli any of the specifies | ||
* events for a given CPU ID have been posted, or the maximum wait time | ||
* @a timeout has expired. | ||
* A thread may wait on up to 4 distinctly numbered events that are expressed | ||
* as bits in a single 8-bit word. | ||
* | ||
* @note This API is a proxy for @ref k_event_wait API that splits the event mask | ||
* into 8 distinct 4-bit pools for 8 different CPU IDs. | ||
* | ||
* @param cpu_id The CPU ID whose events to wait for. | ||
* Use @ref SUIT_EVENT_CPU_ID_ANY to wait for an event for any of the CPUs. | ||
* @param events Set of desired events on which to wait | ||
* @param reset If true, clear the set of events for given CPU ID tracked by the | ||
* event object before waiting. If false, do not clear the events. | ||
* @param timeout Waiting period for the desired set of events. | ||
* Use @ref SUIT_WAIT_FOREVER to wait forever. | ||
* | ||
* @retval set of matching events for a given CPU upon success. | ||
* @retval 0 if matching events were not received for a given CPU within the specified time. | ||
*/ | ||
uint32_t suit_event_wait(uint8_t cpu_id, uint8_t events, bool reset, uint32_t timeout_ms); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* SUIT_EVENTS_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#include <suit_events.h> | ||
#include <zephyr/kernel.h> | ||
|
||
/* Helper mask, with 0th bits for all processors set. */ | ||
#define ALL_CPUS_MASK 0x11111111 | ||
|
||
/* Helper mask, with all event bits for a given processor set. */ | ||
#define ALL_EVENT_MASK 0x0F | ||
|
||
/* The maximum CPU ID handled by this module. */ | ||
#define CPU_N 8 | ||
|
||
/* The number of bits per CPU inside the event mask. */ | ||
#define BITS_N 4 | ||
|
||
/* Internal event structure, common for all API calls. */ | ||
static K_EVENT_DEFINE(suit_events); | ||
|
||
/* Convert (cpu_id, event mask) pair into global (common for all CPUs) event mask. */ | ||
static uint32_t cpu_events_to_suit_events_mask(uint8_t cpu_id, uint8_t events) | ||
{ | ||
/* Check for valid CPU ID values. */ | ||
if ((cpu_id >= CPU_N) && (cpu_id != SUIT_EVENT_CPU_ID_ANY)) { | ||
return 0; | ||
} | ||
|
||
/* Mask all unsupported events. */ | ||
events &= ALL_EVENT_MASK; | ||
|
||
if (cpu_id == SUIT_EVENT_CPU_ID_ANY) { | ||
return events * ALL_CPUS_MASK; | ||
} | ||
|
||
return (uint32_t)events << (cpu_id * BITS_N); | ||
} | ||
|
||
/* Convert global (common for all CPUs) event mask into an event mask for a given CPU. */ | ||
static uint8_t suit_events_mask_to_cpu_events(uint8_t cpu_id, uint32_t events) | ||
{ | ||
uint32_t cpu_shift = 0; | ||
uint32_t cpu_events = 0; | ||
|
||
/* Check for valid CPU ID values. */ | ||
if ((cpu_id >= CPU_N) && (cpu_id != SUIT_EVENT_CPU_ID_ANY)) { | ||
return 0; | ||
} | ||
|
||
if (cpu_id == SUIT_EVENT_CPU_ID_ANY) { | ||
uint8_t common_mask = 0; | ||
|
||
for (size_t id = 0; id < CPU_N; id++) { | ||
cpu_shift = (id * BITS_N); | ||
cpu_events = | ||
(events & ((uint32_t)ALL_EVENT_MASK << cpu_shift)) >> cpu_shift; | ||
common_mask |= (cpu_events & ALL_EVENT_MASK); | ||
} | ||
|
||
return common_mask; | ||
} | ||
|
||
cpu_shift = (cpu_id * BITS_N); | ||
cpu_events = (events & ((uint32_t)ALL_EVENT_MASK << cpu_shift)) >> cpu_shift; | ||
|
||
return (cpu_events & ALL_EVENT_MASK); | ||
} | ||
|
||
uint32_t suit_event_post(uint8_t cpu_id, uint8_t events) | ||
{ | ||
uint32_t main_mask = cpu_events_to_suit_events_mask(cpu_id, events); | ||
|
||
if (main_mask == 0) { | ||
/* Unsupported CPU ID. */ | ||
return 0; | ||
} | ||
|
||
return suit_events_mask_to_cpu_events(cpu_id, k_event_post(&suit_events, main_mask)); | ||
} | ||
|
||
uint32_t suit_event_clear(uint8_t cpu_id, uint8_t events) | ||
{ | ||
uint32_t main_mask = cpu_events_to_suit_events_mask(cpu_id, events); | ||
|
||
if (main_mask == 0) { | ||
/* Unsupported CPU ID. */ | ||
return 0; | ||
} | ||
|
||
return suit_events_mask_to_cpu_events(cpu_id, k_event_clear(&suit_events, main_mask)); | ||
} | ||
|
||
uint32_t suit_event_wait(uint8_t cpu_id, uint8_t events, bool reset, uint32_t timeout_ms) | ||
{ | ||
k_timeout_t timeout = K_NO_WAIT; | ||
uint32_t main_mask = cpu_events_to_suit_events_mask(cpu_id, events); | ||
|
||
if (main_mask == 0) { | ||
/* Unsupported CPU ID. */ | ||
return 0; | ||
} | ||
|
||
if (reset) { | ||
(void)suit_event_clear(cpu_id, main_mask); | ||
} | ||
|
||
if (timeout_ms == SUIT_WAIT_FOREVER) { | ||
timeout = K_FOREVER; | ||
} else if (timeout_ms != 0) { | ||
timeout = K_MSEC(timeout_ms); | ||
} | ||
|
||
return suit_events_mask_to_cpu_events( | ||
cpu_id, k_event_wait(&suit_events, main_mask, false, timeout)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.