Skip to content

Commit

Permalink
Implement event wait signal to avoid data lost.
Browse files Browse the repository at this point in the history
  • Loading branch information
At-EC committed Apr 13, 2024
1 parent c07f1f4 commit 15ae539
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 58 deletions.
6 changes: 3 additions & 3 deletions build_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
extern "C" {
#endif

#define ATOS_BUILD_TIME "2024-04-07,19:46"
#define ATOS_COMMIT_HEAD_ID "4f5dfd03d8433e97030797e30c45f746b06a33a8"
#define ATOS_BUILD_TIME "2024-04-13,19:11"
#define ATOS_COMMIT_HEAD_ID "c07f1f47f92be3dfd394de63e781c9c24fee2510"
#define ATOS_VERSION_MAJOR_NUMBER (1u)
#define ATOS_VERSION_MINOR_NUMBER (4u)
#define ATOS_VERSION_PATCH_NUMBER (2u)
#define ATOS_VERSION_PATCH_NUMBER (3u)

#define ATOS_VERSION_MAJOR_NUMBER_MASK (0x03FFu)
#define ATOS_VERSION_MAJOR_NUMBER_POS (22u)
Expand Down
16 changes: 9 additions & 7 deletions include/kernal/at_rtos.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,23 +511,24 @@ static inline u32p_t evt_set(os_evt_id_t id, u32_t set, u32_t clear, u32_t toggl
*
* @param id The event unique id.
* @param pEvtData The pointer of event value.
* @param desired If the desired is not zero, All changed bits seen can wake up the thread to handle event.
* @param listen Current thread listen which bits in the event.
* @param desired_val If the desired is not zero, All changed bits seen can wake up the thread to handle event.
* @param listen_mask Current thread listen which bits in the event.
* @param group_mask To define a group event.
* @param timeout_ms The event wait timeout setting.
*
* @return The result of the operation.
**
* demo usage:
*
* u32_t event = 0u;
* u32p_t postcode = evt_wait(sample_id, &event, 0x01u, 0x01u, OS_WAIT_FOREVER);
* u32p_t postcode = evt_wait(sample_id, &event, 0xFFFFFFFu, 0x01u, 0x01u, OS_WAIT_FOREVER);
* if (PC_IOK(postcode)) {
* printf("Event wait successful, The event value is 0x%x\n", event);
* } else {
* printf("Event wait error: 0x%x\n", postcode);
* }
*
* u32p_t postcode = evt_wait(sample_id, &event, 0x01u, 0x01u, 1000u);
* u32p_t postcode = evt_wait(sample_id, &event, 0xFFFFFFFu, 0x03u, 0x03u, 1000u);
* if (PC_IOK(postcode)) {
* if (postcode == PC_SC_TIMEOUT) {
* printf("Event wait timeout\n");
Expand All @@ -538,9 +539,10 @@ static inline u32p_t evt_set(os_evt_id_t id, u32_t set, u32_t clear, u32_t toggl
* printf("Event wait error: 0x%x\n", postcode);
* }
*/
static inline u32p_t evt_wait(os_evt_id_t id, u32_t *pEvtData, u32_t desired, u32_t listen, u32_t timeout_ms)
static inline u32p_t evt_wait(os_evt_id_t id, os_evt_val_t *pEvtData, u32_t desired_val, u32_t listen_mask, u32_t group_mask,
u32_t timeout_ms)
{
return (u32p_t)_impl_event_wait(id.val, pEvtData, desired, listen, timeout_ms);
return (u32p_t)_impl_event_wait(id.val, pEvtData, desired_val, listen_mask, group_mask, timeout_ms);
}

/**
Expand Down Expand Up @@ -876,7 +878,7 @@ typedef struct {

os_evt_id_t (*evt_init)(u32_t, u32_t, const char_t *);
u32p_t (*evt_set)(os_evt_id_t, u32_t, u32_t, u32_t);
u32p_t (*evt_wait)(os_evt_id_t, u32_t *, u32_t, u32_t, u32_t);
u32p_t (*evt_wait)(os_evt_id_t, os_evt_val_t *, u32_t, u32_t, u32_t, u32_t);

os_msgq_id_t (*msgq_init)(const void *, u16_t, u16_t, const char_t *);
u32p_t (*msgq_put)(os_msgq_id_t, const u8_t *, u16_t, b_t, u32_t);
Expand Down
2 changes: 1 addition & 1 deletion include/kernal/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern "C" {
u32_t _impl_event_os_id_to_number(os_id_t id);
os_id_t _impl_event_init(u32_t edgeMask, u32_t clearMask, const char_t *pName);
u32p_t _impl_event_set(os_id_t id, u32_t set, u32_t clear, u32_t toggle);
u32p_t _impl_event_wait(os_id_t id, u32_t *pData, u32_t desired, u32_t listen, u32_t timeout_ms);
u32p_t _impl_event_wait(os_id_t id, os_evt_val_t *pEvtData, u32_t desired_val, u32_t listen_mask, u32_t group_mask, u32_t timeout_ms);

#ifdef __cplusplus
}
Expand Down
17 changes: 10 additions & 7 deletions include/kernal/kstruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,17 @@ typedef struct {
} pool_context_t;

typedef struct {
/* The event last value */
u32_t last;
/* the desired bits*/
u32_t desired;

/* Current thread listen which bits in the event */
/* the listen bits*/
u32_t listen;

/* If the trigger is not zero, All changed bits seen can wake up the thread to handle event */
u32_t desired;
/* If the group bits are not zero, all correspond changed bits seen can wake up the thread to handle event */
u32_t group;

/* The value store which bits store until it's meet with the group setting it's can be clean */
u32_t *pEvtData;
/* The user value pointer, the user only can access it until it meets with the group setting so that it can be clean */
os_evt_val_t *pEvtVal;
} action_event_t;

typedef struct {
Expand All @@ -149,6 +149,9 @@ typedef struct {
/* The event value */
u32_t value;

/* The event defer value */
u32_t defer;

/* Specific the event trigger condition of edge or level. */
u32_t edgeMask;

Expand Down
5 changes: 5 additions & 0 deletions include/kernal/ktype.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ typedef struct os_id os_pool_id_t;
typedef struct os_priority os_priority_t;
typedef struct os_time os_time_t;

typedef struct {
u32_t value;
u32_t defer;
} os_evt_val_t;

#define OS_INVALID_ID_VAL (0xFFFFFFFFu)

#define OS_TIME_INVALID_VAL (0xFFFFFFFFu)
Expand Down
102 changes: 65 additions & 37 deletions kernal/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,15 @@ u32p_t _impl_event_set(os_id_t id, u32_t set, u32_t clear, u32_t toggle)
* @brief Wait a target event.
*
* @param id The event unique id.
* @param pData The pointer of event value.
* @param desired If the desired is not zero, All changed bits seen can wake up the thread to handle event.
* @param listen Current thread listen which bits in the event.
* @param pEvtData The pointer of event value.
* @param desired_val If the desired is not zero, All changed bits seen can wake up the thread to handle event.
* @param listen_mask Current thread listen which bits in the event.
* @param group_mask To define a group event.
* @param timeout_ms The event wait timeout setting.
*
* @return The result of the operation.
*/
u32p_t _impl_event_wait(os_id_t id, u32_t *pEvtData, u32_t desired, u32_t listen, u32_t timeout_ms)
u32p_t _impl_event_wait(os_id_t id, os_evt_val_t *pEvtData, u32_t desired_val, u32_t listen_mask, u32_t group_mask, u32_t timeout_ms)
{
if (_event_id_isInvalid(id)) {
return _PC_CMPT_FAILED;
Expand All @@ -246,8 +247,8 @@ u32p_t _impl_event_wait(os_id_t id, u32_t *pEvtData, u32_t desired, u32_t listen
}

arguments_t arguments[] = {
[0] = {.u32_val = (u32_t)id}, [1] = {.u32_val = (u32_t)pEvtData}, [2] = {.u32_val = (u32_t)desired},
[3] = {.u32_val = (u32_t)listen}, [4] = {.u32_val = (u32_t)timeout_ms},
[0] = {.u32_val = (u32_t)id}, [1] = {.pv_val = (void *)pEvtData}, [2] = {.u32_val = (u32_t)desired_val},
[3] = {.u32_val = (u32_t)listen_mask}, [4] = {.u32_val = (u32_t)group_mask}, [5] = {.u32_val = (u32_t)timeout_ms},
};

u32p_t postcode = _impl_kernal_privilege_invoke((const void *)_event_wait_privilege_routine, arguments);
Expand Down Expand Up @@ -335,8 +336,9 @@ static u32_t _event_set_privilege_routine(arguments_t *pArgs)
u32p_t postcode = PC_SC_SUCCESS;
event_context_t *pCurEvent = NULL;
u32_t value = 0u;
u32_t change = 0u;
u32_t trigger = 0u;
u32_t defer = 0u;
u32_t report = 0u;
u32_t reported = 0u;

pCurEvent = _event_object_contextGet(id);

Expand All @@ -347,46 +349,47 @@ static u32_t _event_set_privilege_routine(arguments_t *pArgs)
value |= set;
/* toggle bits */
value ^= toggle;
change = (u32_t)(value ^ pCurEvent->value);

/* edge trigger */
trigger = (u32_t)(change & pCurEvent->edgeMask);
/* Calculate defer bits */
defer = pCurEvent->defer;
defer |= (u32_t)(value ^ pCurEvent->value);

/* level trigger */
trigger |= (u32_t)(value & (~pCurEvent->edgeMask));
/* Calculate triggered report bits */
report = (u32_t)(defer & pCurEvent->edgeMask); // Edge trigger
report |= (u32_t)(value & (~pCurEvent->edgeMask)); // Level trigger

list_iterator_t it = {0u};
list_iterator_init(&it, _event_list_blockingHeadGet(id));
thread_context_t *pCurThread = (thread_context_t *)list_iterator_next(&it);
while (pCurThread) {
b_t isTrigger = FALSE;

*pCurThread->event.pEvtData |= (u32_t)(trigger & pCurThread->event.listen);

if (pCurThread->event.desired) {
if (pCurThread->event.desired == (*pCurThread->event.pEvtData & pCurThread->event.desired)) {
/* Group trigger */
isTrigger = TRUE;
}
} else {
if (*pCurThread->event.pEvtData) {
/* Single trigger */
isTrigger = TRUE;
u32_t unreported = ~(report ^ pCurThread->event.desired) & pCurThread->event.listen;

if (unreported) {
pCurThread->event.pEvtVal->value |= unreported;
reported |= unreported;

if (pCurThread->event.group) { // Group event
if (pCurThread->event.group == (pCurThread->event.pEvtVal->value & pCurThread->event.group)) {
_impl_kernal_thread_entry_trigger(pCurThread->head.id, id, PC_SC_SUCCESS, _event_schedule);
}
} else {
if (pCurThread->event.pEvtVal->value) { // Single event
_impl_kernal_thread_entry_trigger(pCurThread->head.id, id, PC_SC_SUCCESS, _event_schedule);
}
}
}

if (isTrigger) {
postcode = _impl_kernal_thread_entry_trigger(pCurThread->head.id, id, PC_SC_SUCCESS, _event_schedule);
}

if (PC_IER(postcode)) {
break;
}
pCurThread = (thread_context_t *)list_iterator_next(&it);
}

pCurEvent->value = value;
pCurEvent->value &= ~(trigger & pCurEvent->clearMask);
pCurEvent->value &= ~(reported & pCurEvent->clearMask); // Clear reported value

pCurEvent->defer = defer;
pCurEvent->defer &= ~reported; // Clear reported defer

EXIT_CRITICAL_SECTION();
return postcode;
Expand All @@ -404,18 +407,43 @@ static u32_t _event_wait_privilege_routine(arguments_t *pArgs)
ENTER_CRITICAL_SECTION();

os_id_t id = (os_id_t)pArgs[0].u32_val;
u32_t *pEvtData = (u32_t *)pArgs[1].u32_val;
u32_t trigger = (u32_t)pArgs[2].u32_val;
os_evt_val_t *pEvtData = (os_evt_val_t *)pArgs[1].pv_val;
u32_t desired = (u32_t)pArgs[2].u32_val;
u32_t listen = (u32_t)pArgs[3].u32_val;
u32_t timeout_ms = (u32_t)pArgs[4].u32_val;
u32_t group = (u32_t)pArgs[4].u32_val;
u32_t timeout_ms = (u32_t)pArgs[5].u32_val;
thread_context_t *pCurThread = NULL;
event_context_t *pCurEvent = NULL;
u32_t report = 0u;
u32_t reported = 0u;
u32p_t postcode = PC_SC_SUCCESS;

pCurEvent = _event_object_contextGet(id);
pCurThread = _impl_kernal_thread_runContextGet();
pCurThread->event.listen = listen;
pCurThread->event.desired = trigger;
pCurThread->event.pEvtData = pEvtData;
*pCurThread->event.pEvtData = 0u;
pCurThread->event.desired = desired;
pCurThread->event.group = group;
pCurThread->event.pEvtVal = pEvtData;

report = (u32_t)(pCurEvent->defer & pCurEvent->edgeMask); // Edge trigger
report |= (u32_t)(pCurEvent->value & (~pCurEvent->edgeMask)); // Level trigger

reported = ~(report ^ desired) & listen;
if (reported) {
pCurThread->event.pEvtVal->value = reported;
pCurEvent->defer &= ~reported; // Clear reported defer
pCurEvent->value &= ~(reported & pCurEvent->clearMask); // Clear reported value

if (!group) {
EXIT_CRITICAL_SECTION();
return postcode;
}

if (group == (reported & group)) {
EXIT_CRITICAL_SECTION();
return postcode;
}
}

postcode =
_impl_kernal_thread_exit_trigger(pCurThread->head.id, id, _event_list_blockingHeadGet(id), timeout_ms, _event_callback_fromTimeOut);
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "At-RTOS",
"homepage": "https://github.com/At-EC/At-RTOS",
"version": "1.4.2",
"timestamp": "2024-04-07,19:46",
"commit_id": "a1de4de44baf2966f49181ce2133bc32ffe9855a"
"version": "1.4.3",
"timestamp": "2024-04-13,19:11",
"commit_id": "4f5dfd03d8433e97030797e30c45f746b06a33a8"
}

0 comments on commit 15ae539

Please sign in to comment.