Skip to content

Commit c0bb696

Browse files
committed
Fix #540, add OSAL event framework
Define an interface to allow an app/PSP to be notified when state changes or other events occur at the OS level. Initially defined events are resource creation/deletion and task startup. The interface is easily extendable with more events as needed. This can be used to add platform-specific/nonstandard functions by putting the code inside the event handler at the PSP level.
1 parent 53b25f4 commit c0bb696

File tree

6 files changed

+199
-1
lines changed

6 files changed

+199
-1
lines changed

src/os/inc/osapi-os-core.h

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,75 @@ typedef enum
173173
OS_STREAM_STATE_WRITABLE = 0x08, /**< @brief whether the stream is writable */
174174
} OS_StreamState_t;
175175

176+
/**
177+
* @brief A set of events that can be used with event callback routines
178+
*/
179+
typedef enum
180+
{
181+
OS_EVENT_RESERVED = 0, /**< no-op/reserved event id value */
182+
183+
/**
184+
* resource/id has been newly allocated but not yet created.
185+
*
186+
* This event is invoked from WITHIN the locked region, in
187+
* the context of the task which is allocating the resource.
188+
*
189+
* If the handler returns non-success, the error will be returned
190+
* to the caller and the creation process is aborted.
191+
*/
192+
OS_EVENT_RESOURCE_ALLOCATED,
193+
194+
/**
195+
* resource/id has been fully created/finalized.
196+
*
197+
* Invoked outside locked region, in the context
198+
* of the task which created the resource.
199+
*
200+
* Data object is not used, passed as NULL.
201+
*
202+
* Return value is ignored - this is for information purposes only.
203+
*/
204+
OS_EVENT_RESOURCE_CREATED,
205+
206+
/**
207+
* resource/id has been deleted.
208+
*
209+
* Invoked outside locked region, in the context
210+
* of the task which deleted the resource.
211+
*
212+
* Data object is not used, passed as NULL.
213+
*
214+
* Return value is ignored - this is for information purposes only.
215+
*/
216+
OS_EVENT_RESOURCE_DELETED,
217+
218+
/**
219+
* New task is starting.
220+
*
221+
* Invoked outside locked region, in the context
222+
* of the task which is currently starting, before
223+
* the entry point is called.
224+
*
225+
* Data object is not used, passed as NULL.
226+
*
227+
* If the handler returns non-success, task startup is aborted
228+
* and the entry point is not called.
229+
*/
230+
OS_EVENT_TASK_STARTUP,
231+
232+
OS_EVENT_MAX /**< placeholder for end of enum, not used */
233+
} OS_Event_t;
234+
235+
/**
236+
* @brief A callback routine for event handling.
237+
*
238+
* @param[in] event The event that occurred
239+
* @param[in] object_id The associated object_id, or 0 if not associated with an object
240+
* @param[inout] data An abstract data/context object associated with the event, or NULL.
241+
* @return status Execution status, see @ref OSReturnCodes.
242+
*/
243+
typedef int32 (*OS_EventHandler_t)(OS_Event_t event, uint32 object_id, void *data);
244+
176245
/**
177246
* @brief For the @ref OS_GetErrorName() function, to ensure
178247
* everyone is making an array of the same length.
@@ -360,7 +429,6 @@ int32 OS_ConvertToArrayIndex (uint32 object_id, uint32 *ArrayIndex);
360429
* @param[in] callback_arg Opaque Argument to pass to callback function
361430
*/
362431
void OS_ForEachObject (uint32 creator_id, OS_ArgCallback_t callback_ptr, void *callback_arg);
363-
/**@}*/
364432

365433
/*-------------------------------------------------------------------------------------*/
366434
/**
@@ -377,6 +445,26 @@ void OS_ForEachObject (uint32 creator_id, OS_ArgCallback_t callback_pt
377445
*/
378446
void OS_ForEachObjectOfType (uint32 objtype, uint32 creator_id, OS_ArgCallback_t callback_ptr, void *callback_arg);
379447

448+
/*-------------------------------------------------------------------------------------*/
449+
/**
450+
* @brief Callback routine registration
451+
*
452+
* This hook enables the application code to perform extra platform-specific
453+
* operations on various system events such as resource creation/deletion.
454+
*
455+
* @note Some events are invoked while the resource is "locked" and therefore
456+
* application-defined handlers for these events should not block or attempt
457+
* to access other OSAL resources.
458+
*
459+
* @param[in] handler The application-provided event handler
460+
* @return Execution status, see @ref OSReturnCodes.
461+
* @retval #OS_SUCCESS @copybrief OS_SUCCESS
462+
* @retval #OS_ERROR @copybrief OS_ERROR
463+
*/
464+
int32 OS_RegisterEventHandler (OS_EventHandler_t handler);
465+
466+
/**@}*/
467+
380468

381469
/** @defgroup OSAPITask OSAL Task APIs
382470
* @{

src/os/shared/inc/os-shared-common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ struct OS_shared_global_vars
5757
int32 MicroSecPerTick;
5858
int32 TicksPerSecond;
5959

60+
/*
61+
* The event handler is an application-defined callback
62+
* that gets invoked as resources are created/configured/deleted.
63+
*/
64+
OS_EventHandler_t EventHandler;
65+
6066
#ifdef OSAL_CONFIG_DEBUG_PRINTF
6167
uint8 DebugLevel;
6268
#endif
@@ -69,6 +75,16 @@ struct OS_shared_global_vars
6975
*/
7076
extern OS_SharedGlobalVars_t OS_SharedGlobalVars;
7177

78+
/*---------------------------------------------------------------------------------------
79+
Name: OS_NotifyEvent
80+
81+
Purpose: Notify the user application of a change in the state of an OSAL resource
82+
83+
returns: OS_SUCCESS on success, or relevant error code
84+
---------------------------------------------------------------------------------------*/
85+
int32 OS_NotifyEvent(OS_Event_t event, uint32 object_id, void *data);
86+
87+
7288
/*---------------------------------------------------------------------------------------
7389
Name: OS_API_Impl_Init
7490

src/os/shared/src/osapi-common.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,36 @@ OS_SharedGlobalVars_t OS_SharedGlobalVars =
6565
.ShutdownFlag = 0,
6666
.MicroSecPerTick = 0, /* invalid, _must_ be set by implementation init */
6767
.TicksPerSecond = 0, /* invalid, _must_ be set by implementation init */
68+
.EventHandler = NULL,
6869
#if defined(OSAL_CONFIG_DEBUG_PRINTF)
6970
.DebugLevel = 1,
7071
#endif
7172
};
7273

74+
75+
/*----------------------------------------------------------------
76+
*
77+
* Function: OS_NotifyEvent
78+
*
79+
* Purpose: Helper function to invoke the user-defined event handler
80+
*
81+
*-----------------------------------------------------------------*/
82+
int32 OS_NotifyEvent(OS_Event_t event, uint32 object_id, void *data)
83+
{
84+
int32 status;
85+
86+
if (OS_SharedGlobalVars.EventHandler != NULL)
87+
{
88+
status = OS_SharedGlobalVars.EventHandler(event, object_id, data);
89+
}
90+
else
91+
{
92+
status = OS_SUCCESS;
93+
}
94+
95+
return status;
96+
}
97+
7398
/*
7499
*********************************************************************************
75100
* PUBLIC API (application-callable functions)
@@ -199,6 +224,24 @@ int32 OS_API_Init(void)
199224
return(return_code);
200225
} /* end OS_API_Init */
201226

227+
/*----------------------------------------------------------------
228+
*
229+
* Function: OS_RegisterEventHandler
230+
*
231+
* Purpose: Implemented per public OSAL API
232+
* See description in API and header file for detail
233+
*
234+
*-----------------------------------------------------------------*/
235+
int32 OS_RegisterEventHandler (OS_EventHandler_t handler)
236+
{
237+
if (handler == NULL)
238+
{
239+
return OS_INVALID_POINTER;
240+
}
241+
242+
OS_SharedGlobalVars.EventHandler = handler;
243+
return OS_SUCCESS;
244+
}
202245

203246
/*----------------------------------------------------------------
204247
*

src/os/shared/src/osapi-idmap.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,12 @@ int32 OS_ObjectIdFinalizeNew(int32 operation_status, OS_common_record_t *record,
766766
/* Either way we must unlock the object type */
767767
OS_Unlock_Global(idtype);
768768

769+
/* Give event callback to the application */
770+
if (operation_status == OS_SUCCESS)
771+
{
772+
OS_NotifyEvent(OS_EVENT_RESOURCE_CREATED, record->active_id, NULL);
773+
}
774+
769775
return operation_status;
770776
} /* end OS_ObjectIdFinalizeNew */
771777

@@ -794,6 +800,12 @@ int32 OS_ObjectIdFinalizeDelete(int32 operation_status, OS_common_record_t *reco
794800
/* Either way we must unlock the object type */
795801
OS_Unlock_Global(idtype);
796802

803+
/* Give event callback to the application */
804+
if (saved_id != 0)
805+
{
806+
OS_NotifyEvent(OS_EVENT_RESOURCE_DELETED, saved_id, NULL);
807+
}
808+
797809
return operation_status;
798810
}
799811

@@ -1078,6 +1090,11 @@ int32 OS_ObjectIdAllocateNew(uint32 idtype, const char *name, uint32 *array_inde
10781090
return_code = OS_ObjectIdFindNext(idtype, array_index, record);
10791091
}
10801092

1093+
if (return_code == OS_SUCCESS)
1094+
{
1095+
return_code = OS_NotifyEvent(OS_EVENT_RESOURCE_ALLOCATED, (*record)->active_id, NULL);
1096+
}
1097+
10811098
/* If allocation failed for any reason, unlock the global.
10821099
* otherwise the global should stay locked so remaining initialization can be done */
10831100
if (return_code != OS_SUCCESS)

src/os/shared/src/osapi-task.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ static int32 OS_TaskPrepare(uint32 task_id, osal_task_entry *entrypt)
120120
return_code = OS_TaskRegister_Impl(task_id);
121121
}
122122

123+
if (return_code == OS_SUCCESS)
124+
{
125+
/* Give event callback to the application */
126+
return_code = OS_NotifyEvent(OS_EVENT_TASK_STARTUP, task_id, NULL);
127+
}
128+
123129
if (return_code != OS_SUCCESS)
124130
{
125131
*entrypt = NULL;

src/ut-stubs/osapi-utstub-common.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,34 @@ int32 OS_API_Init(void)
4949
return status;
5050
}
5151

52+
/*****************************************************************************
53+
*
54+
* Stub function for OS_NotifyEvent()
55+
*
56+
*****************************************************************************/
57+
int32 OS_NotifyEvent(OS_Event_t event, uint32 object_id, void *data)
58+
{
59+
int32 status;
60+
61+
status = UT_DEFAULT_IMPL(OS_NotifyEvent);
62+
63+
return status;
64+
}
65+
66+
/*****************************************************************************
67+
*
68+
* Stub function for OS_RegisterEventHandler()
69+
*
70+
*****************************************************************************/
71+
int32 OS_RegisterEventHandler (OS_EventHandler_t handler)
72+
{
73+
int32 status;
74+
75+
status = UT_DEFAULT_IMPL(OS_RegisterEventHandler);
76+
77+
return status;
78+
}
79+
5280

5381
/*****************************************************************************
5482
*

0 commit comments

Comments
 (0)