Skip to content

Commit 186e0c0

Browse files
committed
CM: Applications can now handle process events
Applications can register handler function for specific process events. These functions will be called before the library handler routines for that event.
1 parent 369e343 commit 186e0c0

File tree

6 files changed

+75
-32
lines changed

6 files changed

+75
-32
lines changed

include/cm/cm.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include <types.h>
1212
#include <stdarg.h>
13-
#if defined(KERNEL) || defined (UNITTEST)
13+
#if defined(KERNEL) || defined(UNITTEST)
1414
#include <cm/osif.h>
1515
#include <cm/syscall.h>
1616
#else
@@ -36,7 +36,6 @@ void cm_delay (UINT ms);
3636
***************************************************************************************************/
3737
INT cm_thread_create (void (*startLocation)(), bool isKernelMode);
3838
INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode);
39-
bool cm_process_is_yield_requested();
4039

4140
static inline void cm_process_yield()
4241
{
@@ -57,3 +56,10 @@ static inline void* cm_process_get_datamem_start()
5756
{
5857
return (void*)syscall (OSIF_SYSCALL_PROCESS_GET_DATAMEM_START, 0, 0, 0, 0, 0);
5958
}
59+
60+
/***************************************************************************************************
61+
* Handling of process events
62+
***************************************************************************************************/
63+
typedef void (*cm_event_handler)(OSIF_ProcessEvent const * const);
64+
bool cm_process_register_event_handler(OSIF_ProcessEvents event, cm_event_handler h);
65+
bool cm_process_handle_events();

include/cm/err.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919

2020
typedef enum CMErrors {
2121
// OS Errors start from 0 and must end before the start of library errors
22-
LIBRARY_ERRORS_START = 100,
23-
CM_ERR_INVALID_INPUT = 100,
22+
LIBRARY_ERRORS_START = 100,
23+
CM_ERR_INVALID_INPUT = 100,
24+
CM_ERR_EVENT_HANDLER_ALREADY_REGISTERED = 101,
2425
} CMErrors;
2526

2627
extern uint32_t cm_error_num__;

include/cm/osif.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ typedef enum OSIF_SYSCALLS {
3737
typedef enum OSIF_ProcessEvents {
3838
OSIF_PROCESS_EVENT_NONE = 0,
3939
OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ = 1,
40-
OSIF_PROCESS_EVENT_PROCCESS_CHILD_KILLED = 2
40+
OSIF_PROCESS_EVENT_PROCCESS_CHILD_KILLED = 2,
41+
OSIF_PROCESS_EVENTS_COUNT
4142
} OSIF_ProcessEvents;
4243

4344
typedef struct OSIF_ProcessEvent {

src/apps/gui0.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ void proc_main()
3333
cm_thread_create (&thread0, false);
3434

3535
while (1) {
36-
if (cm_process_is_yield_requested()) {
37-
cm_process_yield();
38-
}
36+
cm_process_handle_events();
3937
}
4038
}
4139

src/cm/cm.c

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,6 @@ uint32_t cm_error_num__;
1414

1515
#define cm_MICRODEC_TO_TICK_COUNT(us) ((us) / cm_get_tick_period_us())
1616

17-
void event_handler_NDU_()
18-
{
19-
volatile OSIF_ProcessEvent e = { 0 };
20-
cm_process_pop_event ((OSIF_ProcessEvent*)&e);
21-
switch (e.event) {
22-
case OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ:
23-
cm_process_yield();
24-
break;
25-
case OSIF_PROCESS_EVENT_PROCCESS_CHILD_KILLED:
26-
CM_DBG_INFO ("Child exitted with code: %x", e.data);
27-
break;
28-
case OSIF_PROCESS_EVENT_NONE:
29-
break;
30-
}
31-
}
32-
3317
void cm_delay (UINT ms)
3418
{
3519
UINT us = ms * 1000;
@@ -38,6 +22,6 @@ void cm_delay (UINT ms)
3822
U32 end_tick = start_tick + cm_MICRODEC_TO_TICK_COUNT (us);
3923

4024
while (cm_get_tickcount() < end_tick) {
41-
event_handler_NDU_();
25+
cm_process_handle_events();
4226
}
4327
}

src/cm/process.c

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,66 @@
77
#include <process.h>
88
#include <cm/syscall.h>
99
#include <cm/err.h>
10+
#include <cm/cm.h>
11+
#include <stdbool.h>
12+
13+
/***************************************************************************************************
14+
* Handling of process events
15+
* Some events are handled automaticaly by the library while others are for the applications to
16+
* handle. The applications can register a hander function for each event and those will be called
17+
* when the associated event is read.
18+
*
19+
* Not that though every thread receives events, the application event handler function is common
20+
* and is shared by every thread & the parent process. Per thread handling of events can be
21+
* done by quering process id.
22+
***************************************************************************************************/
23+
static cm_event_handler app_event_handlers[OSIF_PROCESS_EVENTS_COUNT] = { 0 };
24+
25+
bool cm_process_register_event_handler (OSIF_ProcessEvents e, cm_event_handler h)
26+
{
27+
if (app_event_handlers[e] != NULL) {
28+
CM_RETURN_ERROR__ (CM_ERR_EVENT_HANDLER_ALREADY_REGISTERED, false);
29+
}
30+
31+
app_event_handlers[e] = h;
32+
return true;
33+
}
34+
35+
/***************************************************************************************************
36+
* Default handler for process events
37+
*
38+
* Note:
39+
* Since its upto each process to read their events queue and handle them,
40+
* it is important that cm_process_handle_events() gets called regularly.
41+
**************************************************************************************************/
42+
bool cm_process_handle_events()
43+
{
44+
volatile OSIF_ProcessEvent e = { 0 };
45+
if (!cm_process_pop_event ((OSIF_ProcessEvent*)&e)) {
46+
CM_RETURN_ERROR__ (cm_get_os_error(), false);
47+
}
48+
49+
switch (e.event) {
50+
case OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ:
51+
if (app_event_handlers[e.event]) {
52+
app_event_handlers[e.event]((const OSIF_ProcessEvent* const)&e);
53+
}
54+
cm_process_yield();
55+
break;
56+
case OSIF_PROCESS_EVENT_PROCCESS_CHILD_KILLED:
57+
if (app_event_handlers[e.event]) {
58+
app_event_handlers[e.event]((const OSIF_ProcessEvent* const)&e);
59+
}
60+
break;
61+
case OSIF_PROCESS_EVENT_NONE:
62+
break;
63+
default:
64+
// TODO: Should panic! and kill the process
65+
break;
66+
}
67+
return true;
68+
}
69+
/**************************************************************************************************/
1070

1171
INT cm_process_create (void* startLocation, SIZE binaryLengthBytes, bool isKernelMode)
1272
{
@@ -44,10 +104,3 @@ INT cm_thread_create (void (*startLocation)(), bool isKernelMode)
44104
}
45105
return pid;
46106
}
47-
48-
bool cm_process_is_yield_requested()
49-
{
50-
volatile OSIF_ProcessEvent e = { 0 };
51-
cm_process_pop_event ((OSIF_ProcessEvent*)&e);
52-
return (e.event == OSIF_PROCESS_EVENT_PROCCESS_YIELD_REQ);
53-
}

0 commit comments

Comments
 (0)