Skip to content

Commit

Permalink
microkernel: introduce private event objects
Browse files Browse the repository at this point in the history
This patch enables defining microkernel events within source code.
This is similar to other private kernel object patches.

The test has been modified a little bit due to the fact that
the event ID is now a memory address, instead of numeric ID.

Change-Id: Ie3c8d4f4e459d9c631e50bb242cf7a05ca8ea82c
Signed-off-by: Daniel Leung <[email protected]>
Signed-off-by: Anas Nashif <[email protected]>
  • Loading branch information
dcpleung authored and nashif committed Feb 6, 2016
1 parent 3657987 commit 851c6f8
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 67 deletions.
8 changes: 8 additions & 0 deletions include/arch/arm/cortex_m/scripts/linker.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ SECTIONS
_k_mem_map_ptr_end = .;
} GROUP_LINK_IN(RAMABLE_REGION)

SECTION_PROLOGUE(_k_event_list, (OPTIONAL),)
{
_k_event_list_start = .;
*(._k_event_list.event.*)
KEEP(*(SORT_BY_NAME("._k_event_list*")))
_k_event_list_end = .;
} GROUP_LINK_IN(RAMABLE_REGION)

__data_ram_end = .;

SECTION_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
Expand Down
8 changes: 8 additions & 0 deletions include/arch/x86/linker-common-sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ SECTIONS
_k_mem_map_ptr_end = .;
} GROUP_LINK_IN(RAM)

SECTION_PROLOGUE(_k_event_list, (OPTIONAL),)
{
_k_event_list_start = .;
*(._k_event_list.event.*)
KEEP(*(SORT_BY_NAME("._k_event_list*")))
_k_event_list_end = .;
} GROUP_LINK_IN(RAM)

__data_ram_end = .;

SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD OPTIONAL),)
Expand Down
6 changes: 6 additions & 0 deletions include/microkernel/base_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ struct _k_mem_map_struct {
#endif
};

struct _k_event_struct {
int status;
kevent_handler_t func;
struct k_args *waiter;
int count;
};

#ifdef CONFIG_DEBUG_TRACING_KERNEL_OBJECTS
struct _k_mbox_struct *_track_list_micro_mbox;
Expand Down
25 changes: 24 additions & 1 deletion include/microkernel/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ extern "C" {
#include <microkernel/command_packet.h>

/* well-known events */
extern const kevent_t TICK_EVENT;

#define TICK_EVENT 0
/**
* @cond internal
*/
Expand Down Expand Up @@ -159,6 +159,29 @@ extern int task_event_send(kevent_t event);
* @}
*/

#define _K_EVENT_INITIALIZER(handler) \
{ \
.status = 0, \
.func = (kevent_handler_t)handler, \
.waiter = NULL, \
.count = 0, \
}

/**
* @brief Define a private microkernel event
*
* This declares and initializes a private event. The new event
* can be passed to the microkernel event functions.
*
* @param name Name of the event
* @param handler Function to handle the event (can be NULL)
*/
#define DEFINE_EVENT(name, handler) \
struct _k_event_struct _k_event_obj_##name \
__in_section(_k_event_list, event, name) = \
_K_EVENT_INITIALIZER(handler); \
const kevent_t name = (kevent_t)&_k_event_obj_##name;

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 0 additions & 2 deletions kernel/microkernel/include/micro_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ extern struct pool_struct _k_mem_pool_list[];

extern int _k_mem_pool_count;

extern const int _k_num_events;

extern struct k_task *_k_current_task;
extern uint32_t _k_task_priority_bitmap[];

Expand Down
7 changes: 0 additions & 7 deletions kernel/microkernel/include/micro_private_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,13 +421,6 @@ struct pool_struct {
struct pool_struct *_track_list_micro_mem_pool;
#endif

struct evstr {
int status;
kevent_handler_t func;
struct k_args *waiter;
int count;
};

#ifdef __cplusplus
}
#endif
Expand Down
14 changes: 6 additions & 8 deletions kernel/microkernel/k_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
#include <toolchain.h>
#include <sections.h>

extern struct evstr _k_event_list[];
extern kevent_t _k_event_list_start[];
extern kevent_t _k_event_list_end[];

/**
*
Expand All @@ -34,8 +35,7 @@ extern struct evstr _k_event_list[];
*/
void _k_event_handler_set(struct k_args *A)
{
kevent_t event = A->args.e1.event;
struct evstr *E = _k_event_list + event;
struct _k_event_struct *E = (struct _k_event_struct *)A->args.e1.event;

if (E->func != NULL) {
if (likely(A->args.e1.func == NULL)) {
Expand Down Expand Up @@ -73,8 +73,7 @@ int task_event_handler_set(kevent_t event, kevent_handler_t handler)
*/
void _k_event_test_timeout(struct k_args *A)
{
kevent_t event = A->args.e1.event;
struct evstr *E = _k_event_list + event;
struct _k_event_struct *E = (struct _k_event_struct *)A->args.e1.event;

FREETIMER(A->Time.timer);
A->Time.rcode = RC_TIME;
Expand All @@ -90,8 +89,7 @@ void _k_event_test_timeout(struct k_args *A)
*/
void _k_event_test(struct k_args *A)
{
kevent_t event = A->args.e1.event;
struct evstr *E = _k_event_list + event;
struct _k_event_struct *E = (struct _k_event_struct *)A->args.e1.event;

if (E->status) { /* the next event can be received */
E->status = 0;
Expand Down Expand Up @@ -145,7 +143,7 @@ int _task_event_recv(kevent_t event, int32_t time)
*/
void _k_do_event_signal(kevent_t event)
{
struct evstr *E = _k_event_list + event;
struct _k_event_struct *E = (struct _k_event_struct *)event;
struct k_args *A = E->waiter;
int ret_val = 1; /* If no handler is available, then ret_val is 1 by default */

Expand Down
7 changes: 3 additions & 4 deletions kernel/microkernel/k_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ extern void _irq_disconnect(unsigned int irq);
#error "Unknown target"
#endif

/* event id used by first task IRQ object */

extern const kevent_t _TaskIrqEvt0_objId;
/* array of event id used by task IRQ objects */
extern const kevent_t _TaskIrqEvt_objIds[];

/**
*
Expand Down Expand Up @@ -200,7 +199,7 @@ static int _k_task_irq_alloc(void *arg)
irq_obj_ptr = &task_irq_object[argp->irq_obj];
irq_obj_ptr->task_id = argp->task_id;
irq_obj_ptr->irq = argp->irq;
irq_obj_ptr->event = (_TaskIrqEvt0_objId + argp->irq_obj);
irq_obj_ptr->event = _TaskIrqEvt_objIds[argp->irq_obj];
irq_obj_ptr->vector = INVALID_VECTOR;

return (int)irq_obj_ptr;
Expand Down
6 changes: 4 additions & 2 deletions kernel/microkernel/k_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <drivers/system_timer.h>

extern const kernelfunc _k_server_dispatch_table[];
extern kevent_t _k_event_list_start[];
extern kevent_t _k_event_list_end[];

/**
*
Expand Down Expand Up @@ -99,9 +101,9 @@ FUNC_NORETURN void _k_server(int unused1, int unused2)
&_k_command_stack); /* will schedule */
do {
kevent_t event;
/* if event < _k_num_events, it's a well-known event */
event = (kevent_t)(pArgs);
if (event < (kevent_t)_k_num_events) {
if ((event >= (kevent_t)_k_event_list_start) &&
(event < (kevent_t)_k_event_list_end)) {
#ifdef CONFIG_TASK_MONITOR
if (_k_monitor_mask & MON_EVENT) {
_k_task_monitor_args(pArgs);
Expand Down
6 changes: 4 additions & 2 deletions kernel/microkernel/k_task_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ static int K_monitor_wind;

k_task_monitor_hook_t _k_task_switch_callback;

extern const int _k_num_events;
extern kevent_t _k_event_list_start[];
extern kevent_t _k_event_list_end[];

void task_monitor_hook_set(k_task_monitor_hook_t func)
{
Expand Down Expand Up @@ -74,7 +75,8 @@ void _k_task_monitor_args(struct k_args *A)
{
k_monitor_wptr->time = _sys_clock_cycle_get();

if ((uint32_t)A < _k_num_events) {
if (((kevent_t)A >= (kevent_t)_k_event_list_start) &&
((kevent_t)A < (kevent_t)_k_event_list_end)) {
k_monitor_wptr->data2 = MO_EVENT | (uint32_t)A;
} else {
k_monitor_wptr->data1 = _k_current_task->id;
Expand Down
5 changes: 3 additions & 2 deletions samples/microkernel/test/test_events/src/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static int handlerRetVal = 0;
extern void testFiberInit(void);
extern struct nano_sem fiberSem; /* semaphore that allows test control the fiber */

extern const int _k_num_events; /* non-public microkernel global variable */
extern kevent_t _k_event_list_end[];

/**
*
Expand Down Expand Up @@ -391,7 +391,8 @@ int eventSignalHandlerTest(void)
int rv; /* return value from task_event_xxx() calls */

/* Expect this call to task_event_handler_set() to fail */
rv = task_event_handler_set(EVENT_ID + 10, eventHandler);
rv = task_event_handler_set((uint32_t)_k_event_list_end + 10,
eventHandler);
if (rv != RC_FAIL) {
TC_ERROR("task_event_handler_set() returned %d not %d\n",
rv, RC_FAIL);
Expand Down
2 changes: 1 addition & 1 deletion scripts/sanitycheck
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class SizeCalculator:

alloc_sections = ["bss", "noinit"]
rw_sections = ["datas", "initlevel", "_k_mem_map_ptr", "_k_pipe_ptr",
"_k_task_ptr", "_k_task_list", "initlevel"]
"_k_task_ptr", "_k_task_list", "initlevel", "_k_event_list"]
# These get copied into RAM only on non-XIP
ro_sections = ["text", "ctors", "rodata", "devconfig"]

Expand Down
64 changes: 26 additions & 38 deletions scripts/sysgen
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import subprocess
num_kargs = 0
num_timers = 0
num_prios = 0
num_task_irqs = 0

task_list = []
event_list = []
Expand Down Expand Up @@ -424,47 +425,32 @@ def kernel_main_c_priorities():
def kernel_main_c_events():
""" Generate event variables """

total_events = 4 + len(event_list)
global num_task_irqs

# event descriptors

kernel_main_c_out("\n" +
"struct evstr _k_event_list[%d] =\n" % (total_events) +
"{\n")
# pre-defined events
# pre-defined event for timer
if (num_timers > 0):
kernel_main_c_out(
" {0, (kevent_handler_t)_k_ticker, " +
"(struct k_args *)NULL, 0},\n")
kernel_main_c_out("DEFINE_EVENT(TICK_EVENT, _k_ticker);\n")
else:
kernel_main_c_out(
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n")
kernel_main_c_out(
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n" +
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n" +
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n"
)
kernel_main_c_out("DEFINE_EVENT(TICK_EVENT, NULL);\n")

# project-specific events
for event in event_list:
kernel_main_c_out(
" {0, (kevent_handler_t)%s, (struct k_args *)NULL, 0},\n" %
(event[1]))
kernel_main_c_out("};\n")

# number of events

kernel_main_c_out("\n" +
"const int _k_num_events = %d;\n" % (total_events))
kernel_main_c_out("DEFINE_EVENT(%s, %s);\n" % (event[0], event[1]))

# event object identifiers (for project-defined events only)
if (event[0].startswith("_TaskIrqEvt")):
num_task_irqs += 1

if (len(event_list) > 0):
kernel_main_c_out("\n")
if (num_task_irqs > 0):
kernel_main_c_out("const kevent_t _TaskIrqEvt_objIds[] = {\n")

for event_name in event_list:
for i in range(0, num_task_irqs):
kernel_main_c_out(
"const kevent_t %s_objId = %s;\n" %
(event_name[0], event_name[0]))
" (kevent_t)&_k_event_obj__TaskIrqEvt%d,\n" % (i)
)

kernel_main_c_out("};\n")


def kernel_main_c_mutexes():
Expand Down Expand Up @@ -877,14 +863,7 @@ def generate_obj_id_lines(obj_types):
def generate_sysgen_h_obj_ids():

global sysgen_h_data

base_event = 4 # no need to generate ids for the 4 pre-defined events
event_id = base_event
for event in event_list:
sysgen_h_data += "#define %s %u\n" % (str(event[0]), event_id)
event_id += 1
if event_id > base_event:
sysgen_h_data += "\n"
global num_task_irqs

# mutex object ids

Expand Down Expand Up @@ -949,6 +928,15 @@ def generate_sysgen_h_obj_ids():
"extern struct k_task _k_task_obj_%s;\n" % (name) + \
"#define %s ((ktask_t)&_k_task_obj_%s)\n" % (name, name)

# event object id

sysgen_h_data += "\n"
for event in event_list:
# no need to expose the irq task events
if not (event[0].startswith("_TaskIrqEvt")):
name = event[0];
sysgen_h_data += \
"extern const kevent_t %s;\n" % (name)

# all other object ids

Expand Down

0 comments on commit 851c6f8

Please sign in to comment.