[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/hsm/os/erika2/include/os/os_config.h b/src/bsp/hsm/os/erika2/include/os/os_config.h
new file mode 100644
index 0000000..d7e4bdc
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/include/os/os_config.h
@@ -0,0 +1,59 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef OS_ERIKA2_INCLUDE_OS_OS_CONFIG_H
+#define OS_ERIKA2_INCLUDE_OS_OS_CONFIG_H
+
+/* IRQ */
+#define OS_ISR1_PRIORITY_TOP 0
+#define OS_ISR1_PRIORITY_BOTTOM 7
+#define OS_ISR2_PRIORITY_TOP 8
+#define OS_ISR2_PRIORITY_BOTTOM 15
+
+#define OS_IRQ_ENABLE (1)
+#define OS_IRQ_DISABLE (0)
+#define OS_IRQ_TRIGGER (0)
+
+/* TIMER */
+#define OS_TIMER_ENABLE (3)
+#define OS_TIMER_DISABLE (0)
+#define OS_TIMER_RESET_VALUE (0)
+#define OS_TIMER_IRQ_PRIORITY OS_ISR2_PRIORITY_BOTTOM
+
+#define OS_TIMER_IRQ (17)
+
+#endif /* OS_ERIKA2_INCLUDE_OS_OS_CONFIG_H */
diff --git a/src/bsp/hsm/os/erika2/include/os/os_tick.h b/src/bsp/hsm/os/erika2/include/os/os_tick.h
new file mode 100644
index 0000000..1b6ba50
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/include/os/os_tick.h
@@ -0,0 +1,53 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef OS_ERIKA2_INCLUDE_OS_OS_TICK_H
+#define OS_ERIKA2_INCLUDE_OS_OS_TICK_H
+
+#include <stdint.h>
+
+/* HSM uses hsm timer as tick source. Others uses core internal timer. */
+#define OS_COUNTER_HZ (26000000UL)
+
+#define OS_TICK_RATE_HZ 1000U
+#define OS_TICK_RATE_MS (1000U / OS_TICK_RATE_HZ)
+#define RTOS_MS_TO_TICK(ms) ((ms) / OS_TICK_RATE_MS)
+
+void os_tick_init(uint32_t hz, uint32_t rate);
+
+#endif /* OS_ERIKA2_INCLUDE_OS_OS_TICK_H */
+
diff --git a/src/bsp/hsm/os/erika2/makefile b/src/bsp/hsm/os/erika2/makefile
new file mode 100644
index 0000000..8fd5d00
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/makefile
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call cur-dir)
+
+ifeq ($(OS_ERIKA2), true)
+
+LOCAL_MODULE := os_erika2
+LOCAL_SRC_FILES := os_tick.c
+LOCAL_C_INCLUDES := ./pkg ./include
+
+ALL_SRCS += $(foreach SRC, $(LOCAL_SRC_FILES:./%=%), $(addprefix $(LOCAL_PATH)/, $(SRC)))
+ALL_INCDIRS += $(foreach INC, $(LOCAL_C_INCLUDES), $(addprefix $(LOCAL_PATH)/, $(INC)))
+
+include $(OS_ROOT)/erika2/pkg/cpu/common/makefile
+include $(OS_ROOT)/erika2/pkg/cpu/arc_em6/makefile
+include $(OS_ROOT)/erika2/pkg/kernel/oo/makefile
+include $(OS_ROOT)/erika2/pkg/test/assert/makefile
+
+endif
diff --git a/src/bsp/hsm/os/erika2/oil/isr.oil b/src/bsp/hsm/os/erika2/oil/isr.oil
new file mode 100644
index 0000000..2f4eab1
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/oil/isr.oil
@@ -0,0 +1,13 @@
+
+
+ISR mbox_isr {
+ CATEGORY = 2; /* 1=internal, 2=standard, 3=trap */
+ ENTRY = "15"; /* interrupt id */
+ PRIORITY = 15;
+};
+
+ISR mcuwdt_isr {
+ CATEGORY = 2;
+ ENTRY = "37";
+ PRIORITY = 15;
+};
diff --git a/src/bsp/hsm/os/erika2/oil/main.oil b/src/bsp/hsm/os/erika2/oil/main.oil
new file mode 100644
index 0000000..ee6b823
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/oil/main.oil
@@ -0,0 +1,9 @@
+
+#include <config.h>
+
+#include "middleware.oil"
+#include "os.oil"
+
+#ifdef __ARC32__
+#include "isr.oil"
+#endif
diff --git a/src/bsp/hsm/os/erika2/oil/middleware.oil b/src/bsp/hsm/os/erika2/oil/middleware.oil
new file mode 100644
index 0000000..d15dfe9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/oil/middleware.oil
@@ -0,0 +1,134 @@
+#include <config.h>
+
+#if CONFIG_SERVICE_CLI == 1
+ TASK cli_io_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 12;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 1024;
+ };
+
+ EVENT = EnableEvent;
+ };
+
+ TASK cli_cmd_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 13;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 2048;
+ };
+
+ EVENT = EnableEvent;
+ };
+
+ TASK cli_mbox_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 15;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 1024;
+ };
+
+ EVENT = EnableEvent;
+ };
+
+ EVENT CLI_EVENT_TYPE_IDLE { MASK = 0x1; };
+ EVENT CLI_EVENT_TYPE_RX { MASK = 0x2; };
+ EVENT CLI_EVENT_TYPE_RX_MBOX { MASK = 0x4; };
+ EVENT CLI_EVENT_TYPE_PROCESS { MASK = 0x8; };
+ EVENT CLI_EVENT_TYPE_RX_REQ { MASK = 0x10; };
+ EVENT CLI_EVENT_TYPE_RX_RSP { MASK = 0x20; };
+#endif
+
+#if CONFIG_HSM_MCUWDT == 1
+ TASK mcuwdt_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 28;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 1024;
+ };
+
+ EVENT = EnableEvent;
+ };
+ EVENT MCUWDT_EVENT { MASK = 0x1; };
+
+ ALARM mcuwdt_alm {
+ COUNTER = ostick;
+ ACTION = SETEVENT {
+ TASK = mcuwdt_task;
+ EVENT = MCUWDT_EVENT;
+ };
+ };
+#endif
+
+#if CONFIG_HSM_CRY_AES_SHA == 1
+ TASK aes_sha_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 28;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 8192;
+ };
+ EVENT = EnableEvent;
+#if CONFIG_HSM_CRYPTO_EX == 1
+ RESOURCE = res_crypto;
+#endif
+ };
+ EVENT AES_SHA_EVENT { MASK = 0x1; };
+#endif
+
+#if CONFIG_HSM_CRY_ECC == 1
+ TASK ecc_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 28;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 8192;
+ };
+ EVENT = EnableEvent;
+ };
+ EVENT ECC_EVENT { MASK = 0x1; };
+#endif
+
+#if CONFIG_HSM_CRY_TRNG == 1
+ TASK trng_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 28;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 8192;
+ };
+ EVENT = EnableEvent;
+ };
+ EVENT TRNG_EVENT { MASK = 0x1; };
+#endif
+
+#if CONFIG_HSM_CRYPTO_EX == 1
+ RESOURCE res_crypto { RESOURCEPROPERTY = STANDARD; };
+#endif
+
+#if CONFIG_HSM_KEY_MANAGEMENT == 1
+ TASK km_task {
+ AUTOSTART = TRUE;
+ ACTIVATION = 1;
+ PRIORITY = 28;
+ SCHEDULE = FULL;
+ STACK = PRIVATE {
+ SYS_SIZE = 8192;
+ };
+
+ EVENT = EnableEvent;
+ };
+ EVENT KEY_MANAGEMENT_EVENT { MASK = 0x1; };
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/oil/os.oil b/src/bsp/hsm/os/erika2/oil/os.oil
new file mode 100644
index 0000000..a18a361
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/oil/os.oil
@@ -0,0 +1,58 @@
+#include <config.h>
+
+OS hsmOS {
+ EE_OPT = "__ARC_EM6__";
+ EE_OPT = "__GNU__";
+
+ MCU_DATA = TRICORE {
+ MODEL = TC27x;
+ };
+
+ CPU_DATA = TRICORE {
+ COMPILER_TYPE = GNU;
+ MULTI_STACK = TRUE {
+ IRQ_STACK = TRUE {
+ SYS_SIZE = 2048;
+ };
+ };
+ };
+
+ STARTUPHOOK = TRUE;
+ ERRORHOOK = TRUE;
+ SHUTDOWNHOOK = TRUE;
+ PRETASKHOOK = TRUE;
+ POSTTASKHOOK = TRUE;
+
+ USEGETSERVICEID = FALSE;
+ USEPARAMETERACCESS = FALSE;
+ USERESSCHEDULER = FALSE;
+
+ STATUS = EXTENDED;
+ KERNEL_TYPE = ECC2;
+};
+
+COUNTER ostick {
+ TICKSPERBASE = 1; // ticks per counter-specific unit
+ MAXALLOWEDVALUE = 1000000000; // the maximum allowed counter value
+ MINCYCLE = 1; // the minimum allowed number of counter ticks for a cyclic alarm
+};
+
+/* build error when no ALARM using ostick COUNTER. Add an empty alarm to
+ * avoid it.
+ */
+ALARM os_alm {
+ COUNTER = ostick;
+ ACTION = ALARMCALLBACK {
+ ALARMCALLBACKNAME = "os_alarm";
+ };
+};
+
+EVENT EnableEvent { MASK = 0x40000000; };
+
+TASK IDLE {
+ AUTOSTART = TRUE;
+ PRIORITY = 0;
+ ACTIVATION = 1;
+ STACK = SHARED;
+ SCHEDULE = FULL;
+};
diff --git a/src/bsp/hsm/os/erika2/os_tick.c b/src/bsp/hsm/os/erika2/os_tick.c
new file mode 100644
index 0000000..341bb22
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/os_tick.c
@@ -0,0 +1,76 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+#include <config.h>
+#include <os/os_hal.h>
+#include <soc/processor.h>
+#include <syslog.h>
+
+#ifdef __ARC32__
+#include <arch/arc_builtin.h>
+#include <arch/arc_reg.h>
+#endif
+
+#include <soc/hsmtmr_sw.h>
+
+void hsmtmr_erika_ostick(enum hsmtmr_ch ch)
+{
+ CounterTick(ostick);
+}
+
+ALARMCALLBACK(os_alarm) {
+ /* do nothing */
+}
+
+TASK(IDLE)
+{
+ while (1U == 1U) {
+ /* do nothing */;
+ }
+}
+
+void os_tick_init(uint32_t hz,
+ uint32_t rate)
+{
+ /* dedicated timer for os */
+ hsmtmr_set_enable(HSMTMR_CH_15, 0);
+ (void)hsmtmr_set_mode(HSMTMR_CH_15, HSMTMR_MODE_REP);
+ hsmtmr_set_timeout_tick(HSMTMR_CH_15, (hz / rate));
+ hsmtmr_set_irq_enable(HSMTMR_CH_15, 1);
+ hsmtmr_set_isr_handler(HSMTMR_CH_15, hsmtmr_erika_ostick);
+ hsmtmr_set_enable(HSMTMR_CH_15, 1);
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/cfg/rules.mk b/src/bsp/hsm/os/erika2/pkg/cfg/rules.mk
new file mode 100644
index 0000000..75fb8b8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cfg/rules.mk
@@ -0,0 +1 @@
+# add this empty file to fix "/src/application/hsm/oil_gen/makefile:116: /os/erika2/pkg/cfg/rules.mk: No such file or directory"
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_compiler.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_compiler.h
new file mode 100644
index 0000000..11bebfe
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_compiler.h
@@ -0,0 +1,56 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef OS_ERIKA2_PKG_CPU_ARC_EM6_INC_EE_COMPILER_H
+#define OS_ERIKA2_PKG_CPU_ARC_EM6_INC_EE_COMPILER_H
+
+#ifdef __MW__
+#include "cpu/common/inc/ee_compiler_mw.h"
+#else /* __MW__ */
+#ifdef __GNU__
+#include "cpu/common/inc/ee_compiler_gcc.h"
+#else /* __GNU__ */
+#error Unsupported compiler
+#endif /* !__GNU__ */
+#endif /* !__MW__ */
+
+#ifdef __IRQ
+#undef __IRQ
+#define __IRQ __attribute__((interrupt("ilink")))
+#endif
+
+#endif /* OS_ERIKA2_PKG_CPU_ARC_EM6_INC_EE_COMPILER_H */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_context.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_context.h
new file mode 100644
index 0000000..4aa0b93
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_context.h
@@ -0,0 +1,181 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ * @file ee_internal.h
+ * @brief Derived from cpu/common/inc/ee_internal.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_CPU_ARC_EM6_EE_CONTEXT__
+#define __INCLUDE_CPU_ARC_EM6_EE_CONTEXT__
+
+/*
+ * Instructions
+ *
+ * The monostack part is complete (obviously, the functions to disable/enable
+ * interrupts are not included here). For the multistack part you have to
+ * provide two additional things:
+ * 1. An assembly implementation of EE_std_change_context_multi(); see below.
+ * 2. A #define directive for EE_hal_active_tos, which is just an alias for the
+ * actual architecture-dependent variable. This variable contains the index of
+ * the current stack.
+ */
+
+/* After a task terminates, the scheduler puts the id of the new task to launch
+ * or switch to in this variable. If the is stacked, its id is marked so.
+ */
+extern EE_TID EE_std_endcycle_next_tid;
+
+/* The multistack version must be implemented in ASM; no standard
+ * implementation, sorry. This is the only function that performs context
+ * switching. The multistack version doesn't jump to the task body if its TID
+ * has been maked as stacked. This is used to switch to a task that has been
+ * suspend by a previous call to EE_std_change_contex().
+ */
+void EE_arc_em6_change_context(EE_TID tid);
+/* Pseudo code for EE_std_change_context_multi():
+ * begin:
+ * tos_index = EE_std_thread_tos[tid+1];
+ * if is_not_the_current_stack(tos_index) {
+ * save_caller_saved_registers();
+ * switch_stacks(tos_index);
+ * restore_caller_saved_registers();
+ * }
+ * if (is_not_marked_stacked(tid)) {
+ * tid = EE_std_run_task_code(tid);
+ * goto begin;
+ * }
+ *
+ * Please notice that the "goto begin" is actually a recursive call to
+ * EE_std_change_context_multi(), but in this way there is no stack growing.
+ *
+ * Please notice also that 'tid' must NOT be saved onto the stack before
+ * switching stacks, otherwise when switching from another stack back to the
+ * current one, you would overwrite its value.
+ *
+ * For processors where the return address is saved in a register, that
+ * register must be saved in the stack too.
+ *
+ * switch_stacks() should also update EE_hal_active_tos.
+ */
+
+/* Call a the body of a task */
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || \
+ defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#define EE_call_task_body(tid) EE_oo_thread_stub()
+#else
+#define EE_call_task_body(tid) (((void (*)(void))EE_hal_thread_body[tid])())
+#endif
+
+
+/* Launch a new task, possibly switching to a different stack, clean up the task
+ * after it ends, and call the scheduler (and switch to other tasks/stacks)
+ * until there are no more tasks to switch to. In the multistack version, also
+ * change the current stack before returning if the scheduler asks for it.
+ */
+__DECLARE_INLINE__ void EE_hal_ready2stacked(EE_TID tid);
+
+
+/* Launch a new task on the current stack, clean up the task after it ends, and
+ * call the scheduler. Return the next task to launch, which is "marked as
+ * stacked" if there is no new task to launch.
+ */
+EE_TID EE_std_run_task_code(EE_TID tid);
+
+void EE_init_task_private_stack(void);
+/*
+ * Inline implementations
+ */
+
+
+#ifdef __MONO__
+
+/* With monostack, we need only the information that the task is stacked. We
+ * don't need to know which task it is, as there is no new stack to switch
+ * to.
+ */
+#define EE_std_mark_tid_stacked(tid) ((EE_TID)-1)
+
+#define EE_std_need_context_change(tid) ((tid) >= 0)
+
+#endif /* __MONO__ */
+
+
+#ifdef __MULTI__
+
+/* TID_IS_STACKED_MARK must set the most significative bit */
+#define EE_std_mark_tid_stacked(tid) ((tid) | (EE_TID)TID_IS_STACKED_MARK)
+
+extern int EE_std_need_context_change(EE_TID tid);
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_stkchange(EE_TID tid)
+{
+ EE_arc_em6_change_context(EE_std_mark_tid_stacked(tid));
+}
+
+#endif /* __MULTI__ */
+
+
+/* The functions below should work for both the monostack and multistack
+ * versions of the kernel, thanks to the macros defined above. In the mono
+ * version, all the stack-related stuff is ignored.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_ready2stacked(EE_TID tid)
+{
+ EE_arc_em6_change_context(tid);
+}
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_ready(EE_TID tid)
+{
+ EE_std_endcycle_next_tid = tid;
+}
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_stacked(EE_TID tid)
+{
+ EE_std_endcycle_next_tid = EE_std_mark_tid_stacked(tid);
+}
+
+#endif /* __INCLUDE_CPU_ARC_EM6_EE_CONTEXT__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_cpu.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_cpu.h
new file mode 100644
index 0000000..c646c21
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_cpu.h
@@ -0,0 +1,491 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ * @file ee_cpu.h
+ * @brief CPU-dependent part of HAL. Derived from pkg/cpu/pic30/inc/ee_cpu.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_ARC_EM6_EE_CPU_H__
+#define __INCLUDE_ARC_EM6_EE_CPU_H__
+
+#include "eecfg.h"
+#include "cpu/arc_em6/inc/ee_compiler.h"
+
+
+/* Initial stack offset (in words): Used in multistack. */
+#ifndef ARC_EM6_INIT_TOS_OFFSET
+#define ARC_EM6_INIT_TOS_OFFSET 10
+#endif
+
+/*************************************************************************
+* HAL Types and structures
+*************************************************************************/
+
+/* Primitive data types */
+#include "cpu/common/inc/ee_types.h"
+
+typedef EE_UINT32 EE_UREG;
+typedef EE_INT32 EE_SREG;
+typedef EE_UINT32 EE_FREG;
+#define EE_UREG_SIZE 4
+
+/* boolean type */
+#ifndef EE_TYPEBOOL
+typedef EE_UREG EE_TYPEBOOL;
+#endif
+
+/* boolean true define */
+#ifndef EE_TRUE
+#define EE_TRUE ((EE_TYPEBOOL)1U)
+#endif
+
+/* boolean false define */
+#ifndef EE_FALSE
+#define EE_FALSE ((EE_TYPEBOOL)0U)
+#endif
+
+#define EE_HWREG_PTR volatile EE_UREG *
+#define EE_HWREG_ADDR(x) ((EE_HWREG_PTR)(x))
+#define EE_HWREG(x) (*EE_HWREG_ADDR(x))
+
+#ifdef __GNU__
+
+/* Get current SP */
+__INLINE__ EE_UINT32 __ALWAYS_INLINE__ __current_sp(void)
+{
+ EE_UINT32 temp;
+
+ __ASM("mov %0, sp" : "=r" (temp) :);
+ return temp;
+}
+
+/* Set a breakpoint */
+#define __breakpoint(value) __ASM("bkpt " #value)
+
+#endif
+
+/* ISR Priority representation type */
+typedef EE_UREG EE_TYPEISR2PRIO;
+
+/* Thread IDs */
+typedef EE_INT32 EE_TID;
+
+/* Thread IDs - unsigned version*/
+typedef EE_UINT32 EE_UTID;
+
+/* Used by the common layer to decide whether to start a new thread */
+#define TID_IS_STACKED_MARK 0x80000000
+
+/* EE_TYPEIRQ is currently unused */
+
+/* XXX: define EE_TIME? */
+
+/* workaround before fix RT-Druid for ARC */
+struct EE_TC_TOS {
+ EE_ADDR SYS_tos;
+ EE_ADDR unused;
+};
+
+/* workaround before fix RT-Druid for ARC. remove after fixed */
+typedef EE_UINT32 EE_tc_task_save_data;
+
+/* Use the "standard" implementation */
+#include "cpu/common/inc/ee_hal_structs.h"
+
+/******************************************************************************
+* Application dependent data types
+******************************************************************************/
+
+#ifdef __HAS_TYPES_H__
+#include "types.h"
+#endif
+
+/******************************************************************************
+* CPU aux registers
+******************************************************************************/
+
+#define EE_AUX_STATUS32 (0xAU)
+#define EE_AUX_STATUS_MASK_E (0x1EU) /*!< interrupt enable */
+#define EE_AUX_STATUS_MASK_IE (0x80000000U) /*!< interrupt enable */
+#define EE_AUX_STATUS_OFFSET_E (1U) /*!< interrupt enable */
+#define EE_AUX_STATUS_OFFSET_IE (31U) /*!< interrupt enable */
+
+#define EE_AUX_IRQ_ACT (0x43U)
+#define EE_AUX_IRQ_PRI (0x206U)
+#define EE_AUX_IRQ_ICAUSE (0x40AU)
+#define EE_AUX_IRQ_SELECT (0x40BU)
+
+__INLINE__ void EE_sr(EE_UREG reg_imm,
+ EE_UREG val)
+{
+ __ASM volatile (
+ "sr %0, [%1]\n"
+ :
+ : "ir" (val), "r" (reg_imm));
+}
+
+__INLINE__ EE_UREG EE_lr(EE_UREG reg_imm)
+{
+ EE_UREG ret;
+
+ __ASM volatile (
+ "lr %0, [%1]\n"
+ : "=r" (ret)
+ : "r" (reg_imm));
+ return ret;
+}
+
+__INLINE__ void EE_kflag(EE_UREG val)
+{
+ __ASM volatile (
+ "kflag %0\n"
+ :
+ : "ir" (val));
+}
+
+/*******************************************************************************
+ * Data Structures for Multi-Stack
+ * They must be visible in API because eecfg.c ERIKA configuration module define
+ * these data multi-stack structures so struct definition need to be seen by
+ * this file. (As reminder I point that eecfg.c include ee.h API collector).
+ ********************************************************************************/
+
+/* Stack Alignment Macros */
+#define EE_STACK_ALIGN 0xFFFFFFF8U
+#define EE_STACK_ALIGN_SIZE 4U
+
+#ifdef __MULTI__
+
+/* Stack Entry Type (I use uint32 to match the type of the filler pattern,
+ * otherwise I would have used uint8)
+ */
+typedef EE_UINT32 EE_STACK_T;
+
+/* Used to initialize stack arrays with the right size. */
+#define EE_STACK_WLEN(size) (((((EE_UINT32)size) + EE_STACK_ALIGN_SIZE) - 1U) \
+ / sizeof(EE_STACK_T))
+
+/* Used to initialize TOS structures. TriCore EABI states that stacks grows
+ * towards small addresses if I know that the base is alligned (as I will
+ * enforce with pragmas) so I only need that "index" is aligned to 8
+ */
+#define EE_STACK_INITP(stack) \
+ ((EE_ADDR)&stack[((sizeof(stack) / sizeof(stack[0])) - 1U) & EE_STACK_ALIGN])
+
+/* Used to initialize TOS structures. TriCore EABI states that stacks grows
+ * towards small addresses so the end of the stack is the begin of the
+ * memory buffer holding it
+ */
+#define EE_STACK_ENDP(stack) ((EE_ADDR)&stack[0U])
+
+/* Used to place ERIKA Stacks in right section for memory protection and ORTI
+ * Stack filling, and handling stack alignment
+ */
+#define EE_STACK_ATTRIB EE_COMPILER_ALIGN(EE_STACK_ALIGN_SIZE) \
+ EE_COMPILER_SECTION(".stack.ee")
+
+#define EE_TC_FILL_STACK(x)
+
+/*******************************************************************************
+* Multistack Data Structures for Context Handling
+*******************************************************************************/
+
+/*
+ * These structures are used by the Multistack HAL to contain the
+ * information about a "stack". This type is used internally by the HAL, but I
+ * cannot move them to ee_tc_internal.h otherwise definition in eecfg.c won't
+ * see correct definition in case of Memory Mapping active.
+ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_AS_OSAPPLICATIONS__
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/* Top-of-stack of each private stack */
+#define EE_tc_system_tos EE_arc_em6_system_tos
+/* TODO: workaround of EE_TC_TOS */
+extern struct EE_TC_TOS EE_arc_em6_system_tos[];
+/* #define EE_std_system_tos EE_arc_em6_system_tos */
+
+/* Index of the current stack */
+#define EE_tc_active_tos EE_arc_em6_active_tos
+extern EE_UREG EE_arc_em6_active_tos;
+
+/* Used in common context */
+#define EE_hal_active_tos EE_arc_em6_active_tos
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_AS_OSAPPLICATIONS__
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_AS_OSAPPLICATIONS__
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/* Stack used by IRQ handlers */
+#ifdef __IRQ_STACK_NEEDED__
+/* This could be declared 'const', but to keep RT-Druid behave as usual
+ * is NOT declared as const */
+#define EE_tc_IRQ_tos EE_arc_em6_IRQ_tos
+extern struct EE_TOS EE_arc_em6_IRQ_tos;
+#endif /* __IRQ_STACK_NEEDED__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_AS_OSAPPLICATIONS__
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#endif
+
+
+/******************************************************************************
+* CPU Peripherals
+******************************************************************************/
+
+#define SWITCH_CONTEXT_IRQ 137
+
+/******************************************************************************
+* HAL Variables
+******************************************************************************/
+
+/*********************************************************************
+* ARC EM6 interrupt disabling/enabling
+*********************************************************************/
+
+/* Used to check the value returned by EE_arc_em6_disableIRQ */
+#define EE_arc_em6_are_IRQs_enabled(ie) ((ie) & EE_AUX_STATUS_MASK_IE)
+
+/**
+ * Enable interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_arc_em6_enableIRQ(void)
+{
+ __ASM volatile ("seti");
+}
+
+/**
+ * Disable interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_arc_em6_disableIRQ(void)
+{
+ __ASM volatile ("clri");
+}
+
+/**
+ * Resume interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_arc_em6_resumeIRQ(EE_FREG f)
+{
+ __ASM volatile (
+ "seti %0\n"
+ :
+ : "r" (f));
+}
+
+/**
+ * Suspend interrupts
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_arc_em6_suspendIRQ(void)
+{
+ EE_FREG istat;
+
+ __ASM volatile ("clri %0" : "=r" (istat));
+ return istat;
+}
+
+/**
+ * Return true (not 0) if IRQs are enabled, 0 (false) if IRQ are disabled.
+ */
+__INLINE__ EE_UINT32 __ALWAYS_INLINE__ EE_arc_em6_get_IRQ_enabled(void)
+{
+ EE_UREG st;
+
+ st = EE_lr(EE_AUX_STATUS32);
+ return EE_arc_em6_are_IRQs_enabled(st);
+}
+
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_arc_em6_get_int_prio(void)
+{
+ EE_UREG st;
+
+ st = EE_lr(EE_AUX_STATUS32);
+ return (st & EE_AUX_STATUS_MASK_E) >> EE_AUX_STATUS_OFFSET_E;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_arc_em6_set_int_prio(
+ EE_TYPEISR2PRIO prio
+ )
+{
+ EE_UREG st;
+
+ st = EE_lr(EE_AUX_STATUS32);
+ st = st & ~(EE_AUX_STATUS_MASK_E);
+ prio = (prio << EE_AUX_STATUS_OFFSET_E) & EE_AUX_STATUS_MASK_E;
+ st = st | prio;
+ EE_kflag(st);
+}
+
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_arc_em6_get_isr_prio(
+ void
+ )
+{
+ EE_TYPEISR2PRIO prio = 0;
+ EE_UREG irq = EE_lr(EE_AUX_IRQ_ACT);
+
+ if (irq != 0U) {
+ irq = EE_lr(EE_AUX_IRQ_ICAUSE);
+ EE_sr(EE_AUX_IRQ_SELECT, irq);
+ prio = EE_lr(EE_AUX_IRQ_PRI);
+ }
+
+ return prio;
+}
+
+__INLINE__ EE_ADDR __ALWAYS_INLINE__ EE_arc_em6_get_SP(void)
+{
+ register EE_ADDR reg = 0U;
+
+ __ASM volatile ("mov %0, sp" : "=r" (reg));
+ return reg;
+}
+
+
+/*************************************************************************
+* Functions exported by the HAL to the kernel
+*************************************************************************/
+
+/*
+ * Interrupt Handling
+ */
+
+/** Hal Enable Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_enableIRQ(void)
+{
+ EE_arc_em6_enableIRQ();
+}
+
+/** Hal Disable Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_disableIRQ(void)
+{
+ EE_arc_em6_disableIRQ();
+}
+
+/** Hal Resume Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_resumeIRQ(EE_FREG f)
+{
+ EE_arc_em6_resumeIRQ(f);
+}
+
+/** Hal Suspend Interrupts */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_suspendIRQ(void)
+{
+ return EE_arc_em6_suspendIRQ();
+}
+
+/**************************************************************************
+ * System Initialization
+ **************************************************************************
+ */
+
+void EE_system_init(void);
+
+/*************************************************************************
+ * CPU-dependent ORT support (mainly OTM)
+ ************************************************************************
+ */
+
+/* Probably, some parts of the OTM code below does not depend on the
+ * architecture. They should be moved somewhere into pkg/cpu/common if this
+ * turns out to be the case.
+ */
+
+#define EE_ORTI_OTM_ID_RUNNINGISR2 1
+#define EE_ORTI_OTM_ID_SERVICETRACE 2
+
+#ifdef __OO_ORTI_USE_OTM__
+void EE_arc_em6_send_otm8(EE_UINT8 id,
+ EE_UINT8 data);
+void EE_arc_em6_send_otm32(EE_UINT8 id,
+ EE_UINT32 data);
+
+#else /* if __OO_ORTI_USE_OTM__ */
+__INLINE__ void EE_arc_em6_send_otm8(EE_UINT8 id,
+ EE_UINT8 data)
+{
+ /* OTM disabled */
+}
+
+__INLINE__ void EE_arc_em6_send_otm32(EE_UINT8 id,
+ EE_UINT32 data)
+{
+ /* OTM disabled */
+}
+#endif /* else __OO_ORTI_USE_OTM__ */
+
+#ifdef __OO_ORTI_RUNNINGISR2__
+__INLINE__ void EE_ORTI_send_otm_runningisr2(EE_ORTI_runningisr2_type isr2)
+{
+ EE_arc_em6_send_otm32(EE_ORTI_OTM_ID_RUNNINGISR2, (EE_UINT32)isr2);
+}
+#endif /* __OO_ORTI_RUNNINGISR2__ */
+
+#ifdef __OO_ORTI_SERVICETRACE__
+__INLINE__ void EE_ORTI_send_otm_servicetrace(EE_UINT8 srv)
+{
+ EE_arc_em6_send_otm8(EE_ORTI_OTM_ID_SERVICETRACE, srv);
+}
+
+#endif /* __OO_ORTI_SERVICETRACE__ */
+
+#endif /* __INCLUDE_ARC_EM6_EE_CPU_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_internal.h
new file mode 100644
index 0000000..b8c8579
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_internal.h
@@ -0,0 +1,201 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ * @file ee_internal.h
+ * @brief Derived from cpu/pic30/inc/ee_internal.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2012
+ */
+
+#ifndef __INCLUDE_ARC_EM6_INTERNAL_H__
+#define __INCLUDE_ARC_EM6_INTERNAL_H__
+
+
+#include "cpu/arc_em6/inc/ee_cpu.h"
+
+
+/*************************************************************************
+* Functions
+*************************************************************************/
+
+/*
+ * Generic Primitives
+ */
+
+#include "cpu/common/inc/ee_primitives.h"
+
+/*************************************************************************
+* System startup
+*************************************************************************/
+
+#define OO_CPU_HAS_STARTOS_ROUTINE
+
+/* If system is defined I have to initialize it*/
+#if (defined(ENABLE_SYSTEM_TIMER) && defined(EE_SYSTEM_TIMER_DEVICE))
+void EE_arc_em6_initialize_system_timer(void);
+#else /* ENABLE_SYSTEM_TIMER */
+#define EE_arc_em6_initialize_system_timer() ((void)0)
+#endif /* ENABLE_SYSTEM_TIMER */
+
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_cpu_startos(void);
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_cpu_startos(void)
+{
+ EE_system_init();
+ EE_arc_em6_initialize_system_timer();
+ return 0;
+}
+
+
+/** Called as _first_ function of a primitive that can be called in
+ * an IRQ and in a task
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_begin_nested_primitive(void)
+{
+ return EE_arc_em6_suspendIRQ();
+}
+
+
+/** Called as _last_ function of a primitive that can be called in
+ * an IRQ and in a task. Enable IRQs if they were enabled before entering.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_end_nested_primitive(EE_FREG f)
+{
+ EE_arc_em6_resumeIRQ(f);
+}
+
+/* Used to get internal CPU priority. */
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_hal_get_int_prio(void)
+{
+ return EE_arc_em6_get_int_prio();
+}
+
+/* Used to set internal CPU priority. */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_set_int_prio(EE_TYPEISR2PRIO prio)
+{
+ EE_arc_em6_set_int_prio(prio);
+}
+
+/*
+ * Used to change internal CPU priority and return a status flag mask.
+ *
+ * Note: EE_FREG param flag and return value needed only for according to
+ * HAL interface.
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_change_int_prio(
+ EE_TYPEISR2PRIO prio,
+ EE_FREG flag
+ )
+{
+ EE_hal_set_int_prio(prio);
+ return flag;
+}
+
+/*
+ * Used to raise internal CPU interrupt priority if param new_prio is greater
+ * than actual priority.
+ *
+ * Note: EE_FREG param flag and return value needed only for according to
+ * HAL interface.
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_raise_int_prio_if_less(
+ EE_TYPEISR2PRIO new_prio,
+ EE_FREG flag
+ )
+{
+ register EE_TYPEISR2PRIO prev_prio = EE_arc_em6_get_int_prio();
+
+ if (((new_prio != 0U) && (prev_prio > new_prio)) || (prev_prio == 0)) {
+ EE_arc_em6_set_int_prio(new_prio);
+ }
+ return flag;
+}
+
+/*
+ * Used to check internal CPU interrupt priority if param new_prio is greater
+ * than actual priority.
+ */
+__INLINE__ EE_BIT __ALWAYS_INLINE__ EE_hal_check_int_prio_if_higher(
+ EE_TYPEISR2PRIO new_prio
+ )
+{
+ register EE_TYPEISR2PRIO prev_prio = EE_arc_em6_get_int_prio();
+
+ return (prev_prio != 0U) && ((prev_prio < new_prio) || (new_prio == 0U));
+}
+
+/*
+ * Context Handling
+ */
+
+#include "cpu/arc_em6/inc/ee_context.h"
+
+/* Launch a new task on the current stack, clean up the task after it ends, and
+ * call the scheduler. Return the next task to launch, which is "marked as
+ * stacked" if there is no new task to launch.
+ */
+EE_TID EE_std_run_task_code(EE_TID tid);
+
+/* typically called at the end of an interrupt */
+#define EE_hal_IRQ_stacked EE_hal_endcycle_stacked
+#define EE_hal_IRQ_ready EE_hal_endcycle_ready
+
+/*
+ * OO TerminateTask related stuffs
+ */
+
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || defined(__OO_ECC2__)
+
+/** Save the context and call the body of the task `tid'. Implemented in
+ * assembly
+ */
+void EE_hal_terminate_savestk(EE_TID tid);
+
+/** Restore the context saved by EE_hal_terminate_savestk() for the task `tid' and
+ * return from EE_hal_terminate_savestk(). Implemented in assembly
+ */
+NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+#endif /* __OO_BCCx */
+
+
+#endif /* __INCLUDE_ARC_EM6_INTERNAL_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq.h
new file mode 100644
index 0000000..56f5cea
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq.h
@@ -0,0 +1,177 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ *
+ * @file ee_irq.h
+ * @brief Prestub and postub macros and related stuffs
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_ARC_EM6_IRQ_H__
+#define __INCLUDE_ARC_EM6_IRQ_H__
+
+
+#ifdef __ARC_EM6__
+#define EE_ISR_UNMASKED 0x00000000
+#define EE_ISR_PRI_1 0x00000006U
+#define EE_ISR_PRI_2 0x00000005U
+#define EE_ISR_PRI_3 0x00000004U
+#define EE_ISR_PRI_4 0x00000003U
+#define EE_ISR_PRI_5 0x00000002U
+#define EE_ISR_PRI_6 0x00000001U
+#endif /* __ARC_EM6__ */
+
+#define EE_std_change_context(x) ((void)0)
+
+/* Use angled parenthesis to include the main "ee_internal.h" */
+#include "cpu/arc_em6/inc/ee_cpu.h"
+#include "cpu/arc_em6/inc/ee_context.h"
+#include "cpu/arc_em6/inc/ee_irq_cng_cont.h"
+#include "cpu/common/inc/ee_irqstub.h"
+#include <config.h>
+
+#ifdef __ALLOW_NESTED_IRQ__
+
+extern struct EE_TOS EE_arc_em6_IRQ_tos;
+
+#if CONFIG_NESTED_INTERRUPT == 1
+#define EE_std_enableIRQ_nested() EE_arc_em6_enableIRQ()
+#define EE_std_disableIRQ_nested() EE_arc_em6_disableIRQ()
+#else
+#define EE_std_enableIRQ_nested() ((void)0)
+#define EE_std_disableIRQ_nested() ((void)0)
+#endif
+
+#else /* else __ALLOW_NESTED_IRQ__*/
+
+#define EE_std_enableIRQ_nested() ((void)0)
+#define EE_std_disableIRQ_nested() ((void)0)
+
+#endif /* end __ALLOW_NESTED_IRQ__*/
+
+#if defined(__MULTI__) && defined(__IRQ_STACK_NEEDED__)
+
+extern void EE_arc_em6_change_IRQ_stack(void);
+extern void EE_arc_em6_change_IRQ_stack_back(void);
+
+/*save the stack pointer*/ /*Load new stack pointer*/
+#define EE_arc_em6_change_stack() \
+ do { \
+ if (EE_IRQ_nesting_level == 1) { \
+ EE_arc_em6_change_IRQ_stack(); \
+ } \
+ } while (0)
+
+#define EE_arc_em6_stack_back() \
+ EE_arc_em6_change_IRQ_stack_back()
+
+#else /* else __MULTI__ && __IRQ_STACK_NEEDED__*/
+
+#define EE_arc_em6_change_stack() ((void)0)
+#define EE_arc_em6_stack_back() ((void)0)
+
+#endif /* end __MULTI__ && __IRQ_STACK_NEEDED__*/
+
+#define EE_ISR2_prestub(void) \
+ /* Defined as Macro */ \
+ do { \
+ EE_arc_em6_disableIRQ(); \
+ ipl = EE_arc_em6_get_int_prio(); \
+ EE_arc_em6_set_int_prio(EE_arc_em6_get_isr_prio()); \
+ EE_increment_IRQ_nesting_level(); \
+ EE_arc_em6_change_stack(); \
+ /* Enable IRQ if nesting is allowed */ \
+ EE_std_enableIRQ_nested(); \
+ } \
+ while (0)
+
+extern EE_UREG EE_arc_em6_change_context_active;
+
+#define EE_ISR2_poststub(void) \
+ /* Defined as Macro */ \
+ do { \
+ /* Disabled IRQ if nesting is allowed.\
+ * Note: if nesting is not allowed, the IRQs are already disabled\
+ */ \
+ EE_std_disableIRQ_nested(); \
+ EE_arc_em6_set_int_prio(ipl); \
+ EE_std_end_IRQ_post_stub(); \
+ EE_decrement_IRQ_nesting_level(); \
+ /*\
+ * If the ISR at the lowest level is ended, restore the stack pointer\
+ * and active the change context procedure if needed ( call the scheduler).\
+ */ \
+ if (!EE_is_inside_ISR_call()) { \
+ EE_arc_em6_stack_back(); \
+ EE_arc_em6_IRQ_active_change_context(); \
+ } \
+ } \
+ while (0)
+
+
+
+#define ISR1(f) \
+ void ISR1_ ## f(void); \
+ void f(void) \
+ { \
+ ISR1_ ## f(); \
+ } \
+ void ISR1_ ## f(void)
+
+
+#define ISR2(f) \
+ void ISR2_ ## f(void); \
+ void f(void) \
+ { \
+ EE_UREG ipl = 0; \
+ EE_ISR2_prestub(); \
+ ISR2_ ## f(); \
+ EE_ISR2_poststub(); \
+ } \
+ void ISR2_ ## f(void)
+
+/* Standard Macro to declare an ISR (2) */
+#define ISR(f) ISR2(f)
+
+#endif /* __INCLUDE_ARC_EM6_IRQ_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq_cng_cont.h b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq_cng_cont.h
new file mode 100644
index 0000000..36839e0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/inc/ee_irq_cng_cont.h
@@ -0,0 +1,72 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ *
+ * @file ee_irq_cng_cont.h
+ * @brief Function active the context change interrupt
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2012
+ */
+
+#ifndef __INCLUDE_ARC_EM6_IRQ_CNG_CONTEXT_H__
+#define __INCLUDE_ARC_EM6_IRQ_CNG_CONTEXT_H__
+
+#ifdef __MW__
+#include "cpu/common/inc/ee_compiler_mw.h"
+#else /* __MW__ */
+#ifdef __GNU__
+#include "cpu/common/inc/ee_compiler_gcc.h"
+#else /* __GNU__ */
+#error Unsupported compiler
+#endif /* !__GNU__ */
+#endif /* !__MW__ */
+
+/* Implemented in ee_<compiler>_change_context_isr.s */
+extern void EE_switch_context(void);
+
+__INLINE__ void __ALWAYS_INLINE__ EE_arc_em6_IRQ_active_change_context(void)
+{
+ EE_switch_context();
+}
+
+#endif /* __INCLUDE_ARC_EM6_IRQ_CNG_CONTEXT_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/makefile b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/makefile
new file mode 100644
index 0000000..cfc77c8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/makefile
@@ -0,0 +1,78 @@
+LOCAL_PATH := $(call cur-dir)
+
+ifeq ($(OS_ERIKA2), true)
+ifeq ($(TARGET_ARCH), arc)
+
+LOCAL_MODULE := os_erika_cpu_arc_em6
+
+EE_SRCS :=
+
+ifeq ($(call iseeopt, __ARC_EM6__), yes)
+EE_SRCS += ./src/ee_utils.c
+EE_SRCS += ./src/ee_context.c
+
+ifeq ($(call iseeopt, __MW__), yes)
+#EE_SRCS += ./src/ee_mw_change_context_isr.s
+else # __MW__
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += ./src/ee_gnu_change_context_isr.S
+endif # __GNU__
+endif # !__MW__
+
+ifeq ($(call iseeopt, __OO_BCC1__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_BCC2__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_ECC1__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_ECC2__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(CPU_OO), YES)
+ifeq ($(call iseeopt, __MW__), yes)
+#EE_SRCS += ./src/ee_mw_oo.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += ./src/ee_gnu_oo.S
+endif
+endif
+endif
+
+ifeq ($(call iseeopt, __MULTI__), yes)
+
+ifeq ($(call iseeopt, __MW__), yes)
+#EE_SRCS += ./src/ee_mw_multi_context.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += ./src/ee_gnu_multi_context.S
+endif
+endif
+
+endif # __MULTI__
+
+ifeq ($(call iseeopt, __IRQ_STACK_NEEDED__), yes)
+
+ifeq ($(call iseeopt, __MW__), yes)
+#EE_SRCS += ./src/ee_mw_irq_stack.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += ./src/ee_gnu_irq_stack.S
+endif
+endif
+
+endif # __IRQ_STACK_NEEDED__
+
+endif # __ARC_EM6__
+
+ALL_SRCS += $(foreach SRC, $(EE_SRCS:./%=%), $(addprefix $(LOCAL_PATH)/, $(SRC)))
+
+endif # TARGET_ARCH
+endif # OS_ERIKA2
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_context.c b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_context.c
new file mode 100644
index 0000000..e7809fc
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_context.c
@@ -0,0 +1,83 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/*
+ * Context switch functions used in HAL implementations
+ * Author: 2011 Gianluca Franchino
+ * 2011 Giuseppe Serano
+ */
+
+#include "ee_internal.h"
+
+#ifdef __MONO__
+
+void EE_arc_em6_change_context(EE_TID tid)
+{
+ do {
+ tid = EE_std_run_task_code(tid);
+ } while (EE_std_need_context_change(tid));
+}
+
+#endif /* __MONO__ */
+
+#ifdef __MULTI__
+
+int EE_std_need_context_change(EE_TID tid)
+{
+ /* FIXME: "tid+1" can be used as an index for arrays even when marked if
+ * EE_TID is defined as an int. Otherwise, the mark will cause a memory
+ * access violation!
+ */
+ EE_UTID utid;
+ int need_context_change = 1;
+
+ if (tid < 0) {
+ /* Unmark the tid to access the EE_std_thread_tos, otherwise undefined
+ * behaviour. (Index out of arrays boundaries)
+ * FIXME: #1
+ */
+ utid = (EE_UTID)(tid + 1) & (~(EE_UTID)TID_IS_STACKED_MARK);
+ need_context_change = (EE_hal_active_tos != EE_std_thread_tos[utid]);
+ }
+ return need_context_change;
+}
+
+#endif /* __MULTI__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_change_context_isr.S b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_change_context_isr.S
new file mode 100644
index 0000000..1d8da16
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_change_context_isr.S
@@ -0,0 +1,433 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2012 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; ;file ee_gnu_change_context_isr.s
+; ;brief Functions to active and manage the context switch for Cortex_MX
+; ;author Gianluca Franchino
+; ;author Giuseppe Serano
+; ;author Mauro Marinoni
+; ;author Alessandro Biondi
+; ;date 2013
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+; void EE_switch_context(void);
+ .global EE_switch_context
+
+; void EE_arc_em6_os_ISR(void);
+ .global EE_arc_em6_os_ISR
+
+; void EE_arc_em6_svc_ISR(void);
+ .global EE_arc_em6_svc_ISR
+
+; void EE_set_switch_context_pri(void)
+ .global EE_set_switch_context_pri
+
+; void EE_IRQ_end_instance(void);
+ .global EE_IRQ_end_instance
+
+; void EE_arc_em6_change_context(EE_TID tid);
+ .global EE_arc_em6_change_context
+ .global EE_arc_em6_change_context_return_point
+
+; EE_TID EE_std_endcycle_next_tid;
+ .global EE_std_endcycle_next_tid
+
+#ifdef __MULTI__
+; int EE_std_need_context_change(EE_TID tid);
+ .global EE_std_need_context_change
+#endif
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ .text
+ .cpu em4
+
+; pick an empty IRQ to do context switch on ARC
+#define SWITCH_CONTEXT_IRQ 137
+
+#define EE_AUX_STATUS32 0xA
+#define EE_AUX_IRQ_HINT 0x201
+#define EE_AUX_IRQ_PRI 0x206
+#define EE_AUX_IRQ_SELECT 0x40B
+#define EE_AUX_IRQ_ENABLE 0x40C
+
+#define EE_AUX_ERBTA 0x401
+#define EE_AUX_BTA 0x412
+
+#define NVIC_INT_CTRL 0xE000ED04 ; Interrupt control status register
+#define NVIC_SHPR2 0xE000ED1C ; System priority register (SVCall 11)
+#define NVIC_SHPR3 0xE000ED20 ; System priority register (PendSV 14)
+#define NVIC_PENDSV_PRI 0x00FF0000 ; PendSV priority OR-value (Lowest)
+#define NVIC_SVCALL_PRI 0x00FFFFFF ; SVCall priority AND-value (Highest)
+#define NVIC_PENDSVSET 0x10000000 ; Value to trigger PendSV exception
+#define NVIC_PENDSVCLR 0x08000000 ; Value to un-trigger PendSV exception
+
+#define EPSR_T_BIT_VAL 0x01000000 ; Value to set the T-bit in EPSR
+ ; (always Thumb mode)
+
+#define EXC_RETURN 0xFFFFFFF9 ; No-FPU, Thread-Mode, MSP.
+#define CONTEXT_STATUS32 0x0000001E ; Disable IRQ, Kernel mode, lowest IRQ threshold
+
+#ifdef __MONO__
+#define TID_IS_STACKED_MARK 0x80000000
+#endif
+
+#define _EE_arc_em6_change_context_addr EE_arc_em6_change_context
+#define _EE_std_endcycle_next_tid_addr EE_std_endcycle_next_tid
+#define _EE_arc_em6_change_context_return_point_addr EE_arc_em6_change_context_return_point
+
+
+; void EE_set_switch_context_pri(void)
+ .type EE_set_switch_context_pri, @function
+ .align 4
+EE_set_switch_context_pri:
+
+;Set PendSV priority to the minumum one
+ ;LDR R0, =NVIC_SHPR3
+ ;LDR R1, =NVIC_PENDSV_PRI
+ ;LDR R2, [R0];
+ ;ORRS R2, R2, R1;
+ ;STR R2, [R0];
+
+;Set SVCall priority to the maximum one
+ ;LDR R0, =NVIC_SHPR2
+ ;LDR R1, =NVIC_SVCALL_PRI
+ ;LDR R2, [R0];
+ ;ANDS R2, R2, R1;
+ ;STR R2, [R0];
+
+ ;BX LR
+
+;Set os IRQ priority to the minimum one
+ MOV r0, EE_AUX_IRQ_SELECT
+ MOV r1, SWITCH_CONTEXT_IRQ
+ SR r1, [r0]
+ MOV r0, EE_AUX_IRQ_PRI
+ MOV r1, 0xE
+ SR r1, [r0]
+ MOV r0, EE_AUX_IRQ_ENABLE
+ MOV r1, 0x1
+ SR r1, [r0]
+
+ J [blink]
+
+ .size EE_set_switch_context_pri, . - EE_set_switch_context_pri
+
+
+; void EE_switch_context(void)
+ .type EE_switch_context, @function
+EE_switch_context:
+
+; Trigger the PendSV exception (causes context switch)
+ ;LDR R0, =NVIC_INT_CTRL
+ ;LDR R1, =NVIC_PENDSVSET
+ ;STR R1, [R0]
+ ;BX LR
+
+; Trigger the switch context irq
+ MOV r0, EE_AUX_IRQ_HINT
+ MOV r1, SWITCH_CONTEXT_IRQ
+ SR r1, [r0]
+ J [blink]
+
+ .size EE_switch_context, . - EE_switch_context
+
+
+; void EE_arc_em6_os_ISR(void)
+ .type EE_arc_em6_os_ISR, @function
+ .align 4
+EE_arc_em6_os_ISR:
+
+ ;CPSID I ; Disable all interrupts.
+ CLRI 0
+
+; Save current context's BTA
+ MOV r0, EE_AUX_BTA
+ LR r1, [r0]
+ PUSH r1
+ PUSH gp
+ PUSH fp
+ PUSH ilink
+ PUSH r30
+
+; Clear the PendSV exception (preventing 2nd triggering)
+ ;LDR R0, =NVIC_INT_CTRL
+ ;LDR R1, =NVIC_PENDSVCLR
+ ;STR R1, [R0]
+ MOV r0, EE_AUX_IRQ_HINT
+ MOV r1, 0
+ SR r1, [r0]
+
+ ;BL EE_IRQ_end_instance ; IRQ Scheduler.
+ PUSH blink
+ JL EE_IRQ_end_instance ; IRQ Scheduler.
+ POP blink
+
+; R0 = EE_std_endcycle_next_tid.
+ ;LDR R0, =_EE_std_endcycle_next_tid_addr
+ ;LDR R0, [R0]
+ MOV r0, _EE_std_endcycle_next_tid_addr
+ LD r0, [r0]
+
+#ifdef __MONO__
+; #define EE_std_need_context_change(tid) ((tid) >= 0)
+ ;LDR R1, =TID_IS_STACKED_MARK
+ ;ANDS R0, R0, R1
+ ;CBNZ R0, EE_arc_em6_os_ISR_end
+ MOV r1, TID_IS_STACKED_MARK
+ AND r0, r0, r1
+ BRNE r0, 0, EE_arc_em6_os_ISR_end
+#endif
+
+#ifdef __MULTI__
+ ;BL EE_std_need_context_change
+ ;CBZ r0, EE_arc_em6_os_ISR_end
+ PUSH blink
+ JL EE_std_need_context_change
+ POP blink
+ BREQ r0, 0, EE_arc_em6_os_ISR_end
+#endif
+
+; Build a stack frame to jump into the EE_std_change_context(EE_TID) at the end
+; of PendSV_Handler.
+
+#if 1
+ MOV r0, _EE_std_endcycle_next_tid_addr
+ LD r0, [r0]
+
+; R3 (STATUS32)
+ MOV r3, CONTEXT_STATUS32
+
+; R2 (PC)
+ MOV r2, _EE_arc_em6_change_context_addr
+
+; R1 (BLINK)
+ MOV r1, _EE_arc_em6_change_context_return_point_addr
+
+;| STATUS32 |
+;| PC |
+;| LP_COUNT |
+;| LP_START |
+;| LP_END |
+;| BLINK |
+ PUSH r3
+ PUSH r2
+ ST.AW 0, [sp, -4]
+ ST.AW 0, [sp, -4]
+ ST.AW 0, [sp, -4]
+ PUSH r1
+;| R25~R0 |
+ ST.AW 25, [sp, -4]
+ ST.AW 24, [sp, -4]
+ ST.AW 23, [sp, -4]
+ ST.AW 22, [sp, -4]
+ ST.AW 21, [sp, -4]
+ ST.AW 20, [sp, -4]
+ ST.AW 19, [sp, -4]
+ ST.AW 18, [sp, -4]
+ ST.AW 17, [sp, -4]
+ ST.AW 16, [sp, -4]
+ ST.AW 15, [sp, -4]
+ ST.AW 14, [sp, -4]
+ ST.AW 13, [sp, -4]
+ ST.AW 12, [sp, -4]
+ ST.AW 11, [sp, -4]
+ ST.AW 10, [sp, -4]
+ ST.AW 9, [sp, -4]
+ ST.AW 8, [sp, -4]
+ ST.AW 7, [sp, -4]
+ ST.AW 6, [sp, -4]
+ ST.AW 5, [sp, -4]
+ ST.AW 4, [sp, -4]
+ ST.AW 3, [sp, -4]
+ ST.AW 2, [sp, -4]
+ ST.AW 1, [sp, -4]
+ PUSH r0
+ RTIE
+#else
+; R0 = EE_std_endcycle_next_tid (R12)
+ ;LDR R0, =_EE_std_endcycle_next_tid_addr
+ ;LDR R0, [R0]
+
+; R3 = 0x01000000 (xPSR)
+ ;LDR R3, =EPSR_T_BIT_VAL
+
+; R2 = EE_arc_em6_change_context (PC)
+ ;LDR R2, =_EE_arc_em6_change_context_addr
+
+; R1 = exit_EE_arc_em6_change_context (LR)
+ ;LDR R1, =_EE_arc_em6_change_context_return_point_addr
+
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_arc_em6_change_context
+;| LR |-> EE_arc_em6_change_context_return_point
+;| R12|
+ ;PUSH {R0-R3}
+
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 |
+ ;PUSH {R0-R3}
+
+;Fake IRQ handler frame on top of PendSV frame:
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_arc_em6_change_context
+;| LR |-> EE_arc_em6_change_context_return_point
+;| R12|
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 | <- MSP
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ ;LDR R0, =EXC_RETURN
+ ;BX R0 ; EXC_RETURN.
+
+ ;NOP ; Alignment.
+#endif
+
+EE_arc_em6_os_ISR_end:
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ ;LDR R0, =EXC_RETURN
+ ;CPSIE I ; Enable all interrupts.
+ ;BX R0 ; EXC_RETURN.
+
+ POP r30
+ POP ilink
+ POP fp
+ POP gp
+ POP r1 ; Restore BTA
+ MOV r0, EE_AUX_BTA
+ SR r1, [r0]
+ RTIE
+
+ .size EE_arc_em6_os_ISR, . - EE_arc_em6_os_ISR
+
+
+; Enable interrupts (clear PRIMASK)
+ .type EE_arc_em6_change_context_return_point, @function
+ .align 4
+EE_arc_em6_change_context_return_point:
+/*; NOTE: If SVC is executed when PRIMASK is set to 1, HardFault Exception will
+; occur. To solve this, instead of using PRIMASK to mask interrupts, use
+; BASEPRI to mask particular interrupts. */
+ ;CPSIE I
+ SETI 0
+; SVCall exception to remove Original PendSV stack-frame.
+ ;SVC #0
+ TRAP_S 0
+
+ .size EE_arc_em6_change_context_return_point, . - EE_arc_em6_change_context_return_point
+
+; void EE_arc_em6_svc_ISR(void)
+ .type EE_arc_em6_svc_ISR, @function
+ .align 4
+EE_arc_em6_svc_ISR:
+; Remove SVCall Stack-Frame.
+ ;ADD SP, SP, #(8*4)
+ ;BX LR ; EXC_RETURN.
+
+; ARC doesn't automatic push registers in exception entry
+; ARC doesn't restore registers automatically on exception exit
+ POP r30
+ POP ilink
+ POP fp
+ POP gp
+
+ ST r30, [sp, -4]
+
+ LD r30, [sp, 0]
+ SR r30, [erbta]
+ LD r0, [sp, 4]
+ LD r1, [sp, 8]
+ LD r2, [sp, 12]
+ LD r3, [sp, 16]
+ LD r4, [sp, 20]
+ LD r5, [sp, 24]
+ LD r6, [sp, 28]
+ LD r7, [sp, 32]
+ LD r8, [sp, 36]
+ LD r9, [sp, 40]
+ LD r10, [sp, 44]
+ LD r11, [sp, 48]
+ LD r12, [sp, 52]
+ LD r13, [sp, 56]
+ LD r14, [sp, 60]
+ LD r15, [sp, 64]
+ LD r16, [sp, 68]
+ LD r17, [sp, 72]
+ LD r18, [sp, 76]
+ LD r19, [sp, 80]
+ LD r20, [sp, 84]
+ LD r21, [sp, 88]
+ LD r22, [sp, 92]
+ LD r23, [sp, 96]
+ LD r24, [sp, 100]
+ LD r25, [sp, 104]
+ LD blink, [sp, 108]
+ LD r30, [sp, 112]
+ SR r30, [lp_end]
+ LD r30, [sp, 116]
+ SR r30, [lp_start]
+ LD r30, [sp, 120]
+ MOV lp_count, r30
+ LD r30, [sp, 124]
+ SR r30, [eret]
+ LD r30, [sp, 128]
+ SR r30, [erstatus]
+
+ LD r30, [sp, -4]
+ ADD sp, sp, 132
+
+ RTIE
+
+ .size EE_arc_em6_svc_ISR, . - EE_arc_em6_svc_ISR
+
+
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_irq_stack.S b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_irq_stack.S
new file mode 100644
index 0000000..50c2d2f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_irq_stack.S
@@ -0,0 +1,122 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; ;file ee_keil_irq_stack.s
+; ;brief Context switch function for multistack on Cortex_MX
+; ;brief Stack switch for ISRs on Cortex_MX.
+; Implementation of EE_arc_em6_call_ISR_new_stack() as described in
+; pkg/cpu/arc_em6/inc/ee_irq_internal.h
+; ;author Gianluca Franchino
+; ;author Giuseppe Serano
+; ;author Alessandro Biondi
+; ;date 2013
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ .global EE_arc_em6_change_IRQ_stack
+ .global EE_arc_em6_change_IRQ_stack_back
+
+ .global EE_arc_em6_IRQ_tos
+
+
+;*******************************************************************************
+; DATA SECTION
+;*******************************************************************************
+ .data
+
+EE_arc_em6_tmp_tos: .word 0 ; EE_UREG EE_arc_em6_tmp_tos;
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ .text
+ .cpu em4
+
+;void EE_arc_em6_change_IRQ_stack(void);
+ .type EE_arc_em6_change_IRQ_stack, @function
+ .align 4
+EE_arc_em6_change_IRQ_stack:
+
+ ;MRS R0, MSP ; R0 = MSP (Main stack Pointer)
+ ;LDR R1, =EE_arc_em6_tmp_tos ; R1 = address of EE_cortex_m0_tmp_tos
+ ;STR R0, [R1] ; Save MSP in EE_arc_em6_tmp_tos
+ ;LDR R0, =EE_arc_em6_IRQ_tos ; R0 = address of EE_arc_em6_IRQ_tos
+ ;LDR R0, [R0] ; R0 = IRQ new stack pointer
+ ;MSR MSP, R0 ; change IRQ stack
+ MOV r1, EE_arc_em6_tmp_tos
+ ST sp, [r1]
+ MOV r0, EE_arc_em6_IRQ_tos
+ LD r0, [r0]
+ MOV sp, r0
+
+ ;BX LR ; return
+ J [blink]
+
+ .size EE_arc_em6_change_IRQ_stack, . - EE_arc_em6_change_IRQ_stack
+
+;*******************************************************************************
+
+;void EE_arc_em6_change_IRQ_stack_back(void);
+ .type EE_arc_em6_change_IRQ_stack_back, @function
+ .align 4
+EE_arc_em6_change_IRQ_stack_back:
+
+ ;LDR R0, =EE_arc_em6_tmp_tos ; R0 = address of EE_arc_em6_tmp_tos
+ ;LDR R0, [R0] ; R0 = old MSP
+ ;MSR MSP, R0 ; Restore the stack pointer
+ MOV r0, EE_arc_em6_tmp_tos
+ LD r0, [r0]
+ MOV sp, r0
+
+ ;BX LR ; return
+ J [blink]
+
+ .size EE_arc_em6_change_IRQ_stack_back, . - EE_arc_em6_change_IRQ_stack_back
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ .end
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_multi_context.S b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_multi_context.S
new file mode 100644
index 0000000..ba352ad
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_multi_context.S
@@ -0,0 +1,294 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; ;file ee_keil_multi_context.s
+; ;brief Context switch function for multistack on Cortex MX
+; Implementation of EE_arc_em6_change_context as described in
+; pkg/cpu/common/inc/ee_context.h
+; ;author Gianluca Franchino
+; ;author Giuseppe Serano
+; ;author Alessandro Biondi
+; ;date 2013
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ .global EE_arc_em6_change_context
+
+ .extern EE_std_run_task_code
+ .extern EE_std_thread_tos
+ .extern EE_arc_em6_active_tos
+ .extern EE_arc_em6_system_tos
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ .text
+ .cpu em4
+
+;Pseudo code for EE_arc_em6_change_context():
+; begin:
+; tos_index = EE_std_thread_tos[tid+1]; ; get tos index (not head of stack). tid is 0-based. +1 because dummy task doesn't counted in tid.
+; if is_not_the_current_stack(tos_index) {
+; save_caller_saved_registers();
+; switch_stacks(tos_index);
+; restore_caller_saved_registers();
+; }
+; if (is_not_marked_stacked(tid)) {
+; tid = EE_std_run_task_code(tid);
+; goto begin;
+; }
+;
+
+;void EE_arc_em6_change_context(EE_TID tid);
+ .type EE_arc_em6_change_context, @function
+ .align 4
+EE_arc_em6_change_context:
+ ; R0 == tid
+ ; R1 = (tid + 1) & ~TID_IS_STACKED_MARK
+ ; tos_index = EE_std_thread_tos[tid+1];
+ ;ADDS R1, R0, #1 ; R1 = tid+1
+ ;LSLS R1, R1, #2 ; R1 = (tid+1)*4= correct offset in EE_std_thread_tos
+ ; The last shift, also gets rid of the `stacked' mark
+ ;LDR R2, =EE_std_thread_tos
+ ;ADD R1, R2, R1
+ ;LDR R1, [R1] ;R1 == tos_index (stack index of task <tid>)
+ ADD r1, r0, 1
+ AND r1, r1, 0x7FFFFFFF
+ ASL r1, r1, 2
+ MOV r2, EE_std_thread_tos
+ LD r1, [r2, r1]
+
+ ;*
+ ;* if is_not_the_current_stack(tos_index) {
+ ;*
+ ;LDR R2, =EE_arc_em6_active_tos ;R2 = & EE_arc_em6_active_tos;
+ ;LDR R3, [R2] ; R3 = EE_arc_em6_active_tos; (current stack index)
+ ;CMP R1, R3
+ ;BEQ end_change_stacks
+ MOV r2, EE_arc_em6_active_tos
+ LD r3, [r2]
+ CMP r1, r3
+ BEQ end_change_stacks
+
+ ;save_caller_saved_registers();
+
+ ;Save all callee-saved registers
+ ;R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ ;PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ ;MOV R4, R8
+ ;MOV R5, R9
+ ;MOV R6, R10
+ ;MOV R7, R11
+ ;PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ ;PUSH {LR} ; Store link register (return address)
+ PUSH r30 ; save r30 before used as scratch register
+ PUSH lp_count
+ LR r30, [lp_start]
+ PUSH r30
+ LR r30, [lp_end]
+ PUSH r30
+ PUSH blink
+ PUSH ilink
+ PUSH fp
+ PUSH gp
+ PUSH r25
+ PUSH r24
+ PUSH r23
+ PUSH r22
+ PUSH r21
+ PUSH r20
+ PUSH r19
+ PUSH r18
+ PUSH r17
+ PUSH r16
+ PUSH r15
+ PUSH r14
+ PUSH r13
+ PUSH r12
+ PUSH r11
+ PUSH r10
+ PUSH r9
+ PUSH r8
+ PUSH r7
+ PUSH r6
+ PUSH r5
+ PUSH r4
+ PUSH r3
+ PUSH r2
+ PUSH r1
+ LR r30, [bta]
+ PUSH r30
+
+ ;!!!!!!!!!!!!!!!
+ ; At this point the non scratch registers (R4...R11) are pushed into stack,
+ ; hence I can use them in the following.
+ ;!!!!!!!!!!!!!!!!
+
+ ; switch_stacks(tos_index);
+ ;LDR R4, =EE_arc_em6_system_tos ; R4 = & arc_em6_system_tos[0];
+ MOV r13, EE_arc_em6_system_tos
+
+ ; Note: although R4 is not a scratch register, it has been saved onto stack,
+ ; therefore we can used it in the follow without problem
+ ; EE_arc_em6_system_tos[R3] = MSP;
+ ;LSLS R3, R3, #2
+ ;ADD R3, R4, R3
+ ;MRS R5, MSP
+ ASL r3, r3, 3 ; change to 2 after fix EE_TC_TOS
+ ADD r3, r13, r3
+
+ ; Note STR can only use the register range -> R0 to R4.
+ ;STR R5, [R3] ; save stack pointer
+ ST sp, [r3]
+
+ ; EE_arc_em6_active_tos = tos_index;
+ ;STR R1, [R2]
+ ST r1, [r2]
+
+ ; MSP= EE_arc_em6_system_tos[R1];
+ ;LSLS R1, R1, #2
+ ;ADD R1, R4, R1
+ ;LDR R1, [R1]
+ ;MSR MSP, R1
+ ASL r1, r1, 3 ; change to 2 after fix EE_TC_TOS
+ LD r1, [r13, r1]
+ MOV sp, r1
+
+ ;; restore_callee_saved_registers();
+ ;POP {R1} ; Get link register from stack
+ ;MOV LR, R1 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ ;POP {R4-R7}
+ ;MOV R8, R4
+ ;MOV R9, R5
+ ;MOV R10, R6
+ ;MOV R11, R7
+ ;POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ POP r30
+ SR r30, [bta]
+ POP r1
+ POP r2
+ POP r3
+ POP r4
+ POP r5
+ POP r6
+ POP r7
+ POP r8
+ POP r9
+ POP r10
+ POP r11
+ POP r12
+ POP r13
+ POP r14
+ POP r15
+ POP r16
+ POP r17
+ POP r18
+ POP r19
+ POP r20
+ POP r21
+ POP r22
+ POP r23
+ POP r24
+ POP r25
+ POP gp
+ POP fp
+ POP ilink
+ POP blink
+ POP r30
+ SR r30, [lp_end]
+ POP r30
+ SR r30, [lp_start]
+ POP r30
+ MOV lp_count, r30
+ POP r30
+ ; *
+ ; * }
+ ; *
+
+end_change_stacks:
+ ; R0 == tid
+
+ ; *
+ ; *if (is_not_marked_stacked(tid)) {
+ ; *
+
+ ;CMP R0, #0 ; cmp with 0 because the mark is a negative sign for signed interger
+ ;BLT end_run_thread ; <0 means marked as stacked
+ BRLT r0, 0, end_run_thread
+
+ ; tid = EE_std_run_task_code(tid);
+ ;PUSH {LR}
+ ;BL EE_std_run_task_code
+ PUSH blink
+ PUSH fp
+ BL EE_std_run_task_code
+ ; R0 == tid
+ ;POP {R1}
+ ;MOV LR, R1
+ POP fp
+ POP blink
+
+ ;B EE_arc_em6_change_context
+ J EE_arc_em6_change_context
+ ; goto begin
+
+ ; *
+ ; * }
+ ; *
+
+
+end_run_thread:
+ ;BX LR ; Return
+ J [blink]
+
+ .size EE_arc_em6_change_context, . - EE_arc_em6_change_context
+
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ .end
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_oo.S b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_oo.S
new file mode 100644
index 0000000..76c7cae
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_gnu_oo.S
@@ -0,0 +1,256 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_keil_oo.S
+; @brief Functions to save and restore registers for OSEK TerminateTask().
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @author Alessandro Biondi
+; @date 2013
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ ; Functions declared in this file
+ .global EE_hal_terminate_savestk ; void EE_hal_terminate_savestk(EE_TID tid)
+ .global EE_hal_terminate_task ; NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+ .global EE_terminate_real_th_body
+ .global EE_terminate_data
+ .global EE_thread_not_terminated
+
+;*******************************************************************************
+; EQUATES
+;*******************************************************************************
+#define EPSR_T_BIT_VAL 0x01000000 ; Value to set the T-bit in EPSR (always Thumb mode)
+#define EE_AUX_STATUS32 0xA
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+
+ .text
+ .cpu em4
+
+;void EE_hal_terminate_savestk(EE_TID tid);
+ .type EE_hal_terminate_savestk, @function
+ .align 4
+EE_hal_terminate_savestk:
+ ; Save all callee-saved registers
+ ; R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ ;PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ ;MOV R4, R8
+ ;MOV R5, R9
+ ;MOV R6, R10
+ ;MOV R7, R11
+ ;PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ ;PUSH {LR} ; Store link register (return address)
+ ;MRS R3, PSR ; Store xPSR to 8-bytes stack aligment
+ ;PUSH {R3}
+
+ ; R13-R25, r27(fp), blink, status32
+ PUSH r13
+ PUSH r14
+ PUSH r15
+ PUSH r16
+ PUSH r17
+ PUSH r18
+ PUSH r19
+ PUSH r20
+ PUSH r21
+ PUSH r22
+ PUSH r23
+ PUSH r24
+ PUSH r25
+ PUSH gp
+ PUSH fp
+ PUSH ilink
+ PUSH r30
+ PUSH blink
+ MOV r13, EE_AUX_STATUS32
+ LR r14, [r13]
+ PUSH r14
+
+ ;R0 == tid
+ ;LSLS R0, R0, #2 ; R0 = tid << 2
+ ;LDR R1, =EE_terminate_real_th_body ; R1 == EE_terminate_real_th_body[tid]
+ ;ADD R1, R1, R0
+ ;LDR R1, [R1]
+ ASL r0, r0, 2
+ MOV r1, EE_terminate_real_th_body
+ ADD r1, r1, r0
+ LD r1, [r1]
+
+ ; Save the stack pointer (including space for registers)
+ ; R2 == & EE_terminate_data[tid]
+ ;LDR R2, =EE_terminate_data
+ ;ADD R2, R2, R0
+ ;MRS R3, MSP ; Get the stack pointer
+ ;STR R3, [R2] ; Save stack pointer
+ MOV r2, EE_terminate_data
+ ADD r2, r2, r0
+ ST sp, [r2]
+
+ ;Start the thread body
+ ;BLX R1
+ JL [r1]
+
+ ; The task terminated with a return: do the usual cleanup
+ ;LDR R0, =EE_thread_not_terminated
+ ;BLX R0
+ MOV r0, EE_thread_not_terminated
+ JL [r0]
+
+ ; NOTE: code never executed because EE_thread_not_terminated()
+ ;POP {R2} ; Get xPSR from stack
+ ;LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ;ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ ;MSR XPSR_NZCVQ, R2 ; Restore xPSR register
+ ;POP {R0} ; Get link register from stack
+ ;MOV LR, R0 ; Restore the link register
+ POP r2
+ MOV r3, EE_AUX_STATUS32
+ SR r2, [r3]
+ POP blink
+ POP r30
+ POP ilink
+ POP fp
+ POP gp
+
+ ; Restore R8, R9, R10, R11 from stack
+ ;POP {R4-R7}
+ ;MOV R8, R4
+ ;MOV R9, R5
+ ;MOV R10, R6
+ ;MOV R11, R7
+ ;POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ POP r25
+ POP r24
+ POP r23
+ POP r22
+ POP r21
+ POP r20
+ POP r19
+ POP r18
+ POP r17
+ POP r16
+ POP r15
+ POP r14
+ POP r13
+
+ ;BX LR ; Return
+ J [blink]
+
+ .size EE_hal_terminate_savestk, . - EE_hal_terminate_savestk
+
+
+;*******************************************************************************
+
+;void EE_hal_terminate_task(EE_TID tid) NORETURN
+ .type EE_hal_terminate_task, @function
+ .align 4
+EE_hal_terminate_task:
+
+ ; R0 == tid
+
+ ; Restore the stack pointer
+ ; R1 == & EE_terminate_data[tid]
+ ;LSLS R0, R0, #2 ; R0 = tid << 2
+ ;LDR R1, =EE_terminate_data ; R1 == & EE_terminate_data[tid]
+ ;ADD R1, R1, R0
+ ;LDR R2, [R1]
+ ;MSR MSP, R2
+ ASL r0, r0, 2
+ MOV r1, EE_terminate_data
+ ADD r1, r1, r0
+ LD r2, [r1]
+ MOV sp, r2
+
+ ;POP {R2} ; Get xPSR from stack
+ ;LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ;ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ ;MSR XPSR_NZCVQ, R2 ; Restore xPSR register
+ ;POP {R3} ; Get link register from stack
+ ;MOV LR, R3 ; Restore the link register
+ POP r2
+ KFLAG r2
+ POP blink
+ POP r30
+ POP ilink
+ POP fp
+ POP gp
+
+ ; Restore R8, R9, R10, R11 from stack
+ ;POP {R4-R7}
+ ;MOV R8, R4
+ ;MOV R9, R5
+ ;MOV R10, R6
+ ;MOV R11, R7
+ ;POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ POP r25
+ POP r24
+ POP r23
+ POP r22
+ POP r21
+ POP r20
+ POP r19
+ POP r18
+ POP r17
+ POP r16
+ POP r15
+ POP r14
+ POP r13
+
+ ;BX LR ; Return
+ J [blink]
+
+ .size EE_hal_terminate_task, . - EE_hal_terminate_task
+
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_utils.c b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_utils.c
new file mode 100644
index 0000000..1de7d2b
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/arc_em6/src/ee_utils.c
@@ -0,0 +1,186 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/**
+ * @file ee_utils.c
+ * @brief Functions to initialize the RTOS services
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#include <ee_internal.h>
+#include <ee_irq.h>
+#include <mt_defs.h>
+
+extern void EE_set_switch_context_pri(void);
+
+/* Function used to calculate the initialize the system */
+void EE_system_init(void)
+{
+ register EE_UREG flags;
+
+ flags = EE_hal_suspendIRQ();
+
+ /*
+ * Set the priority of PendSV to the minimum one
+ * PendSV is the software interrupt used for context switch
+ */
+ EE_set_switch_context_pri();
+
+ /*
+ * Set the priority of PendSV to the minimum one
+ * PendSV is the software interrupt used for context switch
+ */
+ /* EE_set_switch_context_pri(); */
+
+
+ EE_hal_resumeIRQ(flags);
+}
+
+extern void EE_arc_em6_change_context_return_point(void);
+void EE_init_task_private_stack(void)
+{
+ int32_t i;
+
+ for (i = EE_TC_SYSTEM_TOS_SIZE - 1; i > 0; i--) {
+ EE_STACK_T *s = (EE_STACK_T *)EE_tc_system_tos[i].SYS_tos;
+
+ /* task end frame
+ * | STATUS32 |
+ * | PC |
+ * | LP_COUNT |
+ * | LP_START |
+ * | LP_END |
+ * | BLINK |
+ * | R25~R0 |
+ * | BTA |
+ * | GP |
+ * | FP |
+ * | ILINK |
+ * | R30 |
+ */
+ *(--s) = 0x8000001E; /* enable IRQ, IRQ prio level 15 */
+ *(--s) = (EE_STACK_T)__end; /* an infinite loop after return from main */
+ *(--s) = 0;
+ *(--s) = 0;
+ *(--s) = 0;
+ *(--s) = (EE_STACK_T)__end; /* an infinite loop after return from main */
+ *(--s) = 25;
+ *(--s) = 24;
+ *(--s) = 23;
+ *(--s) = 22;
+ *(--s) = 21;
+ *(--s) = 20;
+ *(--s) = 19;
+ *(--s) = 18;
+ *(--s) = 17;
+ *(--s) = 16;
+ *(--s) = 15;
+ *(--s) = 14;
+ *(--s) = 13;
+ *(--s) = 12;
+ *(--s) = 11;
+ *(--s) = 10;
+ *(--s) = 9;
+ *(--s) = 8;
+ *(--s) = 7;
+ *(--s) = 6;
+ *(--s) = 5;
+ *(--s) = 4;
+ *(--s) = 3;
+ *(--s) = 2;
+ *(--s) = 1;
+ *(--s) = 0;
+ *(--s) = 0;
+ *(--s) = (EE_STACK_T)_s_sdata;
+ *(--s) = 27;
+ *(--s) = 29;
+ *(--s) = 30;
+ /* task context frame
+ * | r30 |
+ * | LP_COUNT |
+ * | LP_START |
+ * | LP_END |
+ * | BLINK |
+ * | ILINK |
+ * | FP |
+ * | GP |
+ * | R25~R1 |
+ * | BTA |
+ */
+ *(--s) = 30;
+ *(--s) = 0;
+ *(--s) = 0;
+ *(--s) = 0;
+ *(--s) = (EE_STACK_T)EE_arc_em6_change_context_return_point;
+ *(--s) = 29;
+ *(--s) = 27;
+ *(--s) = (EE_STACK_T)_s_sdata;
+ *(--s) = 25;
+ *(--s) = 24;
+ *(--s) = 23;
+ *(--s) = 22;
+ *(--s) = 21;
+ *(--s) = 20;
+ *(--s) = 19;
+ *(--s) = 18;
+ *(--s) = 17;
+ *(--s) = 16;
+ *(--s) = 15;
+ *(--s) = 14;
+ *(--s) = 13;
+ *(--s) = 12;
+ *(--s) = 11;
+ *(--s) = 10;
+ *(--s) = 9;
+ *(--s) = 8;
+ *(--s) = 7;
+ *(--s) = 6;
+ *(--s) = 5;
+ *(--s) = 4;
+ *(--s) = 3;
+ *(--s) = 2;
+ *(--s) = 1;
+ *(--s) = 0;
+ EE_tc_system_tos[i].SYS_tos = s;
+ }
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/README.txt b/src/bsp/hsm/os/erika2/pkg/cpu/common/README.txt
new file mode 100644
index 0000000..2dcd654
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/README.txt
@@ -0,0 +1,10 @@
+This directory contains a reference implementation of part of the HAL that
+should be usable as it is in many platforms. A new porting should use this
+implementation when possible, or an ad-hoc implementation under cpu/XXX
+otherwise.
+
+Please do not modify these files to accommodate some quirks of your
+architecture. Instead, make a copy of them and create a branch under your
+cpu/XXX directory or whatever. Implementations that can potentially be useful on
+many platforms are welcome; e.g., "inc/ee_compiler_gcc.h" works only for Gcc,
+but it should work across all platforms where Gcc is available.
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/cfg.mk
new file mode 100644
index 0000000..a5a68ad
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/cfg.mk
@@ -0,0 +1,121 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2009 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2009 Bernardo Dal Seno
+## 2011 Giuseppe Serano: pic30 integration.
+## 2012 Giuseppe Serano: cortex_mx integration.
+## 2012 Giuseppe Serano: avr8 integration.
+## 2014 Martin Hoffmann: x86 integration.
+## 2014 Christoph Kreuzberger: cortex_rx integration.
+
+# Atmel AVR8
+ifeq ($(call iseeopt, __AVR8__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+# x86
+ifeq ($(call iseeopt, __X86__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+# Microchip dsPIC
+ifeq ($(call iseeopt, __PIC30__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+# Lattice Mico32
+ifeq ($(call iseeopt, __LM32__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(or $(call iseeopt, __PPCE200ZX__), $(call iseeopt, __PPCE200Z7__)), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __ESI_RISC__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __MSP430__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __CORTEX_MX__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __RX200__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, EE_TRICORE__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, EE_CORTEX_AX_XENPV__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __MC9S12__), yes)
+EE_HC12_COMMON=YES
+endif
+ifeq ($(call iseeopt, __HCS12XS__), yes)
+EE_HC12_COMMON=YES
+endif
+ifeq ($(EE_HC12_COMMON), YES)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
+
+ifeq ($(call iseeopt, __CORTEX_RX__), yes)
+EE_SRCS += pkg/cpu/common/src/ee_hal_structs.c
+EE_SRCS += pkg/cpu/common/src/ee_context.c
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/memprot_generator.awk b/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/memprot_generator.awk
new file mode 100644
index 0000000..b69bf7d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/cfg/memprot_generator.awk
@@ -0,0 +1,209 @@
+#!/usr/bin/awk
+
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2011 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+# Script to generate configuration files with memory protection active
+# Author: 2011 Bernardo Dal Seno
+
+# This script expects a list of OS-application parameters followed by a
+# template; the first line that doesn't seem to contain OS-application
+# parameters is considered to be the first line of the template. The script is
+# a parser organized as a finite-state machine (there are only two recursion
+# levels, so no stack is needed). Whenever a FOR_EACH_APP marker is encoutered,
+# text begins accumulating inside the sec_templ array, one row for every chunk
+# of text enclosed between any two markers (INNER_FOR_EACH_PREV_APP and
+# INNER_END_EACH_PREV_APP included). When END_EACH_APP is encoutered,
+# print_app-sections() is called, which runs through the content of sec_templ
+# once for each OS-application. print_sec_part() does the variable substition
+# and also handles the repetition of the innner sections.
+#
+# Parser states:
+# 0: parsing of application list
+# 1: parsing of linker script template, outside any section
+# 2: beginning of an application section
+# 3: reading an application section
+# 4: printing out an application section
+# 5: beginning of a nested application section
+# 6: reading a nested application section
+# 7: exiting from a nested application section
+#
+# Please note that "section" above refers to a chunk of text between two markers
+# in a template, not to a data or code section inside an object file
+
+BEGIN {
+ state = 0 # State of the parser (see above)
+ numapps = 0 # Number of applications
+}
+
+# Other variables:
+# sec_part: Current part of a section template (an integer, counting from 0)
+# sec_templ: Section template, a two-dimension array
+# sec_templ[i, "templ"]: text, possibly containing variables to
+# be substituted
+# sec_templ[i, "type"]: 1 if the text comes from a nested
+# section, 0 otherwise
+# app_type: Type of applictions the current section applies to (1 = trusted,
+# 0 = unstrusted, -1 = both)
+
+/[_A-Za-z0-9]+[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)/ {
+ if (state == 0) {
+ apps[numapps, "APP_NAME"] = $1
+ apps[numapps, "APP_BASE"] = $2
+ apps[numapps, "APP_SIZE"] = $3
+ apps[numapps, "APP_TYPE"] = $4
+ numapps += 1
+ }
+}
+
+! /[_A-Za-z0-9]+[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)[[:space:]]+(0x[0-9a-fA-F]+|[0-9]+)/ {
+ if (state == 0) {
+ state = 1
+ }
+}
+
+/FOR_EACH_APP/ {
+ if (state == 1) {
+ sec_part = 0
+ delete sec_templ
+ sec_templ[sec_part, "templ"] = ""
+ sec_templ[sec_part, "type"] = 0
+ app_type = -1
+ state = 2
+ } else {
+ print "FOR_EACH_APP found in the wrong context" >> "/dev/stderr"
+ exit
+ }
+}
+
+/INNER_FOR_EACH_PREV_APP/ {
+ if (state == 3) {
+ sec_part += 1
+ sec_templ[sec_part, "templ"] = ""
+ sec_templ[sec_part, "type"] = 1
+ state = 5
+ } else {
+ print "INNER_FOR_EACH_PREV_APP found in the wrong context" \
+ >> "/dev/stderr"
+ exit
+ }
+}
+
+/INNER_END_EACH_PREV_APP/ {
+ if (state == 6) {
+ sec_part += 1
+ sec_templ[sec_part, "templ"] = ""
+ sec_templ[sec_part, "type"] = 0
+ state = 7;
+ } else {
+ print "INNER_END_EACH_PREV_APP found in the wrong context" \
+ >> "/dev/stderr"
+ exit
+ }
+}
+
+/END_EACH_APP/ {
+ if (state == 3) {
+ state = 4
+ print_app_sections(sec_templ, sec_part, app_type)
+ } else {
+ print "END_EACH_APP found in the wrong context" >> "/dev/stderr"
+ exit
+ }
+}
+
+{
+ if (state == 1) {
+ printf("%s\n", $0)
+ } else if (state == 2) {
+ state = 3
+ } else if (state == 3 || state == 6) {
+ sec_templ[sec_part, "templ"] = \
+ sec_templ[sec_part, "templ"] $0 "\n"
+ } else if (state == 4) {
+ state = 1
+ } else if (state == 5) {
+ state = 6
+ } else if (state == 7) {
+ state = 3
+ }
+}
+
+
+# Print the application section template `sec_templ', once for each application
+# of the given type, after variable substitution. `num_parts' is the number of
+# parts composing the section. `app_type' is 1 for trusted applications, 0 for
+# untrusted applications, -1 for both.
+function print_app_sections(sec_templ, num_parts, app_type, i, j)
+{
+ for (j = 0; j < numapps; ++j) {
+ for (i = 0; i <= num_parts; ++i) {
+ print_sec_part(sec_templ[i, "templ"], \
+ sec_templ[i, "type"], j, app_type)
+ }
+ }
+}
+
+
+# Print the part `templ', from an application section. If `type' is 1 (nested
+# part) print the template once for each application `app' up to the current
+# one; if it is 0, print the template for the current application `app.
+# `app_type' is used to filter applications: it is 1 for trusted applications, 0
+# for untrusted applications, -1 for both.
+function print_sec_part(templ, type, app, app_type, t, first, last, j)
+{
+ if (type == 1) {
+ first = 0
+ last = app - 1
+ } else {
+ first = app
+ last = app
+ }
+
+ for (j = first; j <= last; ++j) {
+ if (app_type == -1 || app_type == apps[j, "APP_TYPE"]) {
+ t = templ
+ gsub("\\$\\{APP_NAME\\}", apps[j, "APP_NAME"], t)
+ gsub("\\$\\{APP_BASE\\}", apps[j, "APP_BASE"], t)
+ gsub("\\$\\{APP_SIZE\\}", apps[j, "APP_SIZE"], t)
+ printf("%s", t)
+ }
+ }
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/README.txt b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/README.txt
new file mode 100644
index 0000000..988b991
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/README.txt
@@ -0,0 +1,6 @@
+The header files contained in this directory should be building blocks for other
+architectures. They should not include each other, nor include
+architecture-dependent headers; it is okay to include general headers, like
+"ee.h" or "ee_internals.h" (please notice that this is the one sitting in
+'ee/pkg'). In this way, an implementation is free to use only the parts
+needed/suitable for a particular architecture.
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccrx.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccrx.h
new file mode 100644
index 0000000..f03ca59
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccrx.h
@@ -0,0 +1,83 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for Keil-uVision-MDK-Lite
+ * Derived from pkg/cpu/pic30/inc/ee_compiler.h
+ * Author: 2012 Gianluca Franchino
+ */
+
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_CCRX__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_CCRX__
+
+#include <machine.h>
+
+#define __ALWAYS_INLINE__
+
+/* __INLINE__ is a macro already used by a lot of libraries: protect it for
+ * integration */
+#ifndef __INLINE__
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static inline
+#endif
+#endif /* !__INLINE__ */
+
+/*the compiler has not "noreturn" support*/
+/* #define NORETURN __attribute__ ((noreturn)) */
+#define NORETURN
+
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_KEIL__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccs.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccs.h
new file mode 100644
index 0000000..75343fb
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_ccs.h
@@ -0,0 +1,74 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for TI CCSv4 tms470 compiler
+ * Author: 2011 Giuseppe Serano
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .s files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_CCS__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_CCS__
+
+#include "cpu/common/inc/ee_compiler_gcc.h"
+/* #include "cpu/common/inc/ee_stdint.h" */
+/* #include "cpu/common/inc/ee_types.h" */
+
+#ifndef __CORTEX_RX__
+
+#ifdef __ASM
+#undef __ASM
+#endif
+#define __ASM __asm
+
+#ifdef __IRQ
+#undef __IRQ
+#endif
+#define __IRQ interrupt
+
+#endif /* !__CORTEX_RX__ */
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_CCS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_codewarrior.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_codewarrior.h
new file mode 100644
index 0000000..54509f7
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_codewarrior.h
@@ -0,0 +1,83 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for Freescale CodeWarrior compiler
+ * Author: 2011 Bernardo DalSeno
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .S files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_CODEWARRIOR__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_CODEWARRIOR__
+
+/* __INLINE__ is a macro already used by a lot of libraries: protect it for
+ * integration */
+#ifndef __INLINE__
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static inline
+#endif
+#endif /* !__INLINE__ */
+
+#define __ALWAYS_INLINE__
+
+#define NORETURN
+
+#define EE_COMPILER_ALIGN(a) __attribute__((aligned(a)))
+#define EE_COMPILER_SECTION(s) __declspec(section s)
+#define EE_COMPILER_KEEP __attribute((force_export))
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_CODEWARRIOR__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_diab.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_diab.h
new file mode 100644
index 0000000..33cf450
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_diab.h
@@ -0,0 +1,127 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2010 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for DCC
+ * Derived from pkg/cpu/mico32/inc/ee_compiler.h
+ * Author: 2010 Fabio Checconi
+ */
+
+/* Infinion modifications, to integrate Ifx Build environment:
+ * Author:
+ * Ashok Abbi, <Ashok.Abbi@infineon.com> 18.07.2013
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .S files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef PKG_CPU_COMMON_INC_EE_COMPILER_DIAB_H
+#define PKG_CPU_COMMON_INC_EE_COMPILER_DIAB_H
+
+/* __INLINE__ is a macro already used by a lot of libraries: protect it for
+ * integration */
+#ifndef __INLINE__
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+#else
+#define __INLINE__ static inline
+#endif
+#endif /* !__INLINE__ */
+
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+
+#define __ALWAYS_INLINE__
+
+#define EE_FAR
+
+#define __NEVER_INLINE__ __attribute__ ((noinline))
+
+#define NORETURN __attribute__ ((noreturn))
+
+#define EE_COMPILER_ALIGN(a) __attribute__((aligned(a)))
+#define EE_COMPILER_SECTION(s) __attribute__((section(s)))
+#define EE_COMPILER_KEEP
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+/* Diab Pragma Header/Footer for "pragma section" used in memory protection */
+#define PRAGMA_SECTION_BEGIN_SYS_STACK DATA ".stack" ".stack"
+#define PRAGMA_SECTION_END_SYS_STACK DATA
+
+/* Pragma macros for Multicore applications */
+/* for const variables */
+#define EE_SHARED_CONST_BEGIN CONST "ee_mcglobalc"
+#define EE_SHARED_SCONST_BEGIN SCONST "ee_mcglobalc"
+
+/* for variables inside the rapid access area (initialized data) */
+#define EE_SHARED_BEGIN DATA "ee_mcglobald" "ee_mcglobalu"
+#define EE_SHARED_FAST_BEGIN SDATA "ee_fast_mcglobald" "ee_fast_mcglobalu"
+
+/* for variables outside the rapid access area (initialized data) */
+#define EE_SHARED_SLOW_BEGIN \
+ EE_PREPROC_JOIN(SDATA "ee_fast_mcglobald" "ee_fast_mcglobalu", far - absolute)
+
+/* for variables inside the rapid access area (uninitialized data) */
+#define EE_SHARED_NOTINIT_BEGIN DATA "" "ee_mcglobalu"
+#define EE_SHARED_FAST_NOTINIT_BEGIN SDATA "" "ee_fast_mcglobalu"
+
+/* for variables outside the rapid access area (uninitialized data) */
+#define EE_SHARED_SLOW_NOTINIT_BEGIN \
+ EE_PREPROC_JOIN(SDATA "" "ee_fast_mcglobalu", far - absolute)
+
+/* Pragma section tail for DATA/SDATA classes */
+#define EE_SHARED_END DATA
+#define EE_SHARED_FAST_OR_SLOW_END SDATA
+
+/* Pragma section tail for CONST/SCONST classes */
+#define EE_SHARED_CONST_END CONST
+#define EE_SHARED_SCONST_END SCONST
+
+#define EE_barrier() _nop()
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_DIAB__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_gcc.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_gcc.h
new file mode 100644
index 0000000..345ec7f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_gcc.h
@@ -0,0 +1,103 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for Gcc
+ * Derived from pkg/cpu/pic30/inc/ee_compiler.h
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .S files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_GCC__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_GCC__
+
+/* __INLINE__ is a macro already used by a lot of libraries: protect it for
+ * integration */
+#ifndef __INLINE__
+#if defined(__NO_INLINE__) || defined(__STRICT_ANSI__)
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static inline
+#endif /* __NO_INLINE_ || __STRICT_ANSI__ */
+#endif /* !__INLINE__ */
+
+#define __ALWAYS_INLINE__ __attribute__((always_inline))
+#define __NEVER_INLINE__ __attribute__((noinline))
+
+#define NORETURN __attribute__ ((noreturn))
+
+#define EE_FAR
+
+#define EE_COMPILER_ALIGN(a) __attribute__((aligned(a)))
+#define EE_COMPILER_SECTION(s) __attribute__((section(s)))
+#define EE_COMPILER_KEEP __attribute__((used))
+#define EE_COMPILER_IRQ __attribute__((interrupt("IRQ")))
+
+/* FIXME: MISRA states that symbols and defines with leading two underscores are
+ * reserverd for compilers: the following have to be changed (EG: I suggest
+ * something like EE_ASM and EE_IRQ). */
+#ifndef __ASM
+#define __ASM __asm__
+#endif
+#define __IRQ EE_COMPILER_IRQ
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+#define EE_PREPROC_EVAL(e) e
+
+/* Software "memory barrier" (or "memory clobber") to enforce NOT code
+ * reordering. At compile level.
+ * http://www.nongnu.org/avr-libc/user-manual/optimization.html */
+#define EE_barrier() \
+ __asm__ volatile ("" : : : "memory")
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_GCC__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_iar.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_iar.h
new file mode 100644
index 0000000..7e0064e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_iar.h
@@ -0,0 +1,82 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for IAR compiler
+ * Author: 2011 Gianluca Franchino
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .s files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_IAR__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_IAR__
+
+#include "cpu/common/inc/ee_stdint.h"
+#include "cpu/common/inc/ee_types.h"
+#include <cmsis_iar.h>
+
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static inline
+#endif
+
+#define __ALWAYS_INLINE__ /* __attribute__ does not exist under IAR*/
+ /* we should use #pragma inline=forced */
+#define __ASM __asm
+#define __IRQ __irq
+
+#define NORETURN __noreturn
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_IAR__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_keil.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_keil.h
new file mode 100644
index 0000000..3aa0455
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_keil.h
@@ -0,0 +1,83 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Compiler-dependent definitions for Keil-uVision-MDK-Lite
+ * Derived from pkg/cpu/pic30/inc/ee_compiler.h
+ * Author: 2011 Giuseppe Serano
+ */
+
+/* This file MUST contain only #defines, because it is also included
+ * by the .S files */
+
+/*
+ * Compiler dependent interface
+ */
+
+#ifndef __INCLUDE_CPU_COMMON_EE_COMPILER_KEIL__
+#define __INCLUDE_CPU_COMMON_EE_COMPILER_KEIL__
+
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static __inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static __inline
+#endif
+
+#define __ALWAYS_INLINE__ __attribute__((always_inline))
+
+#define NORETURN __attribute__ ((noreturn))
+
+#define __ASM __asm
+#define __IRQ __irq
+
+#define EE_COMPILER_ALIGN(a) __attribute__((aligned(a)))
+#define EE_COMPILER_SECTION(s) __attribute__((section(s)))
+#define EE_COMPILER_KEEP __attribute((used))
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+#endif /* __INCLUDE_CPU_COMMON_EE_COMPILER_KEIL__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_tasking.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_tasking.h
new file mode 100644
index 0000000..1fb6093
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_compiler_tasking.h
@@ -0,0 +1,154 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_compiler_tasking.h
+ * @brief Compiler-dependent definitions for TASKING
+ * This file has been generated for TASKING 4.0r1.
+ * You can find TASKING documentation pdf file for compiler at:
+ * http://www.tasking.com/support/tricore/tc_user_guide_v4.0.pdf
+ * In following comments, sometime, paragraph reference of this document
+ * are added.
+ * @author Errico Guidieri
+ * @date 2012
+ */
+#ifndef INCLUDE_EE_COMPILER_TASKING_H__
+#define INCLUDE_EE_COMPILER_TASKING_H__
+
+/******************************************************************************
+* TASKING implements the C99 standard pragma operator that let you embed
+* pragmas inside macros.
+* So where will be possibible we'll use pragmas instead that attributes,
+* beacuse more 'standard' and preferred by MISRA-C.
+* (1.7. Pragmas to Control the Compiler)
+* Syntax for _Pragma operator:
+* _Pragma("[label:]pragma-spec pragma-arguments [on|off|default|restore]")
+******************************************************************************/
+/* Used for second level macro expansion and token stringification */
+#define EE_DO_PRAGMA(X) _Pragma(#X)
+/* Aesthetic MACRO to make attributes looks like pragmas */
+#define EE_DO_ATTRIBUTE(X) __attribute__((X))
+
+/* __INLINE__ is a macro already used by a lot of libraries: protect it for
+ * integration */
+#ifndef __INLINE__
+#ifdef __NO_INLINE__
+#define __INLINE__ static
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static
+#else
+#define __INLINE__ static inline
+/* Used to declare an inline function before the actual definition */
+#define __DECLARE_INLINE__ static inline
+#endif
+#endif /* !__INLINE__ */
+
+/* Empty because redundant with the keyword inline. 1.6. Attributes */
+#define __ALWAYS_INLINE__
+
+#define __NEVER_INLINE__ EE_DO_PRAGMA(noinline)
+/* For noreturn attribute there'is not pragma equivalence */
+#define NORETURN EE_DO_ATTRIBUTE(noreturn)
+/* "Maybe Attribute" not documented but originally used in startup code.
+ * It cannot be used with the construct __attribute__, I don't know
+ * why because, as I said, is not documented. */
+#define JUMP __jump__
+#define EE_FAR __far
+/* Alignment, Section, Used attributes as are used in GCC compiler */
+/* attribute __align() (1.1.4. Changing the Alignment: __align()) */
+#define EE_COMPILER_ALIGN(a) EE_DO_ATTRIBUTE(__align(a))
+#define EE_COMPILER_SECTION(s) EE_DO_ATTRIBUTE(section(s))
+#define EE_COMPILER_KEEP EE_DO_ATTRIBUTE(used) EE_DO_ATTRIBUTE(protect)
+
+/* More useful attributes */
+#define EE_COMPILER_UNUSED EE_DO_ATTRIBUTE(unused)
+/* For Weak attribute exist equivalent pragma */
+#define EE_COMPILER_WEAK EE_DO_PRAGMA(weak)
+#define EE_COMPILER_EXPORT EE_DO_ATTRIBUTE(export)
+#define EE_COMPILER_EXTERN(f) EE_DO_PRAGMA(extern f)
+
+/*
+ * I will use label pragmas (1.7. Pragmas to Control the Compiler -
+ * Label Pragmas) for alignment and sections where I should not share
+ * code between TASKING and GCC. I do that to minimize the need of
+ * "#pragma ... restore" statments.
+ */
+#define EE_PRAGMA_ALIGN(label, align_value) \
+ EE_DO_PRAGMA(label: align align_value)
+#define EE_PRAGMA_SECTION(label, section_name) \
+ EE_DO_PRAGMA(label: section all #section_name)
+
+/* Interrupt Function qualifier (1.10.4. Interrupt and Trap Functions) */
+
+/* declare ivec_prio priority interrupt handler (priority and entry ID
+ * are the same thing in TriCore). */
+#define EE_INTERRUPT(ivec_prio) __interrupt(ivec_prio)
+/* declare trap_class trap handler. (It will placed in Vector Table) */
+#define EE_TRAP(trap_class) __trap_fast(trap_class)
+
+#ifdef __CORE_TC16X__
+/* EG: sii sicuro che __MSRP__ sia veramente la macro per il multicore */
+#ifdef __MSRP__
+#define EE_VECTOR_TABLE __vector_table(EE_CURRENTCPU)
+#else /* __MSRP__ */
+/* In sigle-core the main CPU is the one with CPU_ID = 0 */
+#define EE_VECTOR_TABLE __vector_table(0)
+#endif /* __MSRP__ */
+#else /* __CORE_TC16X__ */
+/* Vector Table declaration makes sense only for last multicore chips
+ * (TC16X) */
+#define EE_VECTOR_TABLE
+#endif
+
+/* This define is needed to enhance equivalence between GCC compiler and
+ * TASKING compiler so they can share mostly of the code. */
+#define asm __asm
+
+/* Macros used to encapsulate # and ## operators; used to enforce the expected
+ * evaluation order of arguments */
+#define EE_PREPROC_JOIN(a, b) a ## b
+#define EE_PREPROC_STRING(s) # s
+
+/* Software "memory barrier" (or "memory clobber") to enforce NOT code
+ * reordering. At compile level.
+ * http://www.nongnu.org/avr-libc/user-manual/optimization.html */
+#define EE_barrier() \
+ __asm volatile ("" : : : "memory")
+
+#endif /* INCLUDE_EE_COMPILER_TASKING_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_context.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_context.h
new file mode 100644
index 0000000..12bc0c4
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_context.h
@@ -0,0 +1,235 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2010 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Context switch functions used in HAL implementations, to be included by a
+ * specific ee_internal.h header.
+ * Derived from pkg/cpu/pic30/inc/ee_internal.h
+ * Author: 2009-2010 Bernardo Dal Seno
+ */
+
+#ifndef PKG_CPU_COMMON_INC_EE_CONTEXT_H
+#define PKG_CPU_COMMON_INC_EE_CONTEXT_H
+
+/*
+ * Instructions
+ *
+ * The monostack part is complete (obviously, the functions to disable/enable
+ * interrupts are not included here). For the multistack part you have to
+ * provide two additional things:
+ * 1. An assembly implementation of EE_std_change_context_multi(); see below.
+ * 2. A #define directive for EE_hal_active_tos, which is just an alias for the
+ * actual architecture-dependent variable. This variable contains the index of
+ * the current stack.
+ */
+
+/* After a task terminates, the scheduler puts the id of the new task to launch
+ * or switch to in this variable. If the thread is stacked, its id is marked
+ * so.
+ */
+extern EE_TID EE_std_endcycle_next_tid;
+
+
+/* The multistack version must be implemented in ASM; no standard
+ * implementation, sorry. This is the only function that performs context
+ * switching. The multistack version doesn't jump to the task body if its TID
+ * has been marked as stacked. This is used to switch to a task that has been
+ * suspend by a previous call to EE_std_change_context(). */
+#ifdef __MONO__
+__DECLARE_INLINE__ void EE_std_change_context(EE_TID tid);
+#endif
+#ifdef __MULTI__
+void EE_std_change_context(EE_TID tid);
+#endif
+/* Pseudo code for EE_std_change_context_multi():
+ * begin:
+ * tos_index = EE_std_thread_tos[tid+1];
+ * if is_not_the_current_stack(tos_index) {
+ * save_callee_saved_registers();
+ * switch_stacks(tos_index);
+ * restore_callee_saved_registers();
+ * }
+ * if (is_not_marked_stacked(tid)) {
+ * tid = EE_std_run_task_code(tid);
+ * goto begin;
+ * }
+ *
+ * Please notice that the "goto begin" is actually a recursive call to
+ * EE_std_change_context_multi(), but in this way there is no stack growing.
+ *
+ * Please notice also that 'tid' must NOT be saved onto the stack before
+ * switching stacks, otherwise when switching from another stack back to the
+ * current one, you would overwrite its value.
+ *
+ * For processors where the return address is saved in a register, that
+ * register must be saved in the stack too.
+ *
+ * switch_stacks() should also update EE_hal_active_tos.
+ */
+
+/* Launch a new task, possibly switching to a different stack, clean up the task
+ * after it ends, and call the scheduler (and switch to other tasks/stacks)
+ * until there are no more tasks to switch to. In the multistack version, also
+ * change the current stack before returning if the scheduler asks for it. */
+__DECLARE_INLINE__ void EE_hal_ready2stacked(EE_TID tid);
+
+
+/* Launch a new task on the current stack, clean up the task after it ends, and
+ * call the scheduler. Return the next task to launch, which is "marked as
+ * stacked" if there is no new task to launch. */
+EE_TID EE_std_run_task_code(EE_TID tid);
+
+
+
+/*
+ * Inline implementations
+ */
+
+#ifdef __MONO__
+
+/* With monostack, we need only the information that the task is stacked. We
+ * don't need to know which task it is, as there is no new stack to switch
+ * to. */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_std_mark_tid_stacked(EE_TID tid)
+{
+ return (EE_TID)-1;
+}
+
+#define EE_std_need_context_change(tid) ((tid) >= 0)
+
+__INLINE__ void __ALWAYS_INLINE__ EE_std_change_context(EE_TID tid)
+{
+ do {
+ tid = EE_std_run_task_code(tid);
+ } while (EE_std_need_context_change(tid));
+}
+
+#endif /* __MONO__ */
+
+
+#ifdef __MULTI__
+
+/* TID_IS_STACKED_MARK must set the most significant bit
+ *
+ * #1
+ * FIXME:
+ * This works only with two's complements architecture. Casting between
+ * signed/unsigned integer in C is defined by value not by representation and
+ * only two's complements grant the the equivalence between the two.
+ *
+ * Standard Section 4.7/2 [conv.integral]:
+ *
+ * If the destination type is unsigned, the resulting value is the least
+ * unsigned integer congruent to the source integer (modulo 2^n where n is
+ * the number of bits used to represent the unsigned type).
+ *
+ * Note: In a two's complement representation, this conversion is conceptual
+ * and there is no change in the bit pattern (if there is no truncation).
+ */
+__INLINE__ EE_UTID __ALWAYS_INLINE__ EE_std_mark_tid_stacked(EE_TID tid)
+{
+ return (EE_UTID)(tid) | (EE_UTID)TID_IS_STACKED_MARK;
+}
+
+/* Check if the TID is Marked Stacked */
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_std_tid_is_marked_stacked(EE_TID tid)
+{
+ return ((EE_UTID)(tid) & TID_IS_STACKED_MARK) != 0U;
+}
+
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_std_need_context_change(EE_TID tid)
+{
+ EE_UTID utid;
+ EE_TYPEBOOL need_context_change;
+
+ if (EE_std_tid_is_marked_stacked(tid)) {
+ /* Unmark the tid to access the EE_std_thread_tos, otherwise undefined
+ * behavior. (Index out of arrays boundaries)
+ * FIXME: #1
+ */
+ utid = (((EE_UTID)tid + 1U)) & (~(EE_UTID)TID_IS_STACKED_MARK);
+ need_context_change = (EE_hal_active_tos != EE_std_thread_tos[utid]);
+ } else {
+ need_context_change = EE_TRUE;
+ }
+
+ return need_context_change;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_stkchange(EE_TID tid)
+{
+ EE_UTID tmp = EE_std_mark_tid_stacked(tid);
+
+ EE_std_change_context((EE_TID)tmp);
+}
+
+#endif /* __MULTI__ */
+
+
+/* The functions below should work for both the monostack and multistack
+ * versions of the kernel, thanks to the macros defined above. In the mono
+ * version, all the stack-related stuff is ignored. */
+__INLINE__ void EE_hal_ready2stacked(EE_TID tid)
+{
+ EE_std_change_context(tid);
+}
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_ready(EE_TID tid)
+{
+ EE_std_endcycle_next_tid = tid;
+}
+
+#ifdef __MULTI__
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_stacked(EE_TID tid)
+{
+ EE_UTID utid_tmp = (EE_UTID)EE_std_mark_tid_stacked(tid);
+
+ EE_std_endcycle_next_tid = (EE_TID)utid_tmp;
+}
+#else
+#define EE_hal_endcycle_stacked(x) EE_hal_endcycle_stacked_impl()
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_stacked_impl(void)
+{
+ EE_std_endcycle_next_tid = ((EE_TID)-1);
+}
+#endif
+
+#endif /* __INCLUDE_CPU_COMMON_EE_CONTEXT__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_hal_structs.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_hal_structs.h
new file mode 100644
index 0000000..64aa724
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_hal_structs.h
@@ -0,0 +1,123 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Structures commonly used in HAL implementations, to be included by a specific
+ * ee_cpu.h header.
+ * Derived from pkg/cpu/pic30/inc/ee_cpu.h
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+
+#ifndef PKG_CPU_COMMON_INC_EE_HAL_STRUCTS_H
+#define PKG_CPU_COMMON_INC_EE_HAL_STRUCTS_H
+
+
+/*************************************************************************
+* HAL Constants
+*************************************************************************/
+
+/* defines the NULL invalid pointer */
+#include <stddef.h>
+
+
+/*************************************************************************
+* HAL Types
+*************************************************************************/
+
+/*
+ * This structure is used by the Multistack HAL to contain the
+ * information about a "stack", that is composed by a user stack
+ * (SYS-mode) and a system stack (IRQ-mode). This type is
+ * used internally by the HAL and is not used by the Kernels.
+ */
+#ifdef __MULTI__
+struct EE_TOS {
+ EE_ADDR SYS_tos;
+#ifdef EE_STACK_MONITORING__
+ EE_ADDR SYS_bos;
+#endif /* EE_STACK_MONITORING__ */
+};
+#endif /* __MULTI__ */
+
+
+/*************************************************************************
+* HAL Variables
+*************************************************************************/
+
+/* Thread function body pointer */
+extern const EE_THREAD_PTR EE_hal_thread_body[EE_MAX_TASK];
+
+#ifdef __MULTI__
+
+/* each task uses a system (IRQ) stack and a user (SYS) stack */
+/* The guard is needed to suppress MISRA warning because only these two
+ * architectures are still using this data structure. */
+#if (defined(__ESI_RISC__)) && (defined(__MSP430__))
+extern struct EE_TOS EE_std_system_tos[];
+#endif
+
+/* std_system_tos[] index that points to the thread tos (one for each thread) */
+extern const EE_UREG EE_std_thread_tos[EE_MAX_TASK + 1];
+
+#if 0
+/* seems never used. to be verified */
+/* std_system_tos[] index that points to the active thread tos */
+extern EE_UREG EE_std_active_tos;
+#endif
+
+#endif /* __MULTI__ */
+
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+
+/* this is a safe place to put sp_sys when EE_hal_terminate_savestk
+ * is called into EE_oo_thread_stub */
+extern EE_UINT32 EE_terminate_data[EE_MAX_TASK];
+
+/* this is the real thread body that is called if the thread use the
+ * TerminateTask function */
+extern const EE_THREAD_PTR EE_terminate_real_th_body[EE_MAX_TASK];
+
+#endif /* __OO_BCCx__ */
+
+
+#endif /* __INCLUDE_CPU_COMMON_EE_HAL_STRUCTS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_irqstub.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_irqstub.h
new file mode 100644
index 0000000..8bfad50
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_irqstub.h
@@ -0,0 +1,138 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2010 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Some IRQ-related stuff.
+ * Author: 2009-2010, Bernardo Dal Seno
+ */
+
+/*******************************************************************************
+ * !!!WARNING!!!
+ * This header depends on "cpu/common/inc/ee_context.h" or your own
+ * implementation of the same. You should include it file before including this
+ * file
+ ******************************************************************************/
+
+#ifndef PKG_CPU_COMMON_INC_EE_IRQSTUB_H
+#define PKG_CPU_COMMON_INC_EE_IRQSTUB_H
+
+/* this bring EE_IRQ_nesting_level definition */
+#include "cpu/common/inc/ee_primitives.h"
+
+/* True if we are inside an interrupt-serving routine */
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_is_inside_ISR_call(void)
+{
+ return EE_IRQ_nesting_level > 0U;
+}
+
+
+/* EE_decrement_IRQ_nesting_level() and EE_increment_IRQ_nesting_level() are
+ * used to keep track of the current IRQ nesting level.
+ * EE_std_enableIRQ_nested() and EE_std_disableIRQ_nested() are used to control
+ * when IRQ nesting is enabled.
+ */
+#if defined(__AS_SC4__)
+/* For SC4 the nesting level is updated inside the prestub and postub */
+__INLINE__ void __ALWAYS_INLINE__ EE_decrement_IRQ_nesting_level(void)
+{
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_increment_IRQ_nesting_level(void)
+{
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_std_enableIRQ_nested(void)
+{
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_std_disableIRQ_nested(void)
+{
+}
+#elif defined(__ALLOW_NESTED_IRQ__)
+__INLINE__ void __ALWAYS_INLINE__ EE_decrement_IRQ_nesting_level(void)
+{
+ --EE_IRQ_nesting_level;
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_increment_IRQ_nesting_level(void)
+{
+ ++EE_IRQ_nesting_level;
+}
+/* EE_std_enableIRQ_nested() and EE_std_disableIRQ_nested() must be defined in
+ * the platform-dependent part, as they dependend on the particular way
+ * interrupts are handled by the CPU. */
+#else
+__INLINE__ void __ALWAYS_INLINE__ EE_decrement_IRQ_nesting_level(void)
+{
+ EE_IRQ_nesting_level = 0U;
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_increment_IRQ_nesting_level(void)
+{
+ EE_IRQ_nesting_level = 1U;
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_std_enableIRQ_nested(void)
+{
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_std_disableIRQ_nested(void)
+{
+}
+#endif
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) || (defined(__OO_ECC1__)) \
+ || (defined(__OO_ECC2__)) || (defined(__AS_SC4__))
+/* Function to be called at the end of a function service interrupt, to execute
+ * clean-up specifiend in Autosar standard */
+__INLINE__ void __ALWAYS_INLINE__ EE_std_end_IRQ_post_stub(void)
+{
+ EE_IRQ_end_post_stub();
+}
+#else /* __OO_BCC1__ || __OO_BCC2__ || __OO_ECC1__ || __OO_ECC2__ */
+#define EE_std_end_IRQ_post_stub() ((void)0)
+#endif /* __OO_BCC1__ || __OO_BCC2__ || __OO_ECC1__ || __OO_ECC2__ */
+
+/* Function to be called at the end of a function servicing an interrupt. Call
+ * the scheduler and launch a new scheduled task (if any), or change the current
+ * stack (if needed); return whenever there is nothing else to do.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_std_after_IRQ_schedule(void)
+{
+ EE_IRQ_end_instance();
+ if (EE_std_need_context_change(EE_std_endcycle_next_tid)) {
+ EE_std_change_context(EE_std_endcycle_next_tid);
+ }
+}
+
+#endif /* PKG_CPU_COMMON_INC_EE_IRQSTUB_H */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_primitives.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_primitives.h
new file mode 100644
index 0000000..3819054
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_primitives.h
@@ -0,0 +1,78 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Functions used in HAL implementations, to be included by a specific
+ * ee_internal.h header.
+ * Derived from pkg/cpu/pic30/inc/ee_internal.h
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+
+#ifndef PKG_CPU_COMMON_INC_EE_PRIMITIVES_H
+#define PKG_CPU_COMMON_INC_EE_PRIMITIVES_H
+
+/*
+ * Nested Interrupts Handling
+ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+extern EE_UREG EE_IRQ_nesting_level;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* can be called with interrupt enabled */
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_hal_get_IRQ_nesting_level(void)
+{
+ return EE_IRQ_nesting_level;
+}
+
+
+#endif /* PKG_CPU_COMMON_INC_EE_PRIMITIVES_H */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_stdint.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_stdint.h
new file mode 100644
index 0000000..bc2fa85
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_stdint.h
@@ -0,0 +1,223 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @brief Definitions of (some) ISO types
+ *
+ * @author Bernardo Dal Seno
+ *
+ * Copyright (C) 2011 Evidence srl
+ */
+
+#ifndef PKG_CPU_COMMON_INC_EE_STDINT_H
+#define PKG_CPU_COMMON_INC_EE_STDINT_H
+
+#if ( \
+ ((defined(__PIC32__)) && (defined(__GNUC__))) || \
+ ( \
+ (defined(__CORTEX_MX__)) && \
+ ( \
+ (defined(__CCS__)) || \
+ (defined(__IAR__)) || \
+ (defined(__KEIL__)) || \
+ (defined(__GNU__)) \
+ ) \
+ ) || \
+ ((defined(__RX200__)) && (defined(__CCRX__))) || \
+ ((defined(__AVR8__)) && (defined(__GNUC__))) \
+ )
+/* When supported, include stdint.h to avoid conflicting definitions of
+ * exact-size types. */
+#include <stdint.h>
+
+#elif (defined(__PPCE200ZX__)) && (defined(__CODEWARRIOR__))
+/* EWL CodeWarrior standard library.
+ * I need all types so I need to eneble C99 support */
+#if defined(_EWL_C99) && (!_EWL_C99)
+#define EE_EWL_C99_FALSE
+#undef _EWL_C99
+#endif /* defined(_EWL_C99) && !_EWL_C99 */
+
+#define _EWL_C99 1
+#include <stdint.h>
+
+#undef _EWL_C99
+#ifdef EE_EWL_C99_FALSE
+#define _EWL_C99 0
+#endif /* EE_EWL_C99_FALSE */
+
+#else
+
+/* No stdint.h. Define types through educated guesses */
+
+#include <limits.h>
+
+/**
+ * @name Basic type representations.
+ * @{ */
+
+#if SCHAR_MAX == 127
+#ifndef UINT8_T
+#define UINT8_T
+typedef unsigned char uint8_t; /**< Unsigned 8 bit integer. */
+#endif
+
+#ifndef INT8_T
+#define INT8_T
+typedef signed char int8_t; /**< Signed 8 bit integer. */
+#endif
+#else
+#error Unable to define a 8-bit types
+#endif
+
+#if INT_MAX == 32767 /* 16-bit architecture */
+#define __EE_INT16 int
+#define __EE_UINT16 unsigned int
+#define __EE_INT32 long
+#define __EE_UINT32 unsigned long
+#elif (INT_MAX == 2147483647) && (SHRT_MAX == 32767) /* 32-bit architecture */
+#define __EE_INT16 short
+#define __EE_UINT16 unsigned short
+#define __EE_INT32 int
+#define __EE_UINT32 unsigned int
+#else /* Unknown architecture */
+#error Unknown/unsupported architecture
+#endif
+
+
+#ifndef UINT16_T
+#define UINT16_T
+typedef __EE_UINT16 uint16_t; /**< Unsigned 16 bit integer. */
+#endif
+
+#ifndef UINT32_T
+#define UINT32_T
+typedef __EE_UINT32 uint32_t; /**< Unsigned 32 bit integer. */
+#endif
+
+#ifndef INT16_T
+#define INT16_T
+typedef __EE_INT16 int16_t; /**< Signed 16 bit integer. */
+#endif
+
+#ifndef INT32_T
+#define INT32_T
+typedef __EE_INT32 int32_t; /**< Signed 32 bit integer. */
+#endif
+
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+#ifndef INT_FAST8_T
+#define INT_FAST8_T
+typedef signed char int_fast8_t;
+#endif
+
+#ifndef INT_FAST16_T
+#define INT_FAST16_T
+typedef __EE_INT16 int_fast16_t;
+#endif
+
+#ifndef INT_FAST32_T
+#define INT_FAST32_T
+typedef __EE_INT32 int_fast32_t;
+#endif
+
+#ifndef UINT_FAST8_T
+#define UINT_FAST8_T
+typedef unsigned char uint_fast8_t;
+#endif
+
+#ifndef UINT_FAST16_T
+#define UINT_FAST16_T
+typedef __EE_UINT16 uint_fast16_t;
+#endif
+
+#ifndef UINT_FAST32_T
+#define UINT_FAST32_T
+typedef __EE_UINT32 uint_fast32_t;
+#endif
+
+/* Some real guesswork is needed here, as 64-bit types are not standard */
+#ifndef STDINT_SKIP_64BIT
+
+#ifndef UINT64_T
+#ifdef ULLONG_MAX
+#if ULLONG_MAX != 4294967295UL
+#define UINT64_T
+typedef unsigned long long uint64_t; /**< Unsigned 64 bit integer. */
+#endif
+#endif /* ULLONG_MAX */
+#if !defined(UINT64_T) && defined(__LONG_LONG_MAX__)
+/* Gcc built-in macro __LONG_LONG_MAX__ is only signed */
+#if __LONG_LONG_MAX__ != 2147483647L
+#define UINT64_T
+typedef unsigned long long uint64_t; /**< Unsigned 64 bit integer. */
+#endif
+#endif /* __LONG_LONG_MAX__ */
+#ifndef UINT64_T
+#error "No known way to define an unsigned 64-bit type"
+#endif
+#endif /* ifndef UINT64_T */
+
+#ifndef INT64_T
+#ifdef LLONG_MAX
+#if LLONG_MAX != 4294967295UL
+#define INT64_T
+typedef long long int64_t; /**< Signed 64 bit integer. */
+#endif
+#endif /* ULLONG_MAX */
+#if !defined(INT64_T) && defined(__LONG_LONG_MAX__)
+#if __LONG_LONG_MAX__ != 2147483647L
+#define INT64_T
+typedef long long int64_t; /**< Signed 64 bit integer. */
+#endif
+#endif /* __LONG_LONG_MAX__ */
+#ifndef UINT64_T
+#error "No known way to define a signed 64-bit type"
+#endif
+#endif /* ifndef INT64_T */
+
+#endif /* STDINT_SKIP_64BIT */
+
+#endif /* No <stdint.h> */
+
+/** @} */
+
+#endif /* __INCLUDE_CPU_COMMON_EE_STDINT_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_types.h b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_types.h
new file mode 100644
index 0000000..3592fc3
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/inc/ee_types.h
@@ -0,0 +1,138 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Erika types, based on standard types defined in <limits.h>
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+#ifndef PKG_CPU_COMMON_INC_EE_TYPES_H
+#define PKG_CPU_COMMON_INC_EE_TYPES_H
+
+/* For Gcc we could use __XXX_MAX__ built-in macros, instead */
+#include <limits.h>
+
+/* Primitive data types */
+typedef unsigned char EE_BIT;
+
+#if SCHAR_MAX == 127
+typedef unsigned char EE_UINT8;
+typedef signed char EE_INT8;
+#else
+#error Unable to define a 8-bit types
+#endif
+
+#if INT_MAX == 32767 /* 16-bit architecture */
+typedef int EE_INT16;
+typedef unsigned int EE_UINT16;
+typedef long int EE_INT32;
+typedef unsigned long int EE_UINT32;
+#ifndef __STRICT_ANSI__
+#ifdef ULLONG_MAX
+#if ULLONG_MAX == 0xffffffffffffffffUL
+typedef unsigned long long int EE_UINT64;
+#endif
+#endif
+#endif
+#elif (INT_MAX == 2147483647) && (SHRT_MAX == 32767) /* 32-bit architecture */
+typedef short int EE_INT16;
+typedef unsigned short int EE_UINT16;
+typedef int EE_INT32;
+typedef unsigned int EE_UINT32;
+#if (ULONG_MAX > 0xffffffffUL)
+typedef unsigned long int EE_UINT64;
+#elif !defined(__STRICT_ANSI__)
+#if (defined(ULLONG_MAX)) && (ULLONG_MAX > 0xffffffffUL)
+typedef unsigned long long int EE_UINT64;
+#endif
+#endif
+#else /* Unknown architecture */
+#error Unknow/unsupported architecture
+#endif
+
+/* HAL may need to declare pointers using keywords such as `far'... */
+#ifndef __EE_HAL_CUSTOM_POINTERS__
+
+/* Data addresses (that have the same size of a pointer) */
+typedef void *EE_ADDR;
+
+/*
+ * Introduced to comply with MISRA 16.7.
+ * There may be functions requiring pointer to const)
+ */
+typedef const void *EE_CONST_ADDR;
+
+/* Code addresses (same size of function pointers) */
+typedef void (*EE_FADDR)(void);
+
+/* Callbacks with no parameters nor return value */
+typedef void (*EE_VOID_CALLBACK)(void);
+
+/* Thread body pointer (same size of function pointers) */
+typedef void (*EE_THREAD_PTR)(void);
+
+/* Callback function called by driver handlers */
+typedef EE_VOID_CALLBACK EE_ISR_callback;
+
+#endif /* __EE_HAL_CUSTOM_POINTERS__ */
+
+/** Utility Macro that convert an amount of ms in number of ticks of a given
+ * frequency **/
+#define EE_MILLI_TO_TICKS(X_MS, REF_FREQ_HZ) \
+ ((X_MS)*((REF_FREQ_HZ) / 1000UL))
+
+/** Utility Macro that convert an amount of us in number of ticks of a given
+ * frequency **/
+#define EE_MICRO_TO_TICKS(X_US, REF_FREQ_HZ) \
+ (((X_US) / 1000UL) ? \
+ EE_MILLI_TO_TICKS(((X_US) / 1000UL), (REF_FREQ_HZ)) : \
+ EE_MILLI_TO_TICKS((X_US), (REF_FREQ_HZ)) / 1000UL)
+
+/** Utility Macro that convert an amount of us in number of ticks of a given
+ * frequency **/
+#define MICROSECONDS_TO_TICKS(X_MICROSECS, REF_FREQ_HZ) \
+ EE_MICRO_TO_TICKS((X_MICROSECS), (REF_FREQ_HZ))
+
+/** Utility Macro that convert an amount of ms in number of ticks of a given
+ * frequency **/
+#define MILLISECONDS_TO_TICKS(X_MILLISECS, REF_FREQ_HZ) \
+ EE_MILLI_TO_TICKS((X_MILLISECS), (REF_FREQ_HZ))
+
+#endif /* __INCLUDE_CPU_COMMON_EE_TYPES__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/makefile b/src/bsp/hsm/os/erika2/pkg/cpu/common/makefile
new file mode 100644
index 0000000..3d05484
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/makefile
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call cur-dir)
+
+ifeq ($(OS_ERIKA2), true)
+
+LOCAL_MODULE := os_erika_cpu_common
+
+LOCAL_SRC_FILES := \
+ ./src/ee_common_context.c \
+ ./src/ee_hal_structs.c
+
+LOCAL_C_INCLUDES := ./inc
+
+ALL_SRCS += $(foreach SRC, $(LOCAL_SRC_FILES:./%=%), $(addprefix $(LOCAL_PATH)/, $(SRC)))
+ALL_INCDIRS += $(foreach INC, $(LOCAL_C_INCLUDES), $(addprefix $(LOCAL_PATH)/, $(INC)))
+
+endif
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_common_context.c b/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_common_context.c
new file mode 100644
index 0000000..db3a466
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_common_context.c
@@ -0,0 +1,71 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/*
+ * Context switch functions used in HAL implementations
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+
+#include "ee_internal.h"
+
+/* This version should work for both the monostack and multistack versions of
+ * the kernel, thanks to the macros defined in cpu/common/inc/ee_context.h.
+ * In the mono version, all the stack-related stuff is ignored.
+ */
+EE_TID EE_std_run_task_code(EE_TID tid)
+{
+ EE_hal_enableIRQ();
+ /* Call a the body of a task */
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+ EE_oo_thread_stub();
+ (void)tid;
+#else
+ /* Useless check to make MISRA-C happy. */
+ if (EE_hal_thread_body[tid] != 0) {
+ EE_hal_thread_body[tid]();
+ }
+#endif
+ EE_hal_disableIRQ();
+ EE_thread_end_instance(); /* Call the scheduler */
+ return EE_std_endcycle_next_tid;
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_hal_structs.c b/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_hal_structs.c
new file mode 100644
index 0000000..2d19e9a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/common/src/ee_hal_structs.c
@@ -0,0 +1,57 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Structures commonly used in HAL implementations.
+ * Derived from pkg/cpu/pic30/hal/ee_hal_c.c
+ * Author: 2009 Bernardo Dal Seno
+ */
+
+#include "ee_internal.h"
+
+/*
+ * IRQ nesting level
+ */
+EE_UREG EE_IRQ_nesting_level;
+
+/*
+ * Next thread to run after a thread terminated
+ */
+EE_TID EE_std_endcycle_next_tid;
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/cfg/cfg.mk
new file mode 100644
index 0000000..f27007f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/cfg/cfg.mk
@@ -0,0 +1,143 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-20011 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Files specific to the CORTEX MX
+## Author: 2011 Gianluca Franchino
+## 2011 Giuseppe Serano
+
+ifeq ($(call iseeopt, __CORTEX_MX__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_utils.c
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_context.c
+
+ifeq ($(call iseeopt, __IAR__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_iar_change_context_isr.s
+else # __IAR__
+ifeq ($(call iseeopt, __CCS__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_ccs_change_context_isr.s
+else # __CCS__
+ifeq ($(call iseeopt, __KEIL__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_keil_change_context_isr.s
+else # __KEIL__
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_gnu_change_context_isr.S
+endif # __GNU__
+endif # !__KEIL__
+endif # !__CCS__
+endif # !__IAR__
+
+ifeq ($(call iseeopt, __OO_BCC1__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_BCC2__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_ECC1__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(call iseeopt, __OO_ECC2__), yes)
+CPU_OO=YES
+endif
+
+ifeq ($(CPU_OO), YES)
+ifeq ($(call iseeopt, __IAR__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_iar_oo.s
+else
+ifeq ($(call iseeopt, __CCS__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_ccs_oo.s
+else
+ifeq ($(call iseeopt, __KEIL__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_keil_oo.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_gnu_oo.S
+endif
+endif
+endif
+endif
+endif
+
+ifeq ($(call iseeopt, ENABLE_SYSTEM_TIMER), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_system_timer.c
+endif
+
+ifeq ($(call iseeopt, __MULTI__), yes)
+
+ifeq ($(call iseeopt, __IAR__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_iar_multi_context.s
+else
+ifeq ($(call iseeopt, __CCS__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_ccs_multi_context.s
+else
+ifeq ($(call iseeopt, __KEIL__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_keil_multi_context.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_gnu_multi_context.S
+endif
+endif
+endif
+endif
+
+endif # __MULTI__
+
+ifeq ($(call iseeopt, __IRQ_STACK_NEEDED__), yes)
+
+ifeq ($(call iseeopt, __IAR__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_iar_irq_stack.s
+else
+ifeq ($(call iseeopt, __CCS__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_ccs_irq_stack.s
+else
+ifeq ($(call iseeopt, __KEIL__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_keil_irq_stack.s
+else
+ifeq ($(call iseeopt, __GNU__), yes)
+EE_SRCS += pkg/cpu/cortex_mx/src/ee_gnu_irq_stack.S
+endif
+endif
+endif
+endif
+
+endif # __IRQ_STACK_NEEDED__
+
+endif # __CORTEX_MX__
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_context.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_context.h
new file mode 100644
index 0000000..6b267bd
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_context.h
@@ -0,0 +1,175 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_internal.h
+ * @brief Derived from cpu/common/inc/ee_internal.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_CPU_CORTEX_MX_EE_CONTEXT__
+#define __INCLUDE_CPU_CORTEX_MX_EE_CONTEXT__
+
+/*
+ * Instructions
+ *
+ * The monostack part is complete (obviously, the functions to disable/enable
+ * interrupts are not included here). For the multistack part you have to
+ * provide two additional things:
+ * 1. An assembly implementation of EE_std_change_context_multi(); see below.
+ * 2. A #define directive for EE_hal_active_tos, which is just an alias for the
+ * actual architecture-dependent variable. This variable contains the index of
+ * the current stack.
+ */
+
+/* After a task terminates, the scheduler puts the id of the new task to launch
+ * or switch to in this variable. If the is stacked, its id is marked so. */
+extern EE_TID EE_std_endcycle_next_tid;
+
+/* The multistack version must be implemented in ASM; no standard
+ * implementation, sorry. This is the only function that performs context
+ * switching. The multistack version doesn't jump to the task body if its TID
+ * has been maked as stacked. This is used to switch to a task that has been
+ * suspend by a previous call to EE_std_change_contex(). */
+void EE_cortex_mx_change_context(EE_TID tid);
+/* Pseudo code for EE_std_change_context_multi():
+ * begin:
+ * tos_index = EE_std_thread_tos[tid+1];
+ * if is_not_the_current_stack(tos_index) {
+ * save_caller_saved_registers();
+ * switch_stacks(tos_index);
+ * restore_caller_saved_registers();
+ * }
+ * if (is_not_marked_stacked(tid)) {
+ * tid = EE_std_run_task_code(tid);
+ * goto begin;
+ * }
+ *
+ * Please notice that the "goto begin" is actually a recursive call to
+ * EE_std_change_context_multi(), but in this way there is no stack growing.
+ *
+ * Please notice also that 'tid' must NOT be saved onto the stack before
+ * switching stacks, otherwise when switching from another stack back to the
+ * current one, you would overwrite its value.
+ *
+ * For processors where the return address is saved in a register, that
+ * register must be saved in the stack too.
+ *
+ * switch_stacks() should also update EE_hal_active_tos.
+ */
+
+/* Call a the body of a task */
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || \
+ defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#define EE_call_task_body(tid) EE_oo_thread_stub()
+#else
+#define EE_call_task_body(tid) (((void (*)(void))EE_hal_thread_body[tid])())
+#endif
+
+
+/* Launch a new task, possibly switching to a different stack, clean up the task
+ * after it ends, and call the scheduler (and switch to other tasks/stacks)
+ * until there are no more tasks to switch to. In the multistack version, also
+ * change the current stack before returning if the scheduler asks for it. */
+__DECLARE_INLINE__ void EE_hal_ready2stacked(EE_TID tid);
+
+
+/* Launch a new task on the current stack, clean up the task after it ends, and
+ * call the scheduler. Return the next task to launch, which is "marked as
+ * stacked" if there is no new task to launch. */
+EE_TID EE_std_run_task_code(EE_TID tid);
+
+
+/*
+ * Inline implementations
+ */
+
+
+#ifdef __MONO__
+
+/* With monostack, we need only the information that the task is stacked. We
+ * don't need to know which task it is, as there is no new stack to switch
+ * to. */
+#define EE_std_mark_tid_stacked(tid) ((EE_TID)-1)
+
+#define EE_std_need_context_change(tid) ((tid) >= 0)
+
+#endif /* __MONO__ */
+
+
+#ifdef __MULTI__
+
+/* TID_IS_STACKED_MARK must set the most significative bit */
+#define EE_std_mark_tid_stacked(tid) ((tid) | (EE_TID)TID_IS_STACKED_MARK)
+
+extern int EE_std_need_context_change(EE_TID tid);
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_stkchange(EE_TID tid)
+{
+ EE_cortex_mx_change_context(EE_std_mark_tid_stacked(tid));
+}
+
+#endif /* __MULTI__ */
+
+void EE_init_task_private_stack(void);
+
+/* The functions below should work for both the monostack and multistack
+ * versions of the kernel, thanks to the macros defined above. In the mono
+ * version, all the stack-related stuff is ignored. */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_ready2stacked(EE_TID tid)
+{
+ EE_cortex_mx_change_context(tid);
+}
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_ready(EE_TID tid)
+{
+ EE_std_endcycle_next_tid = tid;
+}
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_endcycle_stacked(EE_TID tid)
+{
+ EE_std_endcycle_next_tid = EE_std_mark_tid_stacked(tid);
+}
+
+#endif /* __INCLUDE_CPU_CORTEX_MX_EE_CONTEXT__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_cpu.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_cpu.h
new file mode 100644
index 0000000..8063978
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_cpu.h
@@ -0,0 +1,489 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_cpu.h
+ * @brief CPU-dependent part of HAL. Derived from pkg/cpu/pic30/inc/ee_cpu.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_CORTEX_MX_EE_CPU_H__
+#define __INCLUDE_CORTEX_MX_EE_CPU_H__
+
+#include "eecfg.h"
+
+#ifdef __IAR__
+#include "cpu/common/inc/ee_compiler_iar.h"
+#else /* __IAR__ */
+#ifdef __CCS__
+#include "cpu/common/inc/ee_compiler_ccs.h"
+#else /* __CCS__ */
+#ifdef __KEIL__
+#include "cpu/common/inc/ee_compiler_keil.h"
+#else /* __KEIL__ */
+#ifdef __GNU__
+#include "cpu/common/inc/ee_compiler_gcc.h"
+#else /* __GNU__ */
+#error Unsupported compiler
+#endif /* !__GNU__ */
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+
+/* Initial stack offset (in words): Used in multistack. */
+#ifndef CORTEX_MX_INIT_TOS_OFFSET
+#define CORTEX_MX_INIT_TOS_OFFSET 10
+#endif
+
+/*************************************************************************
+* HAL Types and structures
+*************************************************************************/
+
+/* Primitive data types */
+#include "cpu/common/inc/ee_types.h"
+
+typedef EE_UINT32 EE_UREG;
+typedef EE_INT32 EE_SREG;
+typedef EE_UINT32 EE_FREG;
+#define EE_UREG_SIZE 4
+
+/* boolean type */
+#ifndef EE_TYPEBOOL
+typedef EE_UREG EE_TYPEBOOL;
+#endif
+
+/* boolean true define */
+#ifndef EE_TRUE
+#define EE_TRUE ((EE_TYPEBOOL)1U)
+#endif
+
+/* boolean false define */
+#ifndef EE_FALSE
+#define EE_FALSE ((EE_TYPEBOOL)0U)
+#endif
+
+#define EE_HWREG_PTR volatile EE_UREG *
+#define EE_HWREG_ADDR(x) ((EE_HWREG_PTR)(x))
+#define EE_HWREG(x) (*EE_HWREG_ADDR(x))
+
+#ifdef __GNU__
+
+/* Get current SP */
+__INLINE__ EE_UINT32 __ALWAYS_INLINE__ __current_sp(void)
+{
+ EE_UINT32 temp;
+
+ __ASM("mov %0, sp" : "=r" (temp) :);
+ return temp;
+}
+
+/* Set a breakpoint */
+#define __breakpoint(value) __ASM("bkpt " #value)
+
+#endif
+
+/* ISR Priority representation type */
+typedef EE_UREG EE_TYPEISR2PRIO;
+
+/* Thread IDs */
+typedef EE_INT32 EE_TID;
+
+/* Thread IDs - unsigned version*/
+typedef EE_UINT32 EE_UTID;
+
+/* Used by the common layer to decide whether to start a new thread */
+#define TID_IS_STACKED_MARK 0x80000000
+
+/* EE_TYPEIRQ is currently unused */
+
+/* XXX: define EE_TIME? */
+
+/* Use the "standard" implementation */
+#include "cpu/common/inc/ee_hal_structs.h"
+
+/******************************************************************************
+* Application dependent data types
+******************************************************************************/
+
+#ifdef __HAS_TYPES_H__
+#include "types.h"
+#endif
+
+/******************************************************************************
+* CPU Peripherals
+******************************************************************************/
+
+#ifdef __CORTEX_MX__
+#include "cpu/cortex_mx/inc/ee_nvic.h"
+#include "cpu/cortex_mx/inc/ee_systick.h"
+#endif
+
+/******************************************************************************
+* HAL Variables
+******************************************************************************/
+
+#ifdef __MULTI__
+
+/* Top-of-stack of each private stack */
+extern struct EE_TOS EE_cortex_mx_system_tos[];
+/* #define EE_std_system_tos EE_cortex_mx_system_tos */
+
+/* Index of the current stack */
+extern EE_UREG EE_cortex_mx_active_tos;
+#define EE_hal_active_tos EE_cortex_mx_active_tos
+
+/*extern EE_UREG EE_pic30_thread_tos[];
+ #define EE_std_thread_tos EE_pic30_thread_tos */
+#endif /* __MULTI__ */
+
+/*********************************************************************
+* Cortex M0 interrupt disabling/enabling
+*********************************************************************/
+
+/* Used to check the value returned by EE_cortex_mx_disableIRQ */
+#define EE_cortex_mx_are_IRQs_enabled(ie) ((ie) ^ 1)
+
+/**
+ * Enable interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_cortex_mx_enableIRQ(void)
+{
+#ifdef __IAR__
+ __ASM("cpsie i");
+#else /* __IAR__ */
+#ifdef __CCS__
+ __ASM(" cpsie i\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ __enable_irq();
+#else /* __KEIL__ */
+ __ASM volatile ("cpsie i");
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+}
+
+/**
+ * Disable interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_cortex_mx_disableIRQ(void)
+{
+#ifdef __IAR__
+ __ASM("cpsid i");
+#else /* __IAR__ */
+#ifdef __CCS__
+ __ASM(" cpsid i\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ __disable_irq();
+#else /* __KEIL__ */
+ __ASM volatile ("cpsid i");
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+}
+
+/**
+ * Resume interrupts
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_cortex_mx_resumeIRQ(EE_FREG f)
+{
+#ifdef __IAR__
+ __set_PRIMASK(f);
+#else /* __IAR__ */
+#ifdef __CCS__
+ __ASM(" msr primask, r0\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ register EE_FREG PRIMASK __ASM("primask");
+ PRIMASK = f;
+#else /* __KEIL__ */
+ __ASM volatile ("msr primask, %0" :: "r" (f));
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+}
+
+/**
+ * Suspend interrupts
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_cortex_mx_suspendIRQ(void)
+{
+#ifndef __CCS__
+ EE_FREG istat;
+#endif
+#ifdef __IAR__
+ istat = __get_PRIMASK();
+ __ASM("cpsid i");
+#else /* __IAR__ */
+#ifdef __CCS__
+ __ASM(" mrs r0, primask\n"
+ " cpsid i\n"
+ " bx lr\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ register EE_FREG PRIMASK __ASM("primask");
+ istat = PRIMASK;
+ __disable_irq();
+#else /* __KEIL__ */
+ __ASM volatile ("mrs %0, primask" : "=r" (istat));
+ __ASM volatile ("cpsid i");
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+#ifdef __CCS__
+ return 0;
+#else
+ return istat;
+#endif
+}
+
+/**
+ * Return true (not 0) if IRQs are enabled, 0 (false) if IRQ are disabled.
+ */
+__INLINE__ EE_UINT32 __ALWAYS_INLINE__ EE_cortex_mx_get_IRQ_enabled(void)
+{
+#ifndef __CCS__
+ EE_UREG ie;
+#endif
+#ifdef __IAR__
+ ie = __get_PRIMASK();
+#else /* __IAR__ */
+#ifdef __CCS__
+ __ASM(" MRS r0, PRIMASK\n"
+ " EOR r0, #1\n"
+ " bx lr\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ register EE_FREG PRIMASK __ASM("primask");
+ ie = PRIMASK;
+#else /* __KEIL__ */
+ __ASM volatile ("MRS %0, primask" : "=r" (ie));
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+#ifdef __CCS__
+ return 0;
+#else
+ return EE_cortex_mx_are_IRQs_enabled(ie);
+#endif
+}
+
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_cortex_mx_get_int_prio(void)
+{
+#ifdef __CORTEX_M4__
+
+#ifndef __CCS__
+ register EE_UREG prio;
+#ifdef __KEIL__
+ register EE_FREG BASEPRI __ASM("basepri");
+#endif
+
+#endif
+
+#ifdef __CCS__
+ /* NVIC_INT_PRI_S = 5 */
+ __ASM(" MRS R0, BASEPRI\n"
+ " ASR R0, #5\n"
+ " BLX LR\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ prio = BASEPRI;
+#else /* __KEIL__ */
+#ifdef __GNU__
+ __ASM volatile ("MRS %0, BASEPRI" : "=r" (prio) :: );
+#else
+ __ASM volatile ("MRS %0, BASEPRI" :: "=r" (prio));
+#endif /* !__GNU__ */
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+
+#ifdef __CCS__
+ return 0;
+#else
+ return prio >> NVIC_INT_PRI_S;
+#endif
+
+#else /* __CORTEX_M4__ */
+ return 0;
+#endif /* !__CORTEX_M4__ */
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_cortex_mx_set_int_prio(
+ EE_TYPEISR2PRIO prio
+ )
+{
+#ifdef __CORTEX_M4__
+#ifdef __CCS__
+ /* NVIC_INT_PRI_S = 5 */
+ __ASM(" LSL R0, #5\n"
+ " MSR BASEPRI, R0\n");
+#else /* __CCS__ */
+#ifdef __KEIL__
+ register EE_FREG BASEPRI __ASM("basepri");
+ BASEPRI = (prio << NVIC_INT_PRI_S);
+#else /* __KEIL__ */
+#ifdef __GNU__
+ __ASM volatile ("MSR BASEPRI, %0" :: "r" (prio << NVIC_INT_PRI_S) :);
+#else
+ __ASM volatile ("MSR BASEPRI, %0" :: "r" (prio << NVIC_INT_PRI_S));
+#endif /* !__GNU__ */
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* __CORTEX_M4__ */
+}
+
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_cortex_mx_get_isr_prio(
+ void
+ )
+{
+#ifdef __CORTEX_M4__
+ register EE_UREG vectact = NVIC_INT_CTRL_R & NVIC_INT_CTRL_VEC_ACT_M;
+ register EE_TYPEISR2PRIO prio = 0;
+
+ if (vectact > EE_CORTEX_MX_SYSTICK_EXC_NUM) {
+ vectact -= EE_CORTEX_MX_SYSTICK_EXC_NUM + 1;
+ prio = NVIC_GET_PRI(vectact);
+ }
+#ifdef __USE_SYSTICK__
+ else if (vectact == EE_CORTEX_MX_SYSTICK_EXC_NUM) {
+ prio = NVIC_SYS_PRI3_R >> NVIC_SYS_PRI3_TICK_S;
+ }
+#endif
+#ifdef __USE_SVC__
+ else if (vectact == EE_CORTEX_MX_SVCALL_EXC_NUM) {
+ prio = NVIC_SYS_PRI2_R >> NVIC_SYS_PRI2_SVC_S;
+ }
+#endif
+
+ return prio;
+
+#else /* __CORTEX_M4__ */
+ return 0;
+#endif /* !__CORTEX_M4__ */
+}
+
+/*************************************************************************
+* Functions exported by the HAL to the kernel
+*************************************************************************/
+
+/*
+ * Interrupt Handling
+ */
+
+/** Hal Enable Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_enableIRQ(void)
+{
+ EE_cortex_mx_enableIRQ();
+}
+
+/** Hal Disable Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_disableIRQ(void)
+{
+ EE_cortex_mx_disableIRQ();
+}
+
+/** Hal Resume Interrupts */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_resumeIRQ(EE_FREG f)
+{
+ EE_cortex_mx_resumeIRQ(f);
+}
+
+/** Hal Suspend Interrupts */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_suspendIRQ(void)
+{
+ return EE_cortex_mx_suspendIRQ();
+}
+
+/**************************************************************************
+ * System Initialization
+ ***************************************************************************/
+
+void EE_system_init(void);
+
+/*************************************************************************
+* CPU-dependent ORT support (mainly OTM)
+*************************************************************************/
+
+/* Probably, some parts of the OTM code below does not depend on the
+ * architecture. They should be moved somewhere into pkg/cpu/common if this
+ * turns out to be the case. */
+
+#define EE_ORTI_OTM_ID_RUNNINGISR2 1
+#define EE_ORTI_OTM_ID_SERVICETRACE 2
+
+#ifdef __OO_ORTI_USE_OTM__
+void EE_cortex_mx_send_otm8(EE_UINT8 id,
+ EE_UINT8 data);
+void EE_cortex_mx_send_otm32(EE_UINT8 id,
+ EE_UINT32 data);
+
+#else /* if __OO_ORTI_USE_OTM__ */
+__INLINE__ void EE_cortex_mx_send_otm8(EE_UINT8 id,
+ EE_UINT8 data)
+{
+ /* OTM disabled */
+}
+
+__INLINE__ void EE_cortex_mx_send_otm32(EE_UINT8 id,
+ EE_UINT32 data)
+{
+ /* OTM disabled */
+}
+#endif /* else __OO_ORTI_USE_OTM__ */
+
+#ifdef __OO_ORTI_RUNNINGISR2__
+__INLINE__ void EE_ORTI_send_otm_runningisr2(EE_ORTI_runningisr2_type isr2)
+{
+ EE_cortex_mx_send_otm32(EE_ORTI_OTM_ID_RUNNINGISR2, (EE_UINT32)isr2);
+}
+#endif /* __OO_ORTI_RUNNINGISR2__ */
+
+#ifdef __OO_ORTI_SERVICETRACE__
+__INLINE__ void EE_ORTI_send_otm_servicetrace(EE_UINT8 srv)
+{
+ EE_cortex_mx_send_otm8(EE_ORTI_OTM_ID_SERVICETRACE, srv);
+}
+
+#endif /* __OO_ORTI_SERVICETRACE__ */
+
+#endif /* __INCLUDE_CORTEX_MX_EE_CPU_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_internal.h
new file mode 100644
index 0000000..c33539a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_internal.h
@@ -0,0 +1,195 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_internal.h
+ * @brief Derived from cpu/pic30/inc/ee_internal.h
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2012
+ */
+
+#ifndef __INCLUDE_CORTEX_MX_INTERNAL_H__
+#define __INCLUDE_CORTEX_MX_INTERNAL_H__
+
+
+#include "cpu/cortex_mx/inc/ee_cpu.h"
+
+
+/*************************************************************************
+* Functions
+*************************************************************************/
+
+/*
+ * Generic Primitives
+ */
+
+#include "cpu/common/inc/ee_primitives.h"
+
+/*************************************************************************
+* System startup
+*************************************************************************/
+
+#define OO_CPU_HAS_STARTOS_ROUTINE
+
+/* If system is defined I have to initialize it*/
+#if (defined(ENABLE_SYSTEM_TIMER) && defined(EE_SYSTEM_TIMER_DEVICE))
+void EE_cortex_mx_initialize_system_timer(void);
+#else /* ENABLE_SYSTEM_TIMER */
+#define EE_cortex_mx_initialize_system_timer() ((void)0)
+#endif /* ENABLE_SYSTEM_TIMER */
+
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_cpu_startos(void);
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_cpu_startos(void)
+{
+ EE_system_init();
+ EE_cortex_mx_initialize_system_timer();
+ return 0;
+}
+
+
+/** Called as _first_ function of a primitive that can be called in
+ * an IRQ and in a task */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_begin_nested_primitive(void)
+{
+ return EE_cortex_mx_suspendIRQ();
+}
+
+
+/** Called as _last_ function of a primitive that can be called in
+ * an IRQ and in a task. Enable IRQs if they were enabled before entering. */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_end_nested_primitive(EE_FREG f)
+{
+ EE_cortex_mx_resumeIRQ(f);
+}
+
+/* Used to get internal CPU priority. */
+__INLINE__ EE_TYPEISR2PRIO __ALWAYS_INLINE__ EE_hal_get_int_prio(void)
+{
+ return EE_cortex_mx_get_int_prio();
+}
+
+/* Used to set internal CPU priority. */
+__INLINE__ void __ALWAYS_INLINE__ EE_hal_set_int_prio(EE_TYPEISR2PRIO prio)
+{
+ EE_cortex_mx_set_int_prio(prio);
+}
+
+/*
+ * Used to change internal CPU priority and return a status flag mask.
+ *
+ * Note: EE_FREG param flag and return value needed only for according to
+ * HAL interface.
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_change_int_prio(
+ EE_TYPEISR2PRIO prio,
+ EE_FREG flag
+ )
+{
+ EE_hal_set_int_prio(prio);
+ return flag;
+}
+
+/*
+ * Used to raise internal CPU interrupt priority if param new_prio is greater
+ * than actual priority.
+ *
+ * Note: EE_FREG param flag and return value needed only for according to
+ * HAL interface.
+ */
+__INLINE__ EE_FREG __ALWAYS_INLINE__ EE_hal_raise_int_prio_if_less(
+ EE_TYPEISR2PRIO new_prio,
+ EE_FREG flag
+ )
+{
+ register EE_TYPEISR2PRIO prev_prio = EE_cortex_mx_get_int_prio();
+
+ if (((new_prio != 0U) && (prev_prio > new_prio)) || (prev_prio == 0)) {
+ EE_cortex_mx_set_int_prio(new_prio);
+ }
+ return flag;
+}
+
+/*
+ * Used to check internal CPU interrupt priority if param new_prio is greater
+ * than actual priority.
+ */
+__INLINE__ EE_BIT __ALWAYS_INLINE__ EE_hal_check_int_prio_if_higher(
+ EE_TYPEISR2PRIO new_prio
+ )
+{
+ register EE_TYPEISR2PRIO prev_prio = EE_cortex_mx_get_int_prio();
+
+ return (prev_prio != 0U) && ((prev_prio < new_prio) || (new_prio == 0U));
+}
+
+/*
+ * Context Handling
+ */
+
+#include "cpu/cortex_mx/inc/ee_context.h"
+
+/* Launch a new task on the current stack, clean up the task after it ends, and
+ * call the scheduler. Return the next task to launch, which is "marked as
+ * stacked" if there is no new task to launch. */
+EE_TID EE_std_run_task_code(EE_TID tid);
+
+/* typically called at the end of an interrupt */
+#define EE_hal_IRQ_stacked EE_hal_endcycle_stacked
+#define EE_hal_IRQ_ready EE_hal_endcycle_ready
+
+/*
+ * OO TerminateTask related stuffs
+ */
+
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || defined(__OO_ECC2__)
+
+/** Save the context and call the body of the task `tid'. Implemented in
+ * assembly */
+void EE_hal_terminate_savestk(EE_TID tid);
+
+/** Restore the context saved by EE_hal_terminate_savestk() for the task `tid' and
+ * return from EE_hal_terminate_savestk(). Implemented in assembly */
+NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+#endif /* __OO_BCCx */
+
+
+#endif /* __INCLUDE_CORTEX_MX_INTERNAL_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq.h
new file mode 100644
index 0000000..796b6cf
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq.h
@@ -0,0 +1,171 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ *
+ * @file ee_irq.h
+ * @brief Prestub and postub macros and related stuffs
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_CORTEX_MX_IRQ_H__
+#define __INCLUDE_CORTEX_MX_IRQ_H__
+
+
+#ifdef __CORTEX_MX__
+#define EE_ISR_UNMASKED 0x00000000
+#define EE_ISR_PRI_1 0x00000006U
+#define EE_ISR_PRI_2 0x00000005U
+#define EE_ISR_PRI_3 0x00000004U
+#define EE_ISR_PRI_4 0x00000003U
+#define EE_ISR_PRI_5 0x00000002U
+#define EE_ISR_PRI_6 0x00000001U
+#endif /* __CORTEX_M4__ */
+
+#define EE_std_change_context(x) ((void)0)
+
+/* Use angled parenthesis to include the main "ee_internal.h" */
+#include "cpu/cortex_mx/inc/ee_cpu.h"
+#include "cpu/cortex_mx/inc/ee_irq_cng_cont.h"
+#include "cpu/cortex_mx/inc/ee_context.h"
+#include "cpu/common/inc/ee_irqstub.h"
+
+#ifdef __ALLOW_NESTED_IRQ__
+
+extern struct EE_TOS EE_cortex_mx_IRQ_tos;
+
+#define EE_std_enableIRQ_nested() EE_cortex_mx_enableIRQ()
+#define EE_std_disableIRQ_nested() EE_cortex_mx_disableIRQ()
+
+#else /* else __ALLOW_NESTED_IRQ__*/
+
+#define EE_std_enableIRQ_nested() ((void)0)
+#define EE_std_disableIRQ_nested() ((void)0)
+
+#endif /* end __ALLOW_NESTED_IRQ__*/
+
+#if defined(__MULTI__) && defined(__IRQ_STACK_NEEDED__)
+
+extern void EE_cortex_mx_change_IRQ_stack(void);
+extern void EE_cortex_mx_change_IRQ_stack_back(void);
+
+/*save the stack pointer*/ /*Load new stack pointer*/
+#define EE_cortex_mx_change_stack() \
+ do { \
+ if (EE_IRQ_nesting_level == 1) { \
+ EE_cortex_mx_change_IRQ_stack(); \
+ } \
+ } while (0)
+
+#define EE_cortex_mx_stack_back() \
+ EE_cortex_mx_change_IRQ_stack_back()
+
+#else /* else __MULTI__ && __IRQ_STACK_NEEDED__*/
+
+#define EE_cortex_mx_change_stack() ((void)0)
+#define EE_cortex_mx_stack_back() ((void)0)
+
+#endif /* end __MULTI__ && __IRQ_STACK_NEEDED__*/
+
+#define EE_ISR2_prestub(void) \
+ /* Defined as Macro */ \
+ do { \
+ EE_cortex_mx_disableIRQ(); \
+ ipl = EE_cortex_mx_get_int_prio(); \
+ EE_cortex_mx_set_int_prio(EE_cortex_mx_get_isr_prio()); \
+ EE_increment_IRQ_nesting_level(); \
+ EE_cortex_mx_change_stack(); \
+ /* Enable IRQ if nesting is allowed */ \
+ EE_std_enableIRQ_nested(); \
+ } \
+ while (0)
+
+extern EE_UREG EE_cortex_mx_change_context_active;
+
+#define EE_ISR2_poststub(void) \
+ /* Defined as Macro */ \
+ do { \
+ /* Disabled IRQ if nesting is allowed.\
+ * Note: if nesting is not allowed, the IRQs are already disabled\
+ */ \
+ EE_std_disableIRQ_nested(); \
+ EE_cortex_mx_set_int_prio(ipl); \
+ EE_std_end_IRQ_post_stub(); \
+ EE_decrement_IRQ_nesting_level(); \
+ /*\
+ * If the ISR at the lowest level is ended, restore the stack pointer\
+ * and active the change context procedure if needed ( call the scheduler).\
+ */ \
+ if (!EE_is_inside_ISR_call()) { \
+ EE_cortex_mx_stack_back(); \
+ EE_cortex_mx_IRQ_active_change_context(); \
+ } \
+ EE_cortex_mx_enableIRQ(); \
+ } \
+ while (0)
+
+
+
+#define ISR1(f) \
+ void ISR1_ ## f(void); \
+ __IRQ void f(void) \
+ { \
+ ISR1_ ## f(); \
+ } \
+ void ISR1_ ## f(void)
+
+
+#define ISR2(f) \
+ void ISR2_ ## f(void); \
+ __IRQ void f(void) \
+ { \
+ EE_UREG ipl = 0; \
+ EE_ISR2_prestub(); \
+ ISR2_ ## f(); \
+ EE_ISR2_poststub(); \
+ } \
+ void ISR2_ ## f(void)
+
+/* Standard Macro to declare an ISR (2) */
+#define ISR(f) ISR2(f)
+
+#endif /* __INCLUDE_CORTEX_MX_IRQ_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq_cng_cont.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq_cng_cont.h
new file mode 100644
index 0000000..0013e5e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_irq_cng_cont.h
@@ -0,0 +1,79 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ *
+ * @file ee_irq_cng_cont.h
+ * @brief Function active the context change interrupt
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2012
+ */
+
+#ifndef __INCLUDE_CORTEX_MX_IRQ_CNG_CONTEXT_H__
+#define __INCLUDE_CORTEX_MX_IRQ_CNG_CONTEXT_H__
+
+#ifdef __IAR__
+#include "cpu/common/inc/ee_compiler_iar.h"
+#else /* __IAR__ */
+#ifdef __CCS__
+#include "cpu/common/inc/ee_compiler_ccs.h"
+#else /* __CCS__ */
+#ifdef __KEIL__
+#include "cpu/common/inc/ee_compiler_keil.h"
+#else /* __KEIL__ */
+#ifdef __GNU__
+#include "cpu/common/inc/ee_compiler_gcc.h"
+#else /* __GNU__ */
+#error Unsupported compiler
+#endif /* !__GNU__ */
+#endif /* !__KEIL__ */
+#endif /* !__CCS__ */
+#endif /* !__IAR__ */
+
+/* Implemented in ee_<compiler>_change_context_isr.s */
+extern void EE_switch_context(void);
+
+__INLINE__ void __ALWAYS_INLINE__ EE_cortex_mx_IRQ_active_change_context(void)
+{
+ EE_switch_context();
+}
+
+#endif /* __INCLUDE_CORTEX_MX_IRQ_CNG_CONTEXT_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_nvic.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_nvic.h
new file mode 100644
index 0000000..2865791
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_nvic.h
@@ -0,0 +1,1415 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_nvic.h
+ * @brief ARM Cortex-MX Nested Vector Interrupt Controller (NVIC) Macros
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#ifndef __INCLUDE_CORTEX_MX_NVIC_H__
+#define __INCLUDE_CORTEX_MX_NVIC_H__
+
+/* NVIC registers (NVIC) */
+#define NVIC_INT_TYPE_R EE_HWREG(0xE000E004)
+#define NVIC_ACTLR_R EE_HWREG(0xE000E008)
+#define NVIC_ST_CTRL_R EE_HWREG(0xE000E010)
+#define NVIC_ST_RELOAD_R EE_HWREG(0xE000E014)
+#define NVIC_ST_CURRENT_R EE_HWREG(0xE000E018)
+#define NVIC_ST_CAL_R EE_HWREG(0xE000E01C)
+#define NVIC_EN0_R EE_HWREG(0xE000E100)
+#define NVIC_EN1_R EE_HWREG(0xE000E104)
+#define NVIC_EN2_R EE_HWREG(0xE000E108)
+#define NVIC_EN3_R EE_HWREG(0xE000E10C)
+#define NVIC_EN4_R EE_HWREG(0xE000E110)
+#define NVIC_DIS0_R EE_HWREG(0xE000E180)
+#define NVIC_DIS1_R EE_HWREG(0xE000E184)
+#define NVIC_DIS2_R EE_HWREG(0xE000E188)
+#define NVIC_DIS3_R EE_HWREG(0xE000E18C)
+#define NVIC_DIS4_R EE_HWREG(0xE000E190)
+#define NVIC_PEND0_R EE_HWREG(0xE000E200)
+#define NVIC_PEND1_R EE_HWREG(0xE000E204)
+#define NVIC_PEND2_R EE_HWREG(0xE000E208)
+#define NVIC_PEND3_R EE_HWREG(0xE000E20C)
+#define NVIC_PEND4_R EE_HWREG(0xE000E210)
+#define NVIC_UNPEND0_R EE_HWREG(0xE000E280)
+#define NVIC_UNPEND1_R EE_HWREG(0xE000E284)
+#define NVIC_UNPEND2_R EE_HWREG(0xE000E288)
+#define NVIC_UNPEND3_R EE_HWREG(0xE000E28C)
+#define NVIC_UNPEND4_R EE_HWREG(0xE000E290)
+#define NVIC_ACTIVE0_R EE_HWREG(0xE000E300)
+#define NVIC_ACTIVE1_R EE_HWREG(0xE000E304)
+#define NVIC_ACTIVE2_R EE_HWREG(0xE000E308)
+#define NVIC_ACTIVE3_R EE_HWREG(0xE000E30C)
+#define NVIC_ACTIVE4_R EE_HWREG(0xE000E310)
+#define NVIC_PRI0_R EE_HWREG(0xE000E400)
+#define NVIC_PRI1_R EE_HWREG(0xE000E404)
+#define NVIC_PRI2_R EE_HWREG(0xE000E408)
+#define NVIC_PRI3_R EE_HWREG(0xE000E40C)
+#define NVIC_PRI4_R EE_HWREG(0xE000E410)
+#define NVIC_PRI5_R EE_HWREG(0xE000E414)
+#define NVIC_PRI6_R EE_HWREG(0xE000E418)
+#define NVIC_PRI7_R EE_HWREG(0xE000E41C)
+#define NVIC_PRI8_R EE_HWREG(0xE000E420)
+#define NVIC_PRI9_R EE_HWREG(0xE000E424)
+#define NVIC_PRI10_R EE_HWREG(0xE000E428)
+#define NVIC_PRI11_R EE_HWREG(0xE000E42C)
+#define NVIC_PRI12_R EE_HWREG(0xE000E430)
+#define NVIC_PRI13_R EE_HWREG(0xE000E434)
+#define NVIC_PRI14_R EE_HWREG(0xE000E438)
+#define NVIC_PRI15_R EE_HWREG(0xE000E43C)
+#define NVIC_PRI16_R EE_HWREG(0xE000E440)
+#define NVIC_PRI17_R EE_HWREG(0xE000E444)
+#define NVIC_PRI18_R EE_HWREG(0xE000E448)
+#define NVIC_PRI19_R EE_HWREG(0xE000E44C)
+#define NVIC_PRI20_R EE_HWREG(0xE000E450)
+#define NVIC_PRI21_R EE_HWREG(0xE000E454)
+#define NVIC_PRI22_R EE_HWREG(0xE000E458)
+#define NVIC_PRI23_R EE_HWREG(0xE000E45C)
+#define NVIC_PRI24_R EE_HWREG(0xE000E460)
+#define NVIC_PRI25_R EE_HWREG(0xE000E464)
+#define NVIC_PRI26_R EE_HWREG(0xE000E468)
+#define NVIC_PRI27_R EE_HWREG(0xE000E46C)
+#define NVIC_PRI28_R EE_HWREG(0xE000E470)
+#define NVIC_PRI29_R EE_HWREG(0xE000E474)
+#define NVIC_PRI30_R EE_HWREG(0xE000E478)
+#define NVIC_PRI31_R EE_HWREG(0xE000E47C)
+#define NVIC_PRI32_R EE_HWREG(0xE000E480)
+#define NVIC_CPUID_R EE_HWREG(0xE000ED00)
+#define NVIC_INT_CTRL_R EE_HWREG(0xE000ED04)
+#define NVIC_VTABLE_R EE_HWREG(0xE000ED08)
+#define NVIC_APINT_R EE_HWREG(0xE000ED0C)
+#define NVIC_SYS_CTRL_R EE_HWREG(0xE000ED10)
+#define NVIC_CFG_CTRL_R EE_HWREG(0xE000ED14)
+#define NVIC_SYS_PRI1_R EE_HWREG(0xE000ED18)
+#define NVIC_SYS_PRI2_R EE_HWREG(0xE000ED1C)
+#define NVIC_SYS_PRI3_R EE_HWREG(0xE000ED20)
+#define NVIC_SYS_HND_CTRL_R EE_HWREG(0xE000ED24)
+#define NVIC_FAULT_STAT_R EE_HWREG(0xE000ED28)
+#define NVIC_HFAULT_STAT_R EE_HWREG(0xE000ED2C)
+#define NVIC_DEBUG_STAT_R EE_HWREG(0xE000ED30)
+#define NVIC_MM_ADDR_R EE_HWREG(0xE000ED34)
+#define NVIC_FAULT_ADDR_R EE_HWREG(0xE000ED38)
+#define NVIC_CPAC_R EE_HWREG(0xE000ED88)
+#define NVIC_MPU_TYPE_R EE_HWREG(0xE000ED90)
+#define NVIC_MPU_CTRL_R EE_HWREG(0xE000ED94)
+#define NVIC_MPU_NUMBER_R EE_HWREG(0xE000ED98)
+#define NVIC_MPU_BASE_R EE_HWREG(0xE000ED9C)
+#define NVIC_MPU_ATTR_R EE_HWREG(0xE000EDA0)
+#define NVIC_MPU_BASE1_R EE_HWREG(0xE000EDA4)
+#define NVIC_MPU_ATTR1_R EE_HWREG(0xE000EDA8)
+#define NVIC_MPU_BASE2_R EE_HWREG(0xE000EDAC)
+#define NVIC_MPU_ATTR2_R EE_HWREG(0xE000EDB0)
+#define NVIC_MPU_BASE3_R EE_HWREG(0xE000EDB4)
+#define NVIC_MPU_ATTR3_R EE_HWREG(0xE000EDB8)
+#define NVIC_DBG_CTRL_R EE_HWREG(0xE000EDF0)
+#define NVIC_DBG_XFER_R EE_HWREG(0xE000EDF4)
+#define NVIC_DBG_DATA_R EE_HWREG(0xE000EDF8)
+#define NVIC_DBG_INT_R EE_HWREG(0xE000EDFC)
+#define NVIC_SW_TRIG_R EE_HWREG(0xE000EF00)
+#define NVIC_FPCC_R EE_HWREG(0xE000EF34)
+#define NVIC_FPCA_R EE_HWREG(0xE000EF38)
+#define NVIC_FPDSC_R EE_HWREG(0xE000EF3C)
+
+/* The following are defines for the bit fields in the NVIC_INT_TYPE register. */
+#define NVIC_INT_TYPE_LINES_M 0x0000001F /* Number of interrupt lines (x32) */
+#define NVIC_INT_TYPE_LINES_S 0
+
+/* The following are defines for the bit fields in the NVIC_ACTLR register. */
+#define NVIC_ACTLR_DISOOFP 0x00000200 /* Disable Out-Of-Order Floating */
+ /* Point */
+#define NVIC_ACTLR_DISFPCA 0x00000100 /* Disable CONTROL */
+#define NVIC_ACTLR_DISFOLD 0x00000004 /* Disable IT Folding */
+#define NVIC_ACTLR_DISWBUF 0x00000002 /* Disable Write Buffer */
+#define NVIC_ACTLR_DISMCYC 0x00000001 /* Disable Interrupts of Multiple */
+ /* Cycle Instructions */
+
+/* The following are defines for the bit fields in the NVIC_ST_CTRL register. */
+#define NVIC_ST_CTRL_COUNT 0x00010000 /* Count Flag */
+#define NVIC_ST_CTRL_CLK_SRC 0x00000004 /* Clock Source */
+#define NVIC_ST_CTRL_INTEN 0x00000002 /* Interrupt Enable */
+#define NVIC_ST_CTRL_ENABLE 0x00000001 /* Enable */
+
+/* The following are defines for the bit fields in the NVIC_ST_RELOAD register. */
+#define NVIC_ST_RELOAD_M 0x00FFFFFF /* Reload Value */
+#define NVIC_ST_RELOAD_S 0
+
+/* The following are defines for the bit fields in the NVIC_ST_CURRENT
+ * register. */
+#define NVIC_ST_CURRENT_M 0x00FFFFFF /* Current Value */
+#define NVIC_ST_CURRENT_S 0
+
+/* The following are defines for the bit fields in the NVIC_ST_CAL register. */
+#define NVIC_ST_CAL_NOREF 0x80000000 /* No reference clock */
+#define NVIC_ST_CAL_SKEW 0x40000000 /* Clock skew */
+#define NVIC_ST_CAL_ONEMS_M 0x00FFFFFF /* 1ms reference value */
+#define NVIC_ST_CAL_ONEMS_S 0
+
+/* The following are defines for the bit fields in the NVIC_EN0 register. */
+#define NVIC_EN0_INT_M 0xFFFFFFFF /* Interrupt Enable */
+#define NVIC_EN0_INT0 0x00000001 /* Interrupt 0 enable */
+#define NVIC_EN0_INT1 0x00000002 /* Interrupt 1 enable */
+#define NVIC_EN0_INT2 0x00000004 /* Interrupt 2 enable */
+#define NVIC_EN0_INT3 0x00000008 /* Interrupt 3 enable */
+#define NVIC_EN0_INT4 0x00000010 /* Interrupt 4 enable */
+#define NVIC_EN0_INT5 0x00000020 /* Interrupt 5 enable */
+#define NVIC_EN0_INT6 0x00000040 /* Interrupt 6 enable */
+#define NVIC_EN0_INT7 0x00000080 /* Interrupt 7 enable */
+#define NVIC_EN0_INT8 0x00000100 /* Interrupt 8 enable */
+#define NVIC_EN0_INT9 0x00000200 /* Interrupt 9 enable */
+#define NVIC_EN0_INT10 0x00000400 /* Interrupt 10 enable */
+#define NVIC_EN0_INT11 0x00000800 /* Interrupt 11 enable */
+#define NVIC_EN0_INT12 0x00001000 /* Interrupt 12 enable */
+#define NVIC_EN0_INT13 0x00002000 /* Interrupt 13 enable */
+#define NVIC_EN0_INT14 0x00004000 /* Interrupt 14 enable */
+#define NVIC_EN0_INT15 0x00008000 /* Interrupt 15 enable */
+#define NVIC_EN0_INT16 0x00010000 /* Interrupt 16 enable */
+#define NVIC_EN0_INT17 0x00020000 /* Interrupt 17 enable */
+#define NVIC_EN0_INT18 0x00040000 /* Interrupt 18 enable */
+#define NVIC_EN0_INT19 0x00080000 /* Interrupt 19 enable */
+#define NVIC_EN0_INT20 0x00100000 /* Interrupt 20 enable */
+#define NVIC_EN0_INT21 0x00200000 /* Interrupt 21 enable */
+#define NVIC_EN0_INT22 0x00400000 /* Interrupt 22 enable */
+#define NVIC_EN0_INT23 0x00800000 /* Interrupt 23 enable */
+#define NVIC_EN0_INT24 0x01000000 /* Interrupt 24 enable */
+#define NVIC_EN0_INT25 0x02000000 /* Interrupt 25 enable */
+#define NVIC_EN0_INT26 0x04000000 /* Interrupt 26 enable */
+#define NVIC_EN0_INT27 0x08000000 /* Interrupt 27 enable */
+#define NVIC_EN0_INT28 0x10000000 /* Interrupt 28 enable */
+#define NVIC_EN0_INT29 0x20000000 /* Interrupt 29 enable */
+#define NVIC_EN0_INT30 0x40000000 /* Interrupt 30 enable */
+#define NVIC_EN0_INT31 0x80000000 /* Interrupt 31 enable */
+
+/* The following are defines for the bit fields in the NVIC_EN1 register. */
+#define NVIC_EN1_INT_M 0xFFFFFFFF /* Interrupt Enable */
+
+/* The following are defines for the bit fields in the NVIC_EN2 register. */
+#define NVIC_EN2_INT_M 0xFFFFFFFF /* Interrupt Enable */
+
+/* The following are defines for the bit fields in the NVIC_EN3 register. */
+#define NVIC_EN3_INT_M 0xFFFFFFFF /* Interrupt Enable */
+
+/* The following are defines for the bit fields in the NVIC_EN4 register. */
+#define NVIC_EN4_INT_M 0x0000000F /* Interrupt Enable */
+
+/* The following are defines for the bit fields in the NVIC_DIS0 register. */
+#define NVIC_DIS0_INT_M 0xFFFFFFFF /* Interrupt Disable */
+#define NVIC_DIS0_INT0 0x00000001 /* Interrupt 0 disable */
+#define NVIC_DIS0_INT1 0x00000002 /* Interrupt 1 disable */
+#define NVIC_DIS0_INT2 0x00000004 /* Interrupt 2 disable */
+#define NVIC_DIS0_INT3 0x00000008 /* Interrupt 3 disable */
+#define NVIC_DIS0_INT4 0x00000010 /* Interrupt 4 disable */
+#define NVIC_DIS0_INT5 0x00000020 /* Interrupt 5 disable */
+#define NVIC_DIS0_INT6 0x00000040 /* Interrupt 6 disable */
+#define NVIC_DIS0_INT7 0x00000080 /* Interrupt 7 disable */
+#define NVIC_DIS0_INT8 0x00000100 /* Interrupt 8 disable */
+#define NVIC_DIS0_INT9 0x00000200 /* Interrupt 9 disable */
+#define NVIC_DIS0_INT10 0x00000400 /* Interrupt 10 disable */
+#define NVIC_DIS0_INT11 0x00000800 /* Interrupt 11 disable */
+#define NVIC_DIS0_INT12 0x00001000 /* Interrupt 12 disable */
+#define NVIC_DIS0_INT13 0x00002000 /* Interrupt 13 disable */
+#define NVIC_DIS0_INT14 0x00004000 /* Interrupt 14 disable */
+#define NVIC_DIS0_INT15 0x00008000 /* Interrupt 15 disable */
+#define NVIC_DIS0_INT16 0x00010000 /* Interrupt 16 disable */
+#define NVIC_DIS0_INT17 0x00020000 /* Interrupt 17 disable */
+#define NVIC_DIS0_INT18 0x00040000 /* Interrupt 18 disable */
+#define NVIC_DIS0_INT19 0x00080000 /* Interrupt 19 disable */
+#define NVIC_DIS0_INT20 0x00100000 /* Interrupt 20 disable */
+#define NVIC_DIS0_INT21 0x00200000 /* Interrupt 21 disable */
+#define NVIC_DIS0_INT22 0x00400000 /* Interrupt 22 disable */
+#define NVIC_DIS0_INT23 0x00800000 /* Interrupt 23 disable */
+#define NVIC_DIS0_INT24 0x01000000 /* Interrupt 24 disable */
+#define NVIC_DIS0_INT25 0x02000000 /* Interrupt 25 disable */
+#define NVIC_DIS0_INT26 0x04000000 /* Interrupt 26 disable */
+#define NVIC_DIS0_INT27 0x08000000 /* Interrupt 27 disable */
+#define NVIC_DIS0_INT28 0x10000000 /* Interrupt 28 disable */
+#define NVIC_DIS0_INT29 0x20000000 /* Interrupt 29 disable */
+#define NVIC_DIS0_INT30 0x40000000 /* Interrupt 30 disable */
+#define NVIC_DIS0_INT31 0x80000000 /* Interrupt 31 disable */
+
+/* The following are defines for the bit fields in the NVIC_DIS1 register. */
+#define NVIC_DIS1_INT_M 0xFFFFFFFF /* Interrupt Disable */
+
+/* The following are defines for the bit fields in the NVIC_DIS2 register. */
+#define NVIC_DIS2_INT_M 0xFFFFFFFF /* Interrupt Disable */
+
+/* The following are defines for the bit fields in the NVIC_DIS3 register. */
+#define NVIC_DIS3_INT_M 0xFFFFFFFF /* Interrupt Disable */
+
+/* The following are defines for the bit fields in the NVIC_DIS4 register. */
+#define NVIC_DIS4_INT_M 0x0000000F /* Interrupt Disable */
+
+/* The following are defines for the bit fields in the NVIC_PEND0 register. */
+#define NVIC_PEND0_INT_M 0xFFFFFFFF /* Interrupt Set Pending */
+#define NVIC_PEND0_INT0 0x00000001 /* Interrupt 0 pend */
+#define NVIC_PEND0_INT1 0x00000002 /* Interrupt 1 pend */
+#define NVIC_PEND0_INT2 0x00000004 /* Interrupt 2 pend */
+#define NVIC_PEND0_INT3 0x00000008 /* Interrupt 3 pend */
+#define NVIC_PEND0_INT4 0x00000010 /* Interrupt 4 pend */
+#define NVIC_PEND0_INT5 0x00000020 /* Interrupt 5 pend */
+#define NVIC_PEND0_INT6 0x00000040 /* Interrupt 6 pend */
+#define NVIC_PEND0_INT7 0x00000080 /* Interrupt 7 pend */
+#define NVIC_PEND0_INT8 0x00000100 /* Interrupt 8 pend */
+#define NVIC_PEND0_INT9 0x00000200 /* Interrupt 9 pend */
+#define NVIC_PEND0_INT10 0x00000400 /* Interrupt 10 pend */
+#define NVIC_PEND0_INT11 0x00000800 /* Interrupt 11 pend */
+#define NVIC_PEND0_INT12 0x00001000 /* Interrupt 12 pend */
+#define NVIC_PEND0_INT13 0x00002000 /* Interrupt 13 pend */
+#define NVIC_PEND0_INT14 0x00004000 /* Interrupt 14 pend */
+#define NVIC_PEND0_INT15 0x00008000 /* Interrupt 15 pend */
+#define NVIC_PEND0_INT16 0x00010000 /* Interrupt 16 pend */
+#define NVIC_PEND0_INT17 0x00020000 /* Interrupt 17 pend */
+#define NVIC_PEND0_INT18 0x00040000 /* Interrupt 18 pend */
+#define NVIC_PEND0_INT19 0x00080000 /* Interrupt 19 pend */
+#define NVIC_PEND0_INT20 0x00100000 /* Interrupt 20 pend */
+#define NVIC_PEND0_INT21 0x00200000 /* Interrupt 21 pend */
+#define NVIC_PEND0_INT22 0x00400000 /* Interrupt 22 pend */
+#define NVIC_PEND0_INT23 0x00800000 /* Interrupt 23 pend */
+#define NVIC_PEND0_INT24 0x01000000 /* Interrupt 24 pend */
+#define NVIC_PEND0_INT25 0x02000000 /* Interrupt 25 pend */
+#define NVIC_PEND0_INT26 0x04000000 /* Interrupt 26 pend */
+#define NVIC_PEND0_INT27 0x08000000 /* Interrupt 27 pend */
+#define NVIC_PEND0_INT28 0x10000000 /* Interrupt 28 pend */
+#define NVIC_PEND0_INT29 0x20000000 /* Interrupt 29 pend */
+#define NVIC_PEND0_INT30 0x40000000 /* Interrupt 30 pend */
+#define NVIC_PEND0_INT31 0x80000000 /* Interrupt 31 pend */
+
+/* The following are defines for the bit fields in the NVIC_PEND1 register. */
+#define NVIC_PEND1_INT_M 0xFFFFFFFF /* Interrupt Set Pending */
+
+/* The following are defines for the bit fields in the NVIC_PEND2 register. */
+#define NVIC_PEND2_INT_M 0xFFFFFFFF /* Interrupt Set Pending */
+
+/* The following are defines for the bit fields in the NVIC_PEND3 register. */
+#define NVIC_PEND3_INT_M 0xFFFFFFFF /* Interrupt Set Pending */
+
+/* The following are defines for the bit fields in the NVIC_PEND4 register. */
+#define NVIC_PEND4_INT_M 0x0000000F /* Interrupt Set Pending */
+
+/* The following are defines for the bit fields in the NVIC_UNPEND0 register. */
+#define NVIC_UNPEND0_INT_M 0xFFFFFFFF /* Interrupt Clear Pending */
+#define NVIC_UNPEND0_INT0 0x00000001 /* Interrupt 0 unpend */
+#define NVIC_UNPEND0_INT1 0x00000002 /* Interrupt 1 unpend */
+#define NVIC_UNPEND0_INT2 0x00000004 /* Interrupt 2 unpend */
+#define NVIC_UNPEND0_INT3 0x00000008 /* Interrupt 3 unpend */
+#define NVIC_UNPEND0_INT4 0x00000010 /* Interrupt 4 unpend */
+#define NVIC_UNPEND0_INT5 0x00000020 /* Interrupt 5 unpend */
+#define NVIC_UNPEND0_INT6 0x00000040 /* Interrupt 6 unpend */
+#define NVIC_UNPEND0_INT7 0x00000080 /* Interrupt 7 unpend */
+#define NVIC_UNPEND0_INT8 0x00000100 /* Interrupt 8 unpend */
+#define NVIC_UNPEND0_INT9 0x00000200 /* Interrupt 9 unpend */
+#define NVIC_UNPEND0_INT10 0x00000400 /* Interrupt 10 unpend */
+#define NVIC_UNPEND0_INT11 0x00000800 /* Interrupt 11 unpend */
+#define NVIC_UNPEND0_INT12 0x00001000 /* Interrupt 12 unpend */
+#define NVIC_UNPEND0_INT13 0x00002000 /* Interrupt 13 unpend */
+#define NVIC_UNPEND0_INT14 0x00004000 /* Interrupt 14 unpend */
+#define NVIC_UNPEND0_INT15 0x00008000 /* Interrupt 15 unpend */
+#define NVIC_UNPEND0_INT16 0x00010000 /* Interrupt 16 unpend */
+#define NVIC_UNPEND0_INT17 0x00020000 /* Interrupt 17 unpend */
+#define NVIC_UNPEND0_INT18 0x00040000 /* Interrupt 18 unpend */
+#define NVIC_UNPEND0_INT19 0x00080000 /* Interrupt 19 unpend */
+#define NVIC_UNPEND0_INT20 0x00100000 /* Interrupt 20 unpend */
+#define NVIC_UNPEND0_INT21 0x00200000 /* Interrupt 21 unpend */
+#define NVIC_UNPEND0_INT22 0x00400000 /* Interrupt 22 unpend */
+#define NVIC_UNPEND0_INT23 0x00800000 /* Interrupt 23 unpend */
+#define NVIC_UNPEND0_INT24 0x01000000 /* Interrupt 24 unpend */
+#define NVIC_UNPEND0_INT25 0x02000000 /* Interrupt 25 unpend */
+#define NVIC_UNPEND0_INT26 0x04000000 /* Interrupt 26 unpend */
+#define NVIC_UNPEND0_INT27 0x08000000 /* Interrupt 27 unpend */
+#define NVIC_UNPEND0_INT28 0x10000000 /* Interrupt 28 unpend */
+#define NVIC_UNPEND0_INT29 0x20000000 /* Interrupt 29 unpend */
+#define NVIC_UNPEND0_INT30 0x40000000 /* Interrupt 30 unpend */
+#define NVIC_UNPEND0_INT31 0x80000000 /* Interrupt 31 unpend */
+
+/* The following are defines for the bit fields in the NVIC_UNPEND1 register. */
+#define NVIC_UNPEND1_INT_M 0xFFFFFFFF /* Interrupt Clear Pending */
+#define NVIC_UNPEND1_INT32 0x00000001 /* Interrupt 32 unpend */
+#define NVIC_UNPEND1_INT33 0x00000002 /* Interrupt 33 unpend */
+#define NVIC_UNPEND1_INT34 0x00000004 /* Interrupt 34 unpend */
+#define NVIC_UNPEND1_INT35 0x00000008 /* Interrupt 35 unpend */
+#define NVIC_UNPEND1_INT36 0x00000010 /* Interrupt 36 unpend */
+#define NVIC_UNPEND1_INT37 0x00000020 /* Interrupt 37 unpend */
+#define NVIC_UNPEND1_INT38 0x00000040 /* Interrupt 38 unpend */
+#define NVIC_UNPEND1_INT39 0x00000080 /* Interrupt 39 unpend */
+#define NVIC_UNPEND1_INT40 0x00000100 /* Interrupt 40 unpend */
+#define NVIC_UNPEND1_INT41 0x00000200 /* Interrupt 41 unpend */
+#define NVIC_UNPEND1_INT42 0x00000400 /* Interrupt 42 unpend */
+#define NVIC_UNPEND1_INT43 0x00000800 /* Interrupt 43 unpend */
+#define NVIC_UNPEND1_INT44 0x00001000 /* Interrupt 44 unpend */
+#define NVIC_UNPEND1_INT45 0x00002000 /* Interrupt 45 unpend */
+#define NVIC_UNPEND1_INT46 0x00004000 /* Interrupt 46 unpend */
+#define NVIC_UNPEND1_INT47 0x00008000 /* Interrupt 47 unpend */
+#define NVIC_UNPEND1_INT48 0x00010000 /* Interrupt 48 unpend */
+#define NVIC_UNPEND1_INT49 0x00020000 /* Interrupt 49 unpend */
+#define NVIC_UNPEND1_INT50 0x00040000 /* Interrupt 50 unpend */
+#define NVIC_UNPEND1_INT51 0x00080000 /* Interrupt 51 unpend */
+#define NVIC_UNPEND1_INT52 0x00100000 /* Interrupt 52 unpend */
+#define NVIC_UNPEND1_INT53 0x00200000 /* Interrupt 53 unpend */
+#define NVIC_UNPEND1_INT54 0x00400000 /* Interrupt 54 unpend */
+#define NVIC_UNPEND1_INT55 0x00800000 /* Interrupt 55 unpend */
+
+/* The following are defines for the bit fields in the NVIC_UNPEND2 register. */
+#define NVIC_UNPEND2_INT_M 0xFFFFFFFF /* Interrupt Clear Pending */
+
+/* The following are defines for the bit fields in the NVIC_UNPEND3 register. */
+#define NVIC_UNPEND3_INT_M 0xFFFFFFFF /* Interrupt Clear Pending */
+
+/* The following are defines for the bit fields in the NVIC_UNPEND4 register. */
+#define NVIC_UNPEND4_INT_M 0x0000000F /* Interrupt Clear Pending */
+
+/* The following are defines for the bit fields in the NVIC_ACTIVE0 register. */
+#define NVIC_ACTIVE0_INT_M 0xFFFFFFFF /* Interrupt Active */
+#define NVIC_ACTIVE0_INT0 0x00000001 /* Interrupt 0 active */
+#define NVIC_ACTIVE0_INT1 0x00000002 /* Interrupt 1 active */
+#define NVIC_ACTIVE0_INT2 0x00000004 /* Interrupt 2 active */
+#define NVIC_ACTIVE0_INT3 0x00000008 /* Interrupt 3 active */
+#define NVIC_ACTIVE0_INT4 0x00000010 /* Interrupt 4 active */
+#define NVIC_ACTIVE0_INT5 0x00000020 /* Interrupt 5 active */
+#define NVIC_ACTIVE0_INT6 0x00000040 /* Interrupt 6 active */
+#define NVIC_ACTIVE0_INT7 0x00000080 /* Interrupt 7 active */
+#define NVIC_ACTIVE0_INT8 0x00000100 /* Interrupt 8 active */
+#define NVIC_ACTIVE0_INT9 0x00000200 /* Interrupt 9 active */
+#define NVIC_ACTIVE0_INT10 0x00000400 /* Interrupt 10 active */
+#define NVIC_ACTIVE0_INT11 0x00000800 /* Interrupt 11 active */
+#define NVIC_ACTIVE0_INT12 0x00001000 /* Interrupt 12 active */
+#define NVIC_ACTIVE0_INT13 0x00002000 /* Interrupt 13 active */
+#define NVIC_ACTIVE0_INT14 0x00004000 /* Interrupt 14 active */
+#define NVIC_ACTIVE0_INT15 0x00008000 /* Interrupt 15 active */
+#define NVIC_ACTIVE0_INT16 0x00010000 /* Interrupt 16 active */
+#define NVIC_ACTIVE0_INT17 0x00020000 /* Interrupt 17 active */
+#define NVIC_ACTIVE0_INT18 0x00040000 /* Interrupt 18 active */
+#define NVIC_ACTIVE0_INT19 0x00080000 /* Interrupt 19 active */
+#define NVIC_ACTIVE0_INT20 0x00100000 /* Interrupt 20 active */
+#define NVIC_ACTIVE0_INT21 0x00200000 /* Interrupt 21 active */
+#define NVIC_ACTIVE0_INT22 0x00400000 /* Interrupt 22 active */
+#define NVIC_ACTIVE0_INT23 0x00800000 /* Interrupt 23 active */
+#define NVIC_ACTIVE0_INT24 0x01000000 /* Interrupt 24 active */
+#define NVIC_ACTIVE0_INT25 0x02000000 /* Interrupt 25 active */
+#define NVIC_ACTIVE0_INT26 0x04000000 /* Interrupt 26 active */
+#define NVIC_ACTIVE0_INT27 0x08000000 /* Interrupt 27 active */
+#define NVIC_ACTIVE0_INT28 0x10000000 /* Interrupt 28 active */
+#define NVIC_ACTIVE0_INT29 0x20000000 /* Interrupt 29 active */
+#define NVIC_ACTIVE0_INT30 0x40000000 /* Interrupt 30 active */
+#define NVIC_ACTIVE0_INT31 0x80000000 /* Interrupt 31 active */
+
+/* The following are defines for the bit fields in the NVIC_ACTIVE1 register. */
+#define NVIC_ACTIVE1_INT_M 0xFFFFFFFF /* Interrupt Active */
+
+/* The following are defines for the bit fields in the NVIC_ACTIVE2 register. */
+#define NVIC_ACTIVE2_INT_M 0xFFFFFFFF /* Interrupt Active */
+
+/* The following are defines for the bit fields in the NVIC_ACTIVE3 register. */
+#define NVIC_ACTIVE3_INT_M 0xFFFFFFFF /* Interrupt Active */
+
+/* The following are defines for the bit fields in the NVIC_ACTIVE4 register. */
+#define NVIC_ACTIVE4_INT_M 0x0000000F /* Interrupt Active */
+
+/* The following are defines for the bit fields in the NVIC_PRI0 register. */
+#define NVIC_PRI0_INT3_M 0xE0000000 /* Interrupt 3 Priority Mask */
+#define NVIC_PRI0_INT2_M 0x00E00000 /* Interrupt 2 Priority Mask */
+#define NVIC_PRI0_INT1_M 0x0000E000 /* Interrupt 1 Priority Mask */
+#define NVIC_PRI0_INT0_M 0x000000E0 /* Interrupt 0 Priority Mask */
+#define NVIC_PRI0_INT3_S 29
+#define NVIC_PRI0_INT2_S 21
+#define NVIC_PRI0_INT1_S 13
+#define NVIC_PRI0_INT0_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI1 register. */
+#define NVIC_PRI1_INT7_M 0xE0000000 /* Interrupt 7 Priority Mask */
+#define NVIC_PRI1_INT6_M 0x00E00000 /* Interrupt 6 Priority Mask */
+#define NVIC_PRI1_INT5_M 0x0000E000 /* Interrupt 5 Priority Mask */
+#define NVIC_PRI1_INT4_M 0x000000E0 /* Interrupt 4 Priority Mask */
+#define NVIC_PRI1_INT7_S 29
+#define NVIC_PRI1_INT6_S 21
+#define NVIC_PRI1_INT5_S 13
+#define NVIC_PRI1_INT4_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI2 register. */
+#define NVIC_PRI2_INT11_M 0xE0000000 /* Interrupt 11 Priority Mask */
+#define NVIC_PRI2_INT10_M 0x00E00000 /* Interrupt 10 Priority Mask */
+#define NVIC_PRI2_INT9_M 0x0000E000 /* Interrupt 9 Priority Mask */
+#define NVIC_PRI2_INT8_M 0x000000E0 /* Interrupt 8 Priority Mask */
+#define NVIC_PRI2_INT11_S 29
+#define NVIC_PRI2_INT10_S 21
+#define NVIC_PRI2_INT9_S 13
+#define NVIC_PRI2_INT8_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI3 register. */
+#define NVIC_PRI3_INT15_M 0xE0000000 /* Interrupt 15 Priority Mask */
+#define NVIC_PRI3_INT14_M 0x00E00000 /* Interrupt 14 Priority Mask */
+#define NVIC_PRI3_INT13_M 0x0000E000 /* Interrupt 13 Priority Mask */
+#define NVIC_PRI3_INT12_M 0x000000E0 /* Interrupt 12 Priority Mask */
+#define NVIC_PRI3_INT15_S 29
+#define NVIC_PRI3_INT14_S 21
+#define NVIC_PRI3_INT13_S 13
+#define NVIC_PRI3_INT12_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI4 register. */
+#define NVIC_PRI4_INT19_M 0xE0000000 /* Interrupt 19 Priority Mask */
+#define NVIC_PRI4_INT18_M 0x00E00000 /* Interrupt 18 Priority Mask */
+#define NVIC_PRI4_INT17_M 0x0000E000 /* Interrupt 17 Priority Mask */
+#define NVIC_PRI4_INT16_M 0x000000E0 /* Interrupt 16 Priority Mask */
+#define NVIC_PRI4_INT19_S 29
+#define NVIC_PRI4_INT18_S 21
+#define NVIC_PRI4_INT17_S 13
+#define NVIC_PRI4_INT16_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI5 register. */
+#define NVIC_PRI5_INT23_M 0xE0000000 /* Interrupt 23 Priority Mask */
+#define NVIC_PRI5_INT22_M 0x00E00000 /* Interrupt 22 Priority Mask */
+#define NVIC_PRI5_INT21_M 0x0000E000 /* Interrupt 21 Priority Mask */
+#define NVIC_PRI5_INT20_M 0x000000E0 /* Interrupt 20 Priority Mask */
+#define NVIC_PRI5_INT23_S 29
+#define NVIC_PRI5_INT22_S 21
+#define NVIC_PRI5_INT21_S 13
+#define NVIC_PRI5_INT20_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI6 register. */
+#define NVIC_PRI6_INT27_M 0xE0000000 /* Interrupt 27 Priority Mask */
+#define NVIC_PRI6_INT26_M 0x00E00000 /* Interrupt 26 Priority Mask */
+#define NVIC_PRI6_INT25_M 0x0000E000 /* Interrupt 25 Priority Mask */
+#define NVIC_PRI6_INT24_M 0x000000E0 /* Interrupt 24 Priority Mask */
+#define NVIC_PRI6_INT27_S 29
+#define NVIC_PRI6_INT26_S 21
+#define NVIC_PRI6_INT25_S 13
+#define NVIC_PRI6_INT24_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI7 register. */
+#define NVIC_PRI7_INT31_M 0xE0000000 /* Interrupt 31 Priority Mask */
+#define NVIC_PRI7_INT30_M 0x00E00000 /* Interrupt 30 Priority Mask */
+#define NVIC_PRI7_INT29_M 0x0000E000 /* Interrupt 29 Priority Mask */
+#define NVIC_PRI7_INT28_M 0x000000E0 /* Interrupt 28 Priority Mask */
+#define NVIC_PRI7_INT31_S 29
+#define NVIC_PRI7_INT30_S 21
+#define NVIC_PRI7_INT29_S 13
+#define NVIC_PRI7_INT28_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI8 register. */
+#define NVIC_PRI8_INT35_M 0xE0000000 /* Interrupt 35 Priority Mask */
+#define NVIC_PRI8_INT34_M 0x00E00000 /* Interrupt 34 Priority Mask */
+#define NVIC_PRI8_INT33_M 0x0000E000 /* Interrupt 33 Priority Mask */
+#define NVIC_PRI8_INT32_M 0x000000E0 /* Interrupt 32 Priority Mask */
+#define NVIC_PRI8_INT35_S 29
+#define NVIC_PRI8_INT34_S 21
+#define NVIC_PRI8_INT33_S 13
+#define NVIC_PRI8_INT32_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI9 register. */
+#define NVIC_PRI9_INT39_M 0xE0000000 /* Interrupt 39 Priority Mask */
+#define NVIC_PRI9_INT38_M 0x00E00000 /* Interrupt 38 Priority Mask */
+#define NVIC_PRI9_INT37_M 0x0000E000 /* Interrupt 37 Priority Mask */
+#define NVIC_PRI9_INT36_M 0x000000E0 /* Interrupt 36 Priority Mask */
+#define NVIC_PRI9_INT39_S 29
+#define NVIC_PRI9_INT38_S 21
+#define NVIC_PRI9_INT37_S 13
+#define NVIC_PRI9_INT36_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI10 register. */
+#define NVIC_PRI10_INT43_M 0xE0000000 /* Interrupt 43 Priority Mask */
+#define NVIC_PRI10_INT42_M 0x00E00000 /* Interrupt 42 Priority Mask */
+#define NVIC_PRI10_INT41_M 0x0000E000 /* Interrupt 41 Priority Mask */
+#define NVIC_PRI10_INT40_M 0x000000E0 /* Interrupt 40 Priority Mask */
+#define NVIC_PRI10_INT43_S 29
+#define NVIC_PRI10_INT42_S 21
+#define NVIC_PRI10_INT41_S 13
+#define NVIC_PRI10_INT40_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI11 register. */
+#define NVIC_PRI11_INT47_M 0xE0000000 /* Interrupt 47 Priority Mask */
+#define NVIC_PRI11_INT46_M 0x00E00000 /* Interrupt 46 Priority Mask */
+#define NVIC_PRI11_INT45_M 0x0000E000 /* Interrupt 45 Priority Mask */
+#define NVIC_PRI11_INT44_M 0x000000E0 /* Interrupt 44 Priority Mask */
+#define NVIC_PRI11_INT47_S 29
+#define NVIC_PRI11_INT46_S 21
+#define NVIC_PRI11_INT45_S 13
+#define NVIC_PRI11_INT44_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI12 register. */
+#define NVIC_PRI12_INT51_M 0xE0000000 /* Interrupt 51 Priority Mask */
+#define NVIC_PRI12_INT50_M 0x00E00000 /* Interrupt 50 Priority Mask */
+#define NVIC_PRI12_INT49_M 0x0000E000 /* Interrupt 49 Priority Mask */
+#define NVIC_PRI12_INT48_M 0x000000E0 /* Interrupt 48 Priority Mask */
+#define NVIC_PRI12_INT51_S 29
+#define NVIC_PRI12_INT50_S 21
+#define NVIC_PRI12_INT49_S 13
+#define NVIC_PRI12_INT48_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI13 register. */
+#define NVIC_PRI13_INT55_M 0xE0000000 /* Interrupt 55 Priority Mask */
+#define NVIC_PRI13_INT54_M 0x00E00000 /* Interrupt 54 Priority Mask */
+#define NVIC_PRI13_INT53_M 0x0000E000 /* Interrupt 53 Priority Mask */
+#define NVIC_PRI13_INT52_M 0x000000E0 /* Interrupt 52 Priority Mask */
+#define NVIC_PRI13_INT55_S 29
+#define NVIC_PRI13_INT54_S 21
+#define NVIC_PRI13_INT53_S 13
+#define NVIC_PRI13_INT52_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI14 register. */
+#define NVIC_PRI14_INTD_M 0xE0000000 /* Interrupt 59 Priority Mask */
+#define NVIC_PRI14_INTC_M 0x00E00000 /* Interrupt 58 Priority Mask */
+#define NVIC_PRI14_INTB_M 0x0000E000 /* Interrupt 57 Priority Mask */
+#define NVIC_PRI14_INTA_M 0x000000E0 /* Interrupt 56 Priority Mask */
+#define NVIC_PRI14_INTD_S 29
+#define NVIC_PRI14_INTC_S 21
+#define NVIC_PRI14_INTB_S 13
+#define NVIC_PRI14_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI15 register. */
+#define NVIC_PRI15_INTD_M 0xE0000000 /* Interrupt 63 Priority Mask */
+#define NVIC_PRI15_INTC_M 0x00E00000 /* Interrupt 62 Priority Mask */
+#define NVIC_PRI15_INTB_M 0x0000E000 /* Interrupt 61 Priority Mask */
+#define NVIC_PRI15_INTA_M 0x000000E0 /* Interrupt 60 Priority Mask */
+#define NVIC_PRI15_INTD_S 29
+#define NVIC_PRI15_INTC_S 21
+#define NVIC_PRI15_INTB_S 13
+#define NVIC_PRI15_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI16 register. */
+#define NVIC_PRI16_INTD_M 0xE0000000 /* Interrupt 67 Priority Mask */
+#define NVIC_PRI16_INTC_M 0x00E00000 /* Interrupt 66 Priority Mask */
+#define NVIC_PRI16_INTB_M 0x0000E000 /* Interrupt 65 Priority Mask */
+#define NVIC_PRI16_INTA_M 0x000000E0 /* Interrupt 64 Priority Mask */
+#define NVIC_PRI16_INTD_S 29
+#define NVIC_PRI16_INTC_S 21
+#define NVIC_PRI16_INTB_S 13
+#define NVIC_PRI16_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI17 register. */
+#define NVIC_PRI17_INTD_M 0xE0000000 /* Interrupt 71 Priority Mask */
+#define NVIC_PRI17_INTC_M 0x00E00000 /* Interrupt 70 Priority Mask */
+#define NVIC_PRI17_INTB_M 0x0000E000 /* Interrupt 69 Priority Mask */
+#define NVIC_PRI17_INTA_M 0x000000E0 /* Interrupt 68 Priority Mask */
+#define NVIC_PRI17_INTD_S 29
+#define NVIC_PRI17_INTC_S 21
+#define NVIC_PRI17_INTB_S 13
+#define NVIC_PRI17_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI18 register. */
+#define NVIC_PRI18_INTD_M 0xE0000000 /* Interrupt 75 Priority Mask */
+#define NVIC_PRI18_INTC_M 0x00E00000 /* Interrupt 74 Priority Mask */
+#define NVIC_PRI18_INTB_M 0x0000E000 /* Interrupt 73 Priority Mask */
+#define NVIC_PRI18_INTA_M 0x000000E0 /* Interrupt 72 Priority Mask */
+#define NVIC_PRI18_INTD_S 29
+#define NVIC_PRI18_INTC_S 21
+#define NVIC_PRI18_INTB_S 13
+#define NVIC_PRI18_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI19 register. */
+#define NVIC_PRI19_INTD_M 0xE0000000 /* Interrupt 79 Priority Mask */
+#define NVIC_PRI19_INTC_M 0x00E00000 /* Interrupt 78 Priority Mask */
+#define NVIC_PRI19_INTB_M 0x0000E000 /* Interrupt 77 Priority Mask */
+#define NVIC_PRI19_INTA_M 0x000000E0 /* Interrupt 76 Priority Mask */
+#define NVIC_PRI19_INTD_S 29
+#define NVIC_PRI19_INTC_S 21
+#define NVIC_PRI19_INTB_S 13
+#define NVIC_PRI19_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI20 register. */
+#define NVIC_PRI20_INTD_M 0xE0000000 /* Interrupt 83 Priority Mask */
+#define NVIC_PRI20_INTC_M 0x00E00000 /* Interrupt 82 Priority Mask */
+#define NVIC_PRI20_INTB_M 0x0000E000 /* Interrupt 81 Priority Mask */
+#define NVIC_PRI20_INTA_M 0x000000E0 /* Interrupt 80 Priority Mask */
+#define NVIC_PRI20_INTD_S 29
+#define NVIC_PRI20_INTC_S 21
+#define NVIC_PRI20_INTB_S 13
+#define NVIC_PRI20_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI21 register. */
+#define NVIC_PRI21_INTD_M 0xE0000000 /* Interrupt 87 Priority Mask */
+#define NVIC_PRI21_INTC_M 0x00E00000 /* Interrupt 86 Priority Mask */
+#define NVIC_PRI21_INTB_M 0x0000E000 /* Interrupt 85 Priority Mask */
+#define NVIC_PRI21_INTA_M 0x000000E0 /* Interrupt 84 Priority Mask */
+#define NVIC_PRI21_INTD_S 29
+#define NVIC_PRI21_INTC_S 21
+#define NVIC_PRI21_INTB_S 13
+#define NVIC_PRI21_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI22 register. */
+#define NVIC_PRI22_INTD_M 0xE0000000 /* Interrupt 91 Priority Mask */
+#define NVIC_PRI22_INTC_M 0x00E00000 /* Interrupt 90 Priority Mask */
+#define NVIC_PRI22_INTB_M 0x0000E000 /* Interrupt 89 Priority Mask */
+#define NVIC_PRI22_INTA_M 0x000000E0 /* Interrupt 88 Priority Mask */
+#define NVIC_PRI22_INTD_S 29
+#define NVIC_PRI22_INTC_S 21
+#define NVIC_PRI22_INTB_S 13
+#define NVIC_PRI22_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI23 register. */
+#define NVIC_PRI23_INTD_M 0xE0000000 /* Interrupt 95 Priority Mask */
+#define NVIC_PRI23_INTC_M 0x00E00000 /* Interrupt 94 Priority Mask */
+#define NVIC_PRI23_INTB_M 0x0000E000 /* Interrupt 93 Priority Mask */
+#define NVIC_PRI23_INTA_M 0x000000E0 /* Interrupt 92 Priority Mask */
+#define NVIC_PRI23_INTD_S 29
+#define NVIC_PRI23_INTC_S 21
+#define NVIC_PRI23_INTB_S 13
+#define NVIC_PRI23_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI24 register. */
+#define NVIC_PRI24_INTD_M 0xE0000000 /* Interrupt 99 Priority Mask */
+#define NVIC_PRI24_INTC_M 0x00E00000 /* Interrupt 98 Priority Mask */
+#define NVIC_PRI24_INTB_M 0x0000E000 /* Interrupt 97 Priority Mask */
+#define NVIC_PRI24_INTA_M 0x000000E0 /* Interrupt 96 Priority Mask */
+#define NVIC_PRI24_INTD_S 29
+#define NVIC_PRI24_INTC_S 21
+#define NVIC_PRI24_INTB_S 13
+#define NVIC_PRI24_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI25 register. */
+#define NVIC_PRI25_INTD_M 0xE0000000 /* Interrupt 103 Priority Mask */
+#define NVIC_PRI25_INTC_M 0x00E00000 /* Interrupt 102 Priority Mask */
+#define NVIC_PRI25_INTB_M 0x0000E000 /* Interrupt 101 Priority Mask */
+#define NVIC_PRI25_INTA_M 0x000000E0 /* Interrupt 100 Priority Mask */
+#define NVIC_PRI25_INTD_S 29
+#define NVIC_PRI25_INTC_S 21
+#define NVIC_PRI25_INTB_S 13
+#define NVIC_PRI25_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI26 register. */
+#define NVIC_PRI26_INTD_M 0xE0000000 /* Interrupt 107 Priority Mask */
+#define NVIC_PRI26_INTC_M 0x00E00000 /* Interrupt 106 Priority Mask */
+#define NVIC_PRI26_INTB_M 0x0000E000 /* Interrupt 105 Priority Mask */
+#define NVIC_PRI26_INTA_M 0x000000E0 /* Interrupt 104 Priority Mask */
+#define NVIC_PRI26_INTD_S 29
+#define NVIC_PRI26_INTC_S 21
+#define NVIC_PRI26_INTB_S 13
+#define NVIC_PRI26_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI27 register. */
+#define NVIC_PRI27_INTD_M 0xE0000000 /* Interrupt 111 Priority Mask */
+#define NVIC_PRI27_INTC_M 0x00E00000 /* Interrupt 110 Priority Mask */
+#define NVIC_PRI27_INTB_M 0x0000E000 /* Interrupt 109 Priority Mask */
+#define NVIC_PRI27_INTA_M 0x000000E0 /* Interrupt 108 Priority Mask */
+#define NVIC_PRI27_INTD_S 29
+#define NVIC_PRI27_INTC_S 21
+#define NVIC_PRI27_INTB_S 13
+#define NVIC_PRI27_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI28 register. */
+#define NVIC_PRI28_INTD_M 0xE0000000 /* Interrupt 115 Priority Mask */
+#define NVIC_PRI28_INTC_M 0x00E00000 /* Interrupt 114 Priority Mask */
+#define NVIC_PRI28_INTB_M 0x0000E000 /* Interrupt 113 Priority Mask */
+#define NVIC_PRI28_INTA_M 0x000000E0 /* Interrupt 112 Priority Mask */
+#define NVIC_PRI28_INTD_S 29
+#define NVIC_PRI28_INTC_S 21
+#define NVIC_PRI28_INTB_S 13
+#define NVIC_PRI28_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI29 register. */
+#define NVIC_PRI29_INTD_M 0xE0000000 /* Interrupt 119 Priority Mask */
+#define NVIC_PRI29_INTC_M 0x00E00000 /* Interrupt 118 Priority Mask */
+#define NVIC_PRI29_INTB_M 0x0000E000 /* Interrupt 117 Priority Mask */
+#define NVIC_PRI29_INTA_M 0x000000E0 /* Interrupt 116 Priority Mask */
+#define NVIC_PRI29_INTD_S 29
+#define NVIC_PRI29_INTC_S 21
+#define NVIC_PRI29_INTB_S 13
+#define NVIC_PRI29_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI30 register. */
+#define NVIC_PRI30_INTD_M 0xE0000000 /* Interrupt 123 Priority Mask */
+#define NVIC_PRI30_INTC_M 0x00E00000 /* Interrupt 122 Priority Mask */
+#define NVIC_PRI30_INTB_M 0x0000E000 /* Interrupt 121 Priority Mask */
+#define NVIC_PRI30_INTA_M 0x000000E0 /* Interrupt 120 Priority Mask */
+#define NVIC_PRI30_INTD_S 29
+#define NVIC_PRI30_INTC_S 21
+#define NVIC_PRI30_INTB_S 13
+#define NVIC_PRI30_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI31 register. */
+#define NVIC_PRI31_INTD_M 0xE0000000 /* Interrupt 127 Priority Mask */
+#define NVIC_PRI31_INTC_M 0x00E00000 /* Interrupt 126 Priority Mask */
+#define NVIC_PRI31_INTB_M 0x0000E000 /* Interrupt 125 Priority Mask */
+#define NVIC_PRI31_INTA_M 0x000000E0 /* Interrupt 124 Priority Mask */
+#define NVIC_PRI31_INTD_S 29
+#define NVIC_PRI31_INTC_S 21
+#define NVIC_PRI31_INTB_S 13
+#define NVIC_PRI31_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_PRI32 register. */
+#define NVIC_PRI32_INTD_M 0xE0000000 /* Interrupt 131 Priority Mask */
+#define NVIC_PRI32_INTC_M 0x00E00000 /* Interrupt 130 Priority Mask */
+#define NVIC_PRI32_INTB_M 0x0000E000 /* Interrupt 129 Priority Mask */
+#define NVIC_PRI32_INTA_M 0x000000E0 /* Interrupt 128 Priority Mask */
+#define NVIC_PRI32_INTD_S 29
+#define NVIC_PRI32_INTC_S 21
+#define NVIC_PRI32_INTB_S 13
+#define NVIC_PRI32_INTA_S 5
+
+/* The following are defines for the bit fields in the NVIC_CPUID register. */
+#define NVIC_CPUID_IMP_M 0xFF000000 /* Implementer Code */
+#define NVIC_CPUID_IMP_ARM 0x41000000 /* ARM */
+#define NVIC_CPUID_VAR_M 0x00F00000 /* Variant Number */
+#define NVIC_CPUID_CON_M 0x000F0000 /* Constant */
+#define NVIC_CPUID_PARTNO_M 0x0000FFF0 /* Part Number */
+#define NVIC_CPUID_PARTNO_CM4 0x0000C240 /* Cortex-M4 processor */
+#define NVIC_CPUID_REV_M 0x0000000F /* Revision Number */
+
+/* The following are defines for the bit fields in the NVIC_INT_CTRL register. */
+#define NVIC_INT_CTRL_NMI_SET 0x80000000 /* NMI Set Pending */
+#define NVIC_INT_CTRL_PEND_SV 0x10000000 /* PendSV Set Pending */
+#define NVIC_INT_CTRL_UNPEND_SV 0x08000000 /* PendSV Clear Pending */
+#define NVIC_INT_CTRL_PENDSTSET 0x04000000 /* SysTick Set Pending */
+#define NVIC_INT_CTRL_PENDSTCLR 0x02000000 /* SysTick Clear Pending */
+#define NVIC_INT_CTRL_ISR_PRE 0x00800000 /* Debug Interrupt Handling */
+#define NVIC_INT_CTRL_ISR_PEND 0x00400000 /* Interrupt Pending */
+#define NVIC_INT_CTRL_VEC_PEN_M 0x000FF000 /* Interrupt Pending Vector Number */
+#define NVIC_INT_CTRL_VEC_PEN_NMI \
+ 0x00002000 /* NMI */
+#define NVIC_INT_CTRL_VEC_PEN_HARD \
+ 0x00003000 /* Hard fault */
+#define NVIC_INT_CTRL_VEC_PEN_MEM \
+ 0x00004000 /* Memory management fault */
+#define NVIC_INT_CTRL_VEC_PEN_BUS \
+ 0x00005000 /* Bus fault */
+#define NVIC_INT_CTRL_VEC_PEN_USG \
+ 0x00006000 /* Usage fault */
+#define NVIC_INT_CTRL_VEC_PEN_SVC \
+ 0x0000B000 /* SVCall */
+#define NVIC_INT_CTRL_VEC_PEN_PNDSV \
+ 0x0000E000 /* PendSV */
+#define NVIC_INT_CTRL_VEC_PEN_TICK \
+ 0x0000F000 /* SysTick */
+#define NVIC_INT_CTRL_RET_BASE 0x00000800 /* Return to Base */
+#define NVIC_INT_CTRL_VEC_ACT_M 0x000000FF /* Interrupt Pending Vector Number */
+#define NVIC_INT_CTRL_VEC_ACT_S 0
+
+/* The following are defines for the bit fields in the NVIC_VTABLE register. */
+#define NVIC_VTABLE_BASE 0x20000000 /* Vector Table Base */
+#define NVIC_VTABLE_OFFSET_M 0x1FFFFC00 /* Vector Table Offset */
+#define NVIC_VTABLE_OFFSET_S 10
+
+/* The following are defines for the bit fields in the NVIC_APINT register. */
+#define NVIC_APINT_VECTKEY_M 0xFFFF0000 /* Register Key */
+#define NVIC_APINT_VECTKEY 0x05FA0000 /* Vector key */
+#define NVIC_APINT_ENDIANESS 0x00008000 /* Data Endianess */
+#define NVIC_APINT_PRIGROUP_M 0x00000700 /* Interrupt Priority Grouping */
+#define NVIC_APINT_PRIGROUP_7_1 0x00000000 /* Priority group 7.1 split */
+#define NVIC_APINT_PRIGROUP_6_2 0x00000100 /* Priority group 6.2 split */
+#define NVIC_APINT_PRIGROUP_5_3 0x00000200 /* Priority group 5.3 split */
+#define NVIC_APINT_PRIGROUP_4_4 0x00000300 /* Priority group 4.4 split */
+#define NVIC_APINT_PRIGROUP_3_5 0x00000400 /* Priority group 3.5 split */
+#define NVIC_APINT_PRIGROUP_2_6 0x00000500 /* Priority group 2.6 split */
+#define NVIC_APINT_PRIGROUP_1_7 0x00000600 /* Priority group 1.7 split */
+#define NVIC_APINT_PRIGROUP_0_8 0x00000700 /* Priority group 0.8 split */
+#define NVIC_APINT_SYSRESETREQ 0x00000004 /* System Reset Request */
+#define NVIC_APINT_VECT_CLR_ACT 0x00000002 /* Clear Active NMI / Fault */
+#define NVIC_APINT_VECT_RESET 0x00000001 /* System Reset */
+
+/* The following are defines for the bit fields in the NVIC_SYS_CTRL register. */
+#define NVIC_SYS_CTRL_SEVONPEND 0x00000010 /* Wake Up on Pending */
+#define NVIC_SYS_CTRL_SLEEPDEEP 0x00000004 /* Deep Sleep Enable */
+#define NVIC_SYS_CTRL_SLEEPEXIT 0x00000002 /* Sleep on ISR Exit */
+
+/* The following are defines for the bit fields in the NVIC_CFG_CTRL register. */
+#define NVIC_CFG_CTRL_STKALIGN 0x00000200 /* Stack Alignment on Exception */
+ /* Entry */
+#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 /* Ignore Bus Fault in NMI and */
+ /* Fault */
+#define NVIC_CFG_CTRL_DIV0 0x00000010 /* Trap on Divide by 0 */
+#define NVIC_CFG_CTRL_UNALIGNED 0x00000008 /* Trap on Unaligned Access */
+#define NVIC_CFG_CTRL_MAIN_PEND 0x00000002 /* Allow Main Interrupt Trigger */
+#define NVIC_CFG_CTRL_BASE_THR 0x00000001 /* Thread State Control */
+
+/* The following are defines for the bit fields in the NVIC_SYS_PRI1 register. */
+#define NVIC_SYS_PRI1_USAGE_M 0x00E00000 /* Usage Fault Priority */
+#define NVIC_SYS_PRI1_BUS_M 0x0000E000 /* Bus Fault Priority */
+#define NVIC_SYS_PRI1_MEM_M 0x000000E0 /* Memory Management Fault Priority */
+#define NVIC_SYS_PRI1_USAGE_S 21
+#define NVIC_SYS_PRI1_BUS_S 13
+#define NVIC_SYS_PRI1_MEM_S 5
+
+/* The following are defines for the bit fields in the NVIC_SYS_PRI2 register. */
+#define NVIC_SYS_PRI2_SVC_M 0xE0000000 /* SVCall Priority */
+#define NVIC_SYS_PRI2_SVC_S 29
+
+/* The following are defines for the bit fields in the NVIC_SYS_PRI3 register. */
+#define NVIC_SYS_PRI3_TICK_M 0xE0000000 /* SysTick Exception Priority */
+#define NVIC_SYS_PRI3_PENDSV_M 0x00E00000 /* PendSV Priority */
+#define NVIC_SYS_PRI3_DEBUG_M 0x000000E0 /* Debug Priority */
+#define NVIC_SYS_PRI3_TICK_S 29
+#define NVIC_SYS_PRI3_PENDSV_S 21
+#define NVIC_SYS_PRI3_DEBUG_S 5
+
+/* The following are defines for the bit fields in the NVIC_SYS_HND_CTRL
+ * register. */
+#define NVIC_SYS_HND_CTRL_USAGE 0x00040000 /* Usage Fault Enable */
+#define NVIC_SYS_HND_CTRL_BUS 0x00020000 /* Bus Fault Enable */
+#define NVIC_SYS_HND_CTRL_MEM 0x00010000 /* Memory Management Fault Enable */
+#define NVIC_SYS_HND_CTRL_SVC 0x00008000 /* SVC Call Pending */
+#define NVIC_SYS_HND_CTRL_BUSP 0x00004000 /* Bus Fault Pending */
+#define NVIC_SYS_HND_CTRL_MEMP 0x00002000 /* Memory Management Fault Pending */
+#define NVIC_SYS_HND_CTRL_USAGEP \
+ 0x00001000 /* Usage Fault Pending */
+#define NVIC_SYS_HND_CTRL_TICK 0x00000800 /* SysTick Exception Active */
+#define NVIC_SYS_HND_CTRL_PNDSV 0x00000400 /* PendSV Exception Active */
+#define NVIC_SYS_HND_CTRL_MON 0x00000100 /* Debug Monitor Active */
+#define NVIC_SYS_HND_CTRL_SVCA 0x00000080 /* SVC Call Active */
+#define NVIC_SYS_HND_CTRL_USGA 0x00000008 /* Usage Fault Active */
+#define NVIC_SYS_HND_CTRL_BUSA 0x00000002 /* Bus Fault Active */
+#define NVIC_SYS_HND_CTRL_MEMA 0x00000001 /* Memory Management Fault Active */
+
+/* The following are defines for the bit fields in the NVIC_FAULT_STAT
+ * register. */
+#define NVIC_FAULT_STAT_DIV0 0x02000000 /* Divide-by-Zero Usage Fault */
+#define NVIC_FAULT_STAT_UNALIGN 0x01000000 /* Unaligned Access Usage Fault */
+#define NVIC_FAULT_STAT_NOCP 0x00080000 /* No Coprocessor Usage Fault */
+#define NVIC_FAULT_STAT_INVPC 0x00040000 /* Invalid PC Load Usage Fault */
+#define NVIC_FAULT_STAT_INVSTAT 0x00020000 /* Invalid State Usage Fault */
+#define NVIC_FAULT_STAT_UNDEF 0x00010000 /* Undefined Instruction Usage */
+ /* Fault */
+#define NVIC_FAULT_STAT_BFARV 0x00008000 /* Bus Fault Address Register Valid */
+#define NVIC_FAULT_STAT_BLSPERR 0x00002000 /* Bus Fault on Floating-Point Lazy */
+ /* State Preservation */
+#define NVIC_FAULT_STAT_BSTKE 0x00001000 /* Stack Bus Fault */
+#define NVIC_FAULT_STAT_BUSTKE 0x00000800 /* Unstack Bus Fault */
+#define NVIC_FAULT_STAT_IMPRE 0x00000400 /* Imprecise Data Bus Error */
+#define NVIC_FAULT_STAT_PRECISE 0x00000200 /* Precise Data Bus Error */
+#define NVIC_FAULT_STAT_IBUS 0x00000100 /* Instruction Bus Error */
+#define NVIC_FAULT_STAT_MMARV 0x00000080 /* Memory Management Fault Address */
+ /* Register Valid */
+#define NVIC_FAULT_STAT_MLSPERR 0x00000020 /* Memory Management Fault on */
+ /* Floating-Point Lazy State */
+ /* Preservation */
+#define NVIC_FAULT_STAT_MSTKE 0x00000010 /* Stack Access Violation */
+#define NVIC_FAULT_STAT_MUSTKE 0x00000008 /* Unstack Access Violation */
+#define NVIC_FAULT_STAT_DERR 0x00000002 /* Data Access Violation */
+#define NVIC_FAULT_STAT_IERR 0x00000001 /* Instruction Access Violation */
+
+/* The following are defines for the bit fields in the NVIC_HFAULT_STAT
+ * register. */
+#define NVIC_HFAULT_STAT_DBG 0x80000000 /* Debug Event */
+#define NVIC_HFAULT_STAT_FORCED 0x40000000 /* Forced Hard Fault */
+#define NVIC_HFAULT_STAT_VECT 0x00000002 /* Vector Table Read Fault */
+
+/* The following are defines for the bit fields in the NVIC_DEBUG_STAT
+ * register. */
+#define NVIC_DEBUG_STAT_EXTRNL 0x00000010 /* EDBGRQ asserted */
+#define NVIC_DEBUG_STAT_VCATCH 0x00000008 /* Vector catch */
+#define NVIC_DEBUG_STAT_DWTTRAP 0x00000004 /* DWT match */
+#define NVIC_DEBUG_STAT_BKPT 0x00000002 /* Breakpoint instruction */
+#define NVIC_DEBUG_STAT_HALTED 0x00000001 /* Halt request */
+
+/* The following are defines for the bit fields in the NVIC_MM_ADDR register. */
+#define NVIC_MM_ADDR_M 0xFFFFFFFF /* Fault Address */
+#define NVIC_MM_ADDR_S 0
+
+/* The following are defines for the bit fields in the NVIC_FAULT_ADDR
+ * register. */
+#define NVIC_FAULT_ADDR_M 0xFFFFFFFF /* Fault Address */
+#define NVIC_FAULT_ADDR_S 0
+
+/* The following are defines for the bit fields in the NVIC_CPAC register. */
+#define NVIC_CPAC_CP11_M 0x00C00000 /* CP11 Coprocessor Access */
+ /* Privilege */
+#define NVIC_CPAC_CP11_DIS 0x00000000 /* Access Denied */
+#define NVIC_CPAC_CP11_PRIV 0x00400000 /* Privileged Access Only */
+#define NVIC_CPAC_CP11_FULL 0x00C00000 /* Full Access */
+#define NVIC_CPAC_CP10_M 0x00300000 /* CP10 Coprocessor Access */
+ /* Privilege */
+#define NVIC_CPAC_CP10_DIS 0x00000000 /* Access Denied */
+#define NVIC_CPAC_CP10_PRIV 0x00100000 /* Privileged Access Only */
+#define NVIC_CPAC_CP10_FULL 0x00300000 /* Full Access */
+
+/* The following are defines for the bit fields in the NVIC_MPU_TYPE register. */
+#define NVIC_MPU_TYPE_IREGION_M 0x00FF0000 /* Number of I Regions */
+#define NVIC_MPU_TYPE_DREGION_M 0x0000FF00 /* Number of D Regions */
+#define NVIC_MPU_TYPE_SEPARATE 0x00000001 /* Separate or Unified MPU */
+#define NVIC_MPU_TYPE_IREGION_S 16
+#define NVIC_MPU_TYPE_DREGION_S 8
+
+/* The following are defines for the bit fields in the NVIC_MPU_CTRL register. */
+#define NVIC_MPU_CTRL_PRIVDEFEN 0x00000004 /* MPU Default Region */
+#define NVIC_MPU_CTRL_HFNMIENA 0x00000002 /* MPU Enabled During Faults */
+#define NVIC_MPU_CTRL_ENABLE 0x00000001 /* MPU Enable */
+
+/* The following are defines for the bit fields in the NVIC_MPU_NUMBER
+ * register. */
+#define NVIC_MPU_NUMBER_M 0x00000007 /* MPU Region to Access */
+#define NVIC_MPU_NUMBER_S 0
+
+/* The following are defines for the bit fields in the NVIC_MPU_BASE register. */
+#define NVIC_MPU_BASE_ADDR_M 0xFFFFFFE0 /* Base Address Mask */
+#define NVIC_MPU_BASE_VALID 0x00000010 /* Region Number Valid */
+#define NVIC_MPU_BASE_REGION_M 0x00000007 /* Region Number */
+#define NVIC_MPU_BASE_ADDR_S 5
+#define NVIC_MPU_BASE_REGION_S 0
+
+/* The following are defines for the bit fields in the NVIC_MPU_ATTR register. */
+#define NVIC_MPU_ATTR_XN 0x10000000 /* Instruction Access Disable */
+#define NVIC_MPU_ATTR_AP_M 0x07000000 /* Access Privilege */
+#define NVIC_MPU_ATTR_TEX_M 0x00380000 /* Type Extension Mask */
+#define NVIC_MPU_ATTR_SHAREABLE 0x00040000 /* Shareable */
+#define NVIC_MPU_ATTR_CACHEABLE 0x00020000 /* Cacheable */
+#define NVIC_MPU_ATTR_BUFFRABLE 0x00010000 /* Bufferable */
+#define NVIC_MPU_ATTR_SRD_M 0x0000FF00 /* Subregion Disable Bits */
+#define NVIC_MPU_ATTR_SIZE_M 0x0000003E /* Region Size Mask */
+#define NVIC_MPU_ATTR_ENABLE 0x00000001 /* Region Enable */
+
+/* The following are defines for the bit fields in the NVIC_MPU_BASE1 register. */
+#define NVIC_MPU_BASE1_ADDR_M 0xFFFFFFE0 /* Base Address Mask */
+#define NVIC_MPU_BASE1_VALID 0x00000010 /* Region Number Valid */
+#define NVIC_MPU_BASE1_REGION_M 0x00000007 /* Region Number */
+#define NVIC_MPU_BASE1_ADDR_S 5
+#define NVIC_MPU_BASE1_REGION_S 0
+
+/* The following are defines for the bit fields in the NVIC_MPU_ATTR1 register. */
+#define NVIC_MPU_ATTR1_XN 0x10000000 /* Instruction Access Disable */
+#define NVIC_MPU_ATTR1_AP_M 0x07000000 /* Access Privilege */
+#define NVIC_MPU_ATTR1_TEX_M 0x00380000 /* Type Extension Mask */
+#define NVIC_MPU_ATTR1_SHAREABLE \
+ 0x00040000 /* Shareable */
+#define NVIC_MPU_ATTR1_CACHEABLE \
+ 0x00020000 /* Cacheable */
+#define NVIC_MPU_ATTR1_BUFFRABLE \
+ 0x00010000 /* Bufferable */
+#define NVIC_MPU_ATTR1_SRD_M 0x0000FF00 /* Subregion Disable Bits */
+#define NVIC_MPU_ATTR1_SIZE_M 0x0000003E /* Region Size Mask */
+#define NVIC_MPU_ATTR1_ENABLE 0x00000001 /* Region Enable */
+
+/* The following are defines for the bit fields in the NVIC_MPU_BASE2 register. */
+#define NVIC_MPU_BASE2_ADDR_M 0xFFFFFFE0 /* Base Address Mask */
+#define NVIC_MPU_BASE2_VALID 0x00000010 /* Region Number Valid */
+#define NVIC_MPU_BASE2_REGION_M 0x00000007 /* Region Number */
+#define NVIC_MPU_BASE2_ADDR_S 5
+#define NVIC_MPU_BASE2_REGION_S 0
+
+/* The following are defines for the bit fields in the NVIC_MPU_ATTR2 register. */
+#define NVIC_MPU_ATTR2_XN 0x10000000 /* Instruction Access Disable */
+#define NVIC_MPU_ATTR2_AP_M 0x07000000 /* Access Privilege */
+#define NVIC_MPU_ATTR2_TEX_M 0x00380000 /* Type Extension Mask */
+#define NVIC_MPU_ATTR2_SHAREABLE \
+ 0x00040000 /* Shareable */
+#define NVIC_MPU_ATTR2_CACHEABLE \
+ 0x00020000 /* Cacheable */
+#define NVIC_MPU_ATTR2_BUFFRABLE \
+ 0x00010000 /* Bufferable */
+#define NVIC_MPU_ATTR2_SRD_M 0x0000FF00 /* Subregion Disable Bits */
+#define NVIC_MPU_ATTR2_SIZE_M 0x0000003E /* Region Size Mask */
+#define NVIC_MPU_ATTR2_ENABLE 0x00000001 /* Region Enable */
+
+/* The following are defines for the bit fields in the NVIC_MPU_BASE3 register. */
+#define NVIC_MPU_BASE3_ADDR_M 0xFFFFFFE0 /* Base Address Mask */
+#define NVIC_MPU_BASE3_VALID 0x00000010 /* Region Number Valid */
+#define NVIC_MPU_BASE3_REGION_M 0x00000007 /* Region Number */
+#define NVIC_MPU_BASE3_ADDR_S 5
+#define NVIC_MPU_BASE3_REGION_S 0
+
+/* The following are defines for the bit fields in the NVIC_MPU_ATTR3 register. */
+#define NVIC_MPU_ATTR3_XN 0x10000000 /* Instruction Access Disable */
+#define NVIC_MPU_ATTR3_AP_M 0x07000000 /* Access Privilege */
+#define NVIC_MPU_ATTR3_TEX_M 0x00380000 /* Type Extension Mask */
+#define NVIC_MPU_ATTR3_SHAREABLE \
+ 0x00040000 /* Shareable */
+#define NVIC_MPU_ATTR3_CACHEABLE \
+ 0x00020000 /* Cacheable */
+#define NVIC_MPU_ATTR3_BUFFRABLE \
+ 0x00010000 /* Bufferable */
+#define NVIC_MPU_ATTR3_SRD_M 0x0000FF00 /* Subregion Disable Bits */
+#define NVIC_MPU_ATTR3_SIZE_M 0x0000003E /* Region Size Mask */
+#define NVIC_MPU_ATTR3_ENABLE 0x00000001 /* Region Enable */
+
+/* The following are defines for the bit fields in the NVIC_DBG_CTRL register. */
+#define NVIC_DBG_CTRL_DBGKEY_M 0xFFFF0000 /* Debug key mask */
+#define NVIC_DBG_CTRL_DBGKEY 0xA05F0000 /* Debug key */
+#define NVIC_DBG_CTRL_S_RESET_ST \
+ 0x02000000 /* Core has reset since last read */
+#define NVIC_DBG_CTRL_S_RETIRE_ST \
+ 0x01000000 /* Core has executed insruction */
+ /* since last read */
+#define NVIC_DBG_CTRL_S_LOCKUP 0x00080000 /* Core is locked up */
+#define NVIC_DBG_CTRL_S_SLEEP 0x00040000 /* Core is sleeping */
+#define NVIC_DBG_CTRL_S_HALT 0x00020000 /* Core status on halt */
+#define NVIC_DBG_CTRL_S_REGRDY 0x00010000 /* Register read/write available */
+#define NVIC_DBG_CTRL_C_SNAPSTALL \
+ 0x00000020 /* Breaks a stalled load/store */
+#define NVIC_DBG_CTRL_C_MASKINT 0x00000008 /* Mask interrupts when stepping */
+#define NVIC_DBG_CTRL_C_STEP 0x00000004 /* Step the core */
+#define NVIC_DBG_CTRL_C_HALT 0x00000002 /* Halt the core */
+#define NVIC_DBG_CTRL_C_DEBUGEN 0x00000001 /* Enable debug */
+
+/* The following are defines for the bit fields in the NVIC_DBG_XFER register. */
+#define NVIC_DBG_XFER_REG_WNR 0x00010000 /* Write or not read */
+#define NVIC_DBG_XFER_REG_SEL_M 0x0000001F /* Register */
+#define NVIC_DBG_XFER_REG_R0 0x00000000 /* Register R0 */
+#define NVIC_DBG_XFER_REG_R1 0x00000001 /* Register R1 */
+#define NVIC_DBG_XFER_REG_R2 0x00000002 /* Register R2 */
+#define NVIC_DBG_XFER_REG_R3 0x00000003 /* Register R3 */
+#define NVIC_DBG_XFER_REG_R4 0x00000004 /* Register R4 */
+#define NVIC_DBG_XFER_REG_R5 0x00000005 /* Register R5 */
+#define NVIC_DBG_XFER_REG_R6 0x00000006 /* Register R6 */
+#define NVIC_DBG_XFER_REG_R7 0x00000007 /* Register R7 */
+#define NVIC_DBG_XFER_REG_R8 0x00000008 /* Register R8 */
+#define NVIC_DBG_XFER_REG_R9 0x00000009 /* Register R9 */
+#define NVIC_DBG_XFER_REG_R10 0x0000000A /* Register R10 */
+#define NVIC_DBG_XFER_REG_R11 0x0000000B /* Register R11 */
+#define NVIC_DBG_XFER_REG_R12 0x0000000C /* Register R12 */
+#define NVIC_DBG_XFER_REG_R13 0x0000000D /* Register R13 */
+#define NVIC_DBG_XFER_REG_R14 0x0000000E /* Register R14 */
+#define NVIC_DBG_XFER_REG_R15 0x0000000F /* Register R15 */
+#define NVIC_DBG_XFER_REG_FLAGS 0x00000010 /* xPSR/Flags register */
+#define NVIC_DBG_XFER_REG_MSP 0x00000011 /* Main SP */
+#define NVIC_DBG_XFER_REG_PSP 0x00000012 /* Process SP */
+#define NVIC_DBG_XFER_REG_DSP 0x00000013 /* Deep SP */
+#define NVIC_DBG_XFER_REG_CFBP 0x00000014 /* Control/Fault/BasePri/PriMask */
+
+/* The following are defines for the bit fields in the NVIC_DBG_DATA register. */
+#define NVIC_DBG_DATA_M 0xFFFFFFFF /* Data temporary cache */
+#define NVIC_DBG_DATA_S 0
+
+/* The following are defines for the bit fields in the NVIC_DBG_INT register. */
+#define NVIC_DBG_INT_HARDERR 0x00000400 /* Debug trap on hard fault */
+#define NVIC_DBG_INT_INTERR 0x00000200 /* Debug trap on interrupt errors */
+#define NVIC_DBG_INT_BUSERR 0x00000100 /* Debug trap on bus error */
+#define NVIC_DBG_INT_STATERR 0x00000080 /* Debug trap on usage fault state */
+#define NVIC_DBG_INT_CHKERR 0x00000040 /* Debug trap on usage fault check */
+#define NVIC_DBG_INT_NOCPERR 0x00000020 /* Debug trap on coprocessor error */
+#define NVIC_DBG_INT_MMERR 0x00000010 /* Debug trap on mem manage fault */
+#define NVIC_DBG_INT_RESET 0x00000008 /* Core reset status */
+#define NVIC_DBG_INT_RSTPENDCLR 0x00000004 /* Clear pending core reset */
+#define NVIC_DBG_INT_RSTPENDING 0x00000002 /* Core reset is pending */
+#define NVIC_DBG_INT_RSTVCATCH 0x00000001 /* Reset vector catch */
+
+/* The following are defines for the bit fields in the NVIC_SW_TRIG register. */
+#define NVIC_SW_TRIG_INTID_M 0x000000FF /* Interrupt ID */
+#define NVIC_SW_TRIG_INTID_S 0
+
+/* The following are defines for the bit fields in the NVIC_FPCC register. */
+#define NVIC_FPCC_ASPEN 0x80000000 /* Automatic State Preservation */
+ /* Enable */
+#define NVIC_FPCC_LSPEN 0x40000000 /* Lazy State Preservation Enable */
+#define NVIC_FPCC_MONRDY 0x00000100 /* Monitor Ready */
+#define NVIC_FPCC_BFRDY 0x00000040 /* Bus Fault Ready */
+#define NVIC_FPCC_MMRDY 0x00000020 /* Memory Management Fault Ready */
+#define NVIC_FPCC_HFRDY 0x00000010 /* Hard Fault Ready */
+#define NVIC_FPCC_THREAD 0x00000008 /* Thread Mode */
+#define NVIC_FPCC_USER 0x00000002 /* User Privilege Level */
+#define NVIC_FPCC_LSPACT 0x00000001 /* Lazy State Preservation Active */
+
+/* The following are defines for the bit fields in the NVIC_FPCA register. */
+#define NVIC_FPCA_ADDRESS_M 0xFFFFFFF8 /* Address */
+#define NVIC_FPCA_ADDRESS_S 3
+
+/* The following are defines for the bit fields in the NVIC_FPDSC register. */
+#define NVIC_FPDSC_AHP 0x04000000 /* AHP Bit Default */
+#define NVIC_FPDSC_DN 0x02000000 /* DN Bit Default */
+#define NVIC_FPDSC_FZ 0x01000000 /* FZ Bit Default */
+#define NVIC_FPDSC_RMODE_M 0x00C00000 /* RMODE Bit Default */
+#define NVIC_FPDSC_RMODE_RN 0x00000000 /* Round to Nearest (RN) mode */
+#define NVIC_FPDSC_RMODE_RP 0x00400000 /* Round towards Plus Infinity (RP) */
+ /* mode */
+#define NVIC_FPDSC_RMODE_RM 0x00800000 /* Round towards Minus Infinity */
+ /* (RM) mode */
+#define NVIC_FPDSC_RMODE_RZ 0x00C00000 /* Round towards Zero (RZ) mode */
+
+/* Exceptions */
+/* Reset */
+#define EE_CORTEX_MX_RESET_EXC_NUM 0x00000001
+/* NMI */
+#define EE_CORTEX_MX_NMI_EXC_NUM 0x00000002
+/* hard fault */
+#define EE_CORTEX_MX_HARD_FAULT_EXC_NUM 0x00000003
+/* MPU fault */
+#define EE_CORTEX_MX_MPU_FAULT_EXC_NUM 0x00000004
+/* bus fault */
+#define EE_CORTEX_MX_BUS_FAULT_EXC_NUM 0x00000005
+/* usage fault */
+#define EE_CORTEX_MX_USAGE_FAULT_EXC_NUM 0x00000006
+/* SVCall */
+#define EE_CORTEX_MX_SVCALL_EXC_NUM 0x0000000B
+/* PendSV */
+#define EE_CORTEX_MX_PENDSV_EXC_NUM 0x0000000E
+/* SysTick */
+#define EE_CORTEX_MX_SYSTICK_EXC_NUM 0x0000000F
+/* Debug monitor */
+#define EE_CORTEX_MX_DEBUG_MONITOR_EXC_NUM 0x0000000C
+
+/* Interrupts */
+#define EE_CORTEX_MX_INT_00_NUM 0x00000000U
+#define EE_CORTEX_MX_INT_01_NUM 0x00000001U
+#define EE_CORTEX_MX_INT_02_NUM 0x00000002U
+#define EE_CORTEX_MX_INT_03_NUM 0x00000003U
+#define EE_CORTEX_MX_INT_04_NUM 0x00000004U
+#define EE_CORTEX_MX_INT_05_NUM 0x00000005U
+#define EE_CORTEX_MX_INT_06_NUM 0x00000006U
+#define EE_CORTEX_MX_INT_07_NUM 0x00000007U
+#define EE_CORTEX_MX_INT_08_NUM 0x00000008U
+#define EE_CORTEX_MX_INT_09_NUM 0x00000009U
+#define EE_CORTEX_MX_INT_0A_NUM 0x0000000AU
+#define EE_CORTEX_MX_INT_0B_NUM 0x0000000BU
+#define EE_CORTEX_MX_INT_0C_NUM 0x0000000CU
+#define EE_CORTEX_MX_INT_0D_NUM 0x0000000DU
+#define EE_CORTEX_MX_INT_0E_NUM 0x0000000EU
+#define EE_CORTEX_MX_INT_0F_NUM 0x0000000FU
+#define EE_CORTEX_MX_INT_10_NUM 0x00000010U
+#define EE_CORTEX_MX_INT_11_NUM 0x00000011U
+#define EE_CORTEX_MX_INT_12_NUM 0x00000012U
+#define EE_CORTEX_MX_INT_13_NUM 0x00000013U
+#define EE_CORTEX_MX_INT_14_NUM 0x00000014U
+#define EE_CORTEX_MX_INT_15_NUM 0x00000015U
+#define EE_CORTEX_MX_INT_16_NUM 0x00000016U
+#define EE_CORTEX_MX_INT_17_NUM 0x00000017U
+#define EE_CORTEX_MX_INT_18_NUM 0x00000018U
+#define EE_CORTEX_MX_INT_19_NUM 0x00000019U
+#define EE_CORTEX_MX_INT_1A_NUM 0x0000001AU
+#define EE_CORTEX_MX_INT_1B_NUM 0x0000001BU
+#define EE_CORTEX_MX_INT_1C_NUM 0x0000001CU
+#define EE_CORTEX_MX_INT_1D_NUM 0x0000001DU
+#define EE_CORTEX_MX_INT_1E_NUM 0x0000001EU
+#define EE_CORTEX_MX_INT_1F_NUM 0x0000001FU
+#define EE_CORTEX_MX_INT_20_NUM 0x00000020U
+#define EE_CORTEX_MX_INT_21_NUM 0x00000021U
+#define EE_CORTEX_MX_INT_22_NUM 0x00000022U
+#define EE_CORTEX_MX_INT_23_NUM 0x00000023U
+#define EE_CORTEX_MX_INT_24_NUM 0x00000024U
+#define EE_CORTEX_MX_INT_25_NUM 0x00000025U
+#define EE_CORTEX_MX_INT_26_NUM 0x00000026U
+#define EE_CORTEX_MX_INT_27_NUM 0x00000027U
+#define EE_CORTEX_MX_INT_28_NUM 0x00000028U
+#define EE_CORTEX_MX_INT_29_NUM 0x00000029U
+#define EE_CORTEX_MX_INT_2A_NUM 0x0000002AU
+#define EE_CORTEX_MX_INT_2B_NUM 0x0000002BU
+#define EE_CORTEX_MX_INT_2C_NUM 0x0000002CU
+#define EE_CORTEX_MX_INT_2D_NUM 0x0000002DU
+#define EE_CORTEX_MX_INT_2E_NUM 0x0000002EU
+#define EE_CORTEX_MX_INT_2F_NUM 0x0000002FU
+#define EE_CORTEX_MX_INT_30_NUM 0x00000030U
+#define EE_CORTEX_MX_INT_31_NUM 0x00000031U
+#define EE_CORTEX_MX_INT_32_NUM 0x00000032U
+#define EE_CORTEX_MX_INT_33_NUM 0x00000033U
+#define EE_CORTEX_MX_INT_34_NUM 0x00000034U
+#define EE_CORTEX_MX_INT_35_NUM 0x00000035U
+#define EE_CORTEX_MX_INT_36_NUM 0x00000036U
+#define EE_CORTEX_MX_INT_37_NUM 0x00000037U
+#define EE_CORTEX_MX_INT_38_NUM 0x00000038U
+#define EE_CORTEX_MX_INT_39_NUM 0x00000039U
+#define EE_CORTEX_MX_INT_3A_NUM 0x0000003AU
+#define EE_CORTEX_MX_INT_3B_NUM 0x0000003BU
+#define EE_CORTEX_MX_INT_3C_NUM 0x0000003CU
+#define EE_CORTEX_MX_INT_3D_NUM 0x0000003DU
+#define EE_CORTEX_MX_INT_3E_NUM 0x0000003EU
+#define EE_CORTEX_MX_INT_3F_NUM 0x0000003FU
+#define EE_CORTEX_MX_INT_40_NUM 0x00000040U
+#define EE_CORTEX_MX_INT_41_NUM 0x00000041U
+#define EE_CORTEX_MX_INT_42_NUM 0x00000042U
+#define EE_CORTEX_MX_INT_43_NUM 0x00000043U
+#define EE_CORTEX_MX_INT_44_NUM 0x00000044U
+#define EE_CORTEX_MX_INT_45_NUM 0x00000045U
+#define EE_CORTEX_MX_INT_46_NUM 0x00000046U
+#define EE_CORTEX_MX_INT_47_NUM 0x00000047U
+#define EE_CORTEX_MX_INT_48_NUM 0x00000048U
+#define EE_CORTEX_MX_INT_49_NUM 0x00000049U
+#define EE_CORTEX_MX_INT_4A_NUM 0x0000004AU
+#define EE_CORTEX_MX_INT_4B_NUM 0x0000004BU
+#define EE_CORTEX_MX_INT_4C_NUM 0x0000004CU
+#define EE_CORTEX_MX_INT_4D_NUM 0x0000004DU
+#define EE_CORTEX_MX_INT_4E_NUM 0x0000004EU
+#define EE_CORTEX_MX_INT_4F_NUM 0x0000004FU
+#define EE_CORTEX_MX_INT_50_NUM 0x00000050U
+#define EE_CORTEX_MX_INT_51_NUM 0x00000051U
+#define EE_CORTEX_MX_INT_52_NUM 0x00000052U
+#define EE_CORTEX_MX_INT_53_NUM 0x00000053U
+#define EE_CORTEX_MX_INT_54_NUM 0x00000054U
+#define EE_CORTEX_MX_INT_55_NUM 0x00000055U
+#define EE_CORTEX_MX_INT_56_NUM 0x00000056U
+#define EE_CORTEX_MX_INT_57_NUM 0x00000057U
+#define EE_CORTEX_MX_INT_58_NUM 0x00000058U
+#define EE_CORTEX_MX_INT_59_NUM 0x00000059U
+#define EE_CORTEX_MX_INT_5A_NUM 0x0000005AU
+#define EE_CORTEX_MX_INT_5B_NUM 0x0000005BU
+#define EE_CORTEX_MX_INT_5C_NUM 0x0000005CU
+#define EE_CORTEX_MX_INT_5D_NUM 0x0000005DU
+#define EE_CORTEX_MX_INT_5E_NUM 0x0000005EU
+#define EE_CORTEX_MX_INT_5F_NUM 0x0000005FU
+#define EE_CORTEX_MX_INT_60_NUM 0x00000060U
+#define EE_CORTEX_MX_INT_61_NUM 0x00000061U
+#define EE_CORTEX_MX_INT_62_NUM 0x00000062U
+#define EE_CORTEX_MX_INT_63_NUM 0x00000063U
+#define EE_CORTEX_MX_INT_64_NUM 0x00000064U
+#define EE_CORTEX_MX_INT_65_NUM 0x00000065U
+#define EE_CORTEX_MX_INT_66_NUM 0x00000066U
+#define EE_CORTEX_MX_INT_67_NUM 0x00000067U
+#define EE_CORTEX_MX_INT_68_NUM 0x00000068U
+#define EE_CORTEX_MX_INT_69_NUM 0x00000069U
+#define EE_CORTEX_MX_INT_6A_NUM 0x0000006AU
+#define EE_CORTEX_MX_INT_6B_NUM 0x0000006BU
+#define EE_CORTEX_MX_INT_6C_NUM 0x0000006CU
+#define EE_CORTEX_MX_INT_6D_NUM 0x0000006DU
+#define EE_CORTEX_MX_INT_6E_NUM 0x0000006EU
+#define EE_CORTEX_MX_INT_6F_NUM 0x0000006FU
+#define EE_CORTEX_MX_INT_70_NUM 0x00000070U
+#define EE_CORTEX_MX_INT_71_NUM 0x00000071U
+#define EE_CORTEX_MX_INT_72_NUM 0x00000072U
+#define EE_CORTEX_MX_INT_73_NUM 0x00000073U
+#define EE_CORTEX_MX_INT_74_NUM 0x00000074U
+#define EE_CORTEX_MX_INT_75_NUM 0x00000075U
+#define EE_CORTEX_MX_INT_76_NUM 0x00000076U
+#define EE_CORTEX_MX_INT_77_NUM 0x00000077U
+#define EE_CORTEX_MX_INT_78_NUM 0x00000078U
+#define EE_CORTEX_MX_INT_79_NUM 0x00000079U
+#define EE_CORTEX_MX_INT_7A_NUM 0x0000007AU
+#define EE_CORTEX_MX_INT_7B_NUM 0x0000007BU
+#define EE_CORTEX_MX_INT_7C_NUM 0x0000007CU
+#define EE_CORTEX_MX_INT_7D_NUM 0x0000007DU
+#define EE_CORTEX_MX_INT_7E_NUM 0x0000007EU
+#define EE_CORTEX_MX_INT_7F_NUM 0x0000007FU
+#define EE_CORTEX_MX_INT_80_NUM 0x00000080U
+#define EE_CORTEX_MX_INT_81_NUM 0x00000081U
+#define EE_CORTEX_MX_INT_82_NUM 0x00000082U
+#define EE_CORTEX_MX_INT_83_NUM 0x00000083U
+#define EE_CORTEX_MX_INT_84_NUM 0x00000084U
+#define EE_CORTEX_MX_INT_85_NUM 0x00000085U
+#define EE_CORTEX_MX_INT_86_NUM 0x00000086U
+#define EE_CORTEX_MX_INT_87_NUM 0x00000087U
+#define EE_CORTEX_MX_INT_88_NUM 0x00000088U
+#define EE_CORTEX_MX_INT_89_NUM 0x00000089U
+#define EE_CORTEX_MX_INT_8A_NUM 0x0000008AU
+#define EE_CORTEX_MX_INT_8B_NUM 0x0000008BU
+#define EE_CORTEX_MX_INT_8C_NUM 0x0000008CU
+#define EE_CORTEX_MX_INT_8D_NUM 0x0000008DU
+#define EE_CORTEX_MX_INT_8E_NUM 0x0000008EU
+#define EE_CORTEX_MX_INT_8F_NUM 0x0000008FU
+
+/* Register Shift-Bits Number */
+#define NVIC_REG_S 2
+
+/* NVIC Interrupt Registers Base Address */
+#define NVIC_INT_REG_B (EE_UREG)0xE000E100
+
+/* NVIC Interrupt Register Mask */
+#define NVIC_INT_REG_M (EE_UREG)0x0000001F
+
+/* NVIC Interrupt Register Shift-Bits Number */
+#define NVIC_INT_REG_S (EE_UREG)0x00000005
+
+/* NVIC Interrupt Register Number */
+#define NVIC_INT_REG_N(_int) \
+ (((EE_UREG)_int >> NVIC_INT_REG_S) << NVIC_REG_S)
+
+/* NVIC Interrupt Register */
+#define NVIC_INT_REG(_int, _base) EE_HWREG(_base + NVIC_INT_REG_N(_int))
+
+/* NVIC Interrupt Mask */
+#define NVIC_INT_M(_int) \
+ ((EE_UREG)0x00000001 << ((EE_UREG)_int & NVIC_INT_REG_M))
+
+/* NVIC Interrupt Priority Registers Base Address */
+#define NVIC_INT_PRI_REG_B (EE_UREG)0xE000E400
+
+/* NVIC Interrupt Priority Register Mask */
+#define NVIC_INT_PRI_REG_M (EE_UREG)0x00000003
+
+/* NVIC Interrupt Priority Register Shift-Bits Number */
+#define NVIC_INT_PRI_REG_S (EE_UREG)0x00000002
+
+/* NVIC Interrupt Priority Register Number */
+#define NVIC_INT_PRI_REG_N(_int) \
+ (((EE_UREG)_int >> NVIC_INT_PRI_REG_S) << NVIC_REG_S)
+
+/* NVIC Interrupt Priority Register */
+#define NVIC_INT_PRI_REG(_int) \
+ EE_HWREG(NVIC_INT_PRI_REG_B + NVIC_INT_PRI_REG_N(_int))
+
+/* NVIC Interrupt Priority Mask */
+#define NVIC_INT_PRI_M(_int) ( \
+ (EE_UREG)0x000000E0 << ( \
+ ((EE_UREG)_int & NVIC_INT_PRI_REG_M) << NVIC_INT_PRI_REG_M \
+ ) \
+ )
+
+/* NVIC Interrupt Priority Shift-Bits Number */
+#define NVIC_INT_PRI_S (EE_UREG)0x00000005
+
+/* NVIC Interrupt Priority */
+#define NVIC_INT_PRI(_int, _pri) ( \
+ ((EE_UREG)_pri << NVIC_INT_PRI_S) << ( \
+ ((EE_UREG)_int & NVIC_INT_PRI_REG_M) << NVIC_INT_PRI_REG_M \
+ ) \
+ )
+
+/* NVIC Interrupt Set Pending Registers Base Address */
+#define NVIC_INT_SET_PENDING_REG_B (EE_UREG)0xE000E200
+
+/* NVIC Interrupt Clear Pending Registers Base Address */
+#define NVIC_INT_CLR_PENDING_REG_B (EE_UREG)0xE000E280
+
+/* NVIC Enable Interrupt */
+#define NVIC_INT_ENABLE(_int) ( \
+ NVIC_INT_REG(_int, NVIC_INT_REG_B) |= NVIC_INT_M(_int) \
+ )
+
+/* NVIC Disable Interrupt */
+#define NVIC_INT_DISABLE(_int) ( \
+ NVIC_INT_REG(_int, NVIC_INT_REG_B) &= ~NVIC_INT_M(_int))
+
+/* NVIC Clear Priority */
+#define NVIC_CLR_PRI(_int) \
+ (NVIC_INT_PRI_REG(_int) &= ~NVIC_INT_PRI_M(_int) \
+ )
+
+/* NVIC Set Priority */
+#define NVIC_SET_PRI(_int, _pri) { \
+ NVIC_CLR_PRI(_int); \
+ ( \
+ NVIC_INT_PRI_REG(_int) |= ( \
+ NVIC_INT_PRI_M(_int) & NVIC_INT_PRI(_int, _pri) \
+ ) \
+ ); \
+}
+
+/* NVIC Get Priority */
+#define NVIC_GET_PRI(_int) ( \
+ ( \
+ (NVIC_INT_PRI_REG(_int) & NVIC_INT_PRI_M(_int)) >> ( \
+ ((EE_UREG)_int & NVIC_INT_PRI_REG_M) << NVIC_INT_PRI_REG_M \
+ ) \
+ ) >> NVIC_INT_PRI_S \
+ ) \
+
+/* NVIC Set Pending Interrupt */
+#define NVIC_INT_SET_PENDING(_int) ( \
+ NVIC_INT_REG(_int, NVIC_INT_SET_PENDING_REG_B) |= NVIC_INT_M(_int) \
+ )
+
+/* NVIC Clear Pending Interrupt */
+#define NVIC_INT_CLR_PENDING(_int) ( \
+ NVIC_INT_REG(_int, NVIC_INT_CLR_PENDING_REG_B) |= NVIC_INT_M(_int) \
+ )
+
+#endif /* __INCLUDE_CORTEX_MX_NVIC_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_systick.h b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_systick.h
new file mode 100644
index 0000000..c7664c0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/inc/ee_systick.h
@@ -0,0 +1,202 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_systick.h
+ * @brief SysTick system timer driver header file.
+ * @author Giuseppe Serano
+ * @date 2012
+ *
+ **/
+
+#ifndef __INCLUDE_CORTEX_MX_SYSTICK_H__
+#define __INCLUDE_CORTEX_MX_SYSTICK_H__
+
+#ifdef __USE_SYSTICK__
+
+/** error value. No errors happened **/
+#define EE_SYSTICK_NO_ERRORS 0
+/** error value. Wrong funtion arguments values **/
+#define EE_SYSTICK_ERR_BAD_ARGS 1
+
+/**
+ * @brief Start SysTick.
+ *
+ * This will start the SysTick counter. If an ISR has been defined, it is
+ * called when the SysTick counter rolls over.
+ *
+ * @note Calling this function will cause the SysTick counter to (re)commence
+ * counting from its current value. The counter is not automatically reloaded
+ * with the period as specified in a previous call to EE_systick_set_period().
+ * If an immediate reload is required, the \b NVIC_ST_CURRENT register must be
+ * written to force this. Any write to this register clears the SysTick
+ * counter to 0 and will cause a reload with the supplied period on the next
+ * clock.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_systick_start(void)
+{
+ NVIC_ST_CTRL_R |= NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE;
+}
+
+/**
+ * @brief Stop SysTick.
+ *
+ * This will stop the SysTick counter. If an ISR has been defined, it will
+ * no longer be called until SysTick is restarted.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_systick_stop(void)
+{
+ NVIC_ST_CTRL_R &= ~(NVIC_ST_CTRL_ENABLE);
+}
+
+/**
+ * @brief Enables the SysTick interrupt.
+ *
+ * This function will enable the SysTick interrupt, allowing it to be
+ * reflected to the processor.
+ *
+ * @note The SysTick ISR does not need to clear the SysTick interrupt source as
+ * this is done automatically by NVIC when the interrupt ISR is called.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_systick_enable_int()
+{
+ NVIC_ST_CTRL_R |= NVIC_ST_CTRL_INTEN;
+}
+
+/**
+ * @brief Disables the SysTick interrupt.
+ *
+ * This function will disable the SysTick interrupt, preventing it from being
+ * reflected to the processor.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_systick_disable_int()
+{
+ NVIC_ST_CTRL_R &= ~(NVIC_ST_CTRL_INTEN);
+}
+
+/**
+ * @brief Sets the period of the SysTick counter.
+ *
+ * @param period is the number of clock ticks in each period of the SysTick
+ * counter; must be between 1 and 16,777,216, inclusive. If the \e period is
+ * out of range the function returns \b EE_SYSTICK_ERR_BAD_ARGS, else it will
+ * returns \b EE_SYSTICK_NO_ERRORS.
+ *
+ * This function sets the rate at which the SysTick counter wraps; this
+ * equates to the number of processor clocks between interrupts.
+ *
+ * @note Calling this function does not cause the SysTick counter to reload
+ * immediately. If an immediate reload is required, the \b NVIC_ST_CURRENT
+ * register must be written. Any write to this register clears the SysTick
+ * counter to 0 and will cause a reload with the \e period supplied here on
+ * the next clock after the SysTick is enabled.
+ */
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_systick_set_period(EE_UREG period)
+{
+ if ((period == NVIC_ST_RELOAD_S) || (period > NVIC_ST_RELOAD_M)) {
+ return EE_SYSTICK_ERR_BAD_ARGS;
+ }
+
+ NVIC_ST_RELOAD_R = period - 1;
+
+ return EE_SYSTICK_NO_ERRORS;
+}
+
+/**
+ * @brief Gets the period of the SysTick counter.
+ *
+ * This function returns the rate at which the SysTick counter wraps; this
+ * equates to the number of processor clocks between interrupts.
+ *
+ * @return Returns the period of the SysTick counter.
+ */
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_systick_get_period()
+{
+ return NVIC_ST_RELOAD_R + 1;
+}
+
+/**
+ * @brief Gets the current value of the SysTick counter.
+ *
+ * This function returns the current value of the SysTick counter; this will
+ * be a value between the period - 1 and zero, inclusive.
+ *
+ * @return Returns the current value of the SysTick counter.
+ */
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_systick_get_value()
+{
+ /* */
+ /* Return the current value of the SysTick counter. */
+ /* */
+ return NVIC_ST_CURRENT_R;
+}
+
+/** Default Clock Frequency */
+#define EE_DEFAULT_CPU_CLOCK 16000000
+
+/**
+ * @brief Delay with SysTick .
+ *
+ * @param usDelay Number of us to Delay.
+ *
+ * This function delays the program execution by <tt>usDelay</tt> microseconds.
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_systick_delay_us(EE_UREG usDelay)
+{
+ EE_UREG const start = EE_systick_get_value();
+
+#ifdef EE_CPU_CLOCK
+ EE_UREG ticks = MICROSECONDS_TO_TICKS(usDelay, EE_CPU_CLOCK);
+#else
+ EE_UREG ticks = MICROSECONDS_TO_TICKS(usDelay, EE_DEFAULT_CPU_CLOCK);
+#endif
+ /* Bound the delay to max one whole run */
+ if ((ticks == NVIC_ST_RELOAD_S) || (ticks > NVIC_ST_RELOAD_M)) {
+ ticks = NVIC_ST_RELOAD_M - 1;
+ }
+
+ while (((EE_systick_get_value() - start) % NVIC_ST_RELOAD_M) < ticks) {
+ ; /* wait */
+ }
+}
+
+#endif /* __USE_SYSTICK__ */
+
+#endif /* __INCLUDE_CORTEX_MX_SYSTICK_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_change_context_isr.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_change_context_isr.s
new file mode 100644
index 0000000..2e124d5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_change_context_isr.s
@@ -0,0 +1,242 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2012 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; @file ee_ccs_change_context_isr.s
+; @brief Functions to active and manage the context switch for Cortex_MX
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2012
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+; void EE_switch_context(void);
+ .global EE_switch_context
+
+; void EE_cortex_mx_pendsv_handler(void);
+ .global EE_cortex_mx_pendsv_handler
+
+; void EE_cortex_mx_svcall_handler(void);
+ .global EE_cortex_mx_svcall_handler
+
+; void EE_set_switch_context_pri(void)
+ .global EE_set_switch_context_pri
+
+; void EE_IRQ_end_instance(void);
+ .global EE_IRQ_end_instance
+
+; void EE_cortex_mx_change_context(EE_TID tid);
+ .global EE_cortex_mx_change_context
+
+; EE_TID EE_std_endcycle_next_tid;
+ .global EE_std_endcycle_next_tid
+
+ .if $$isdefed("__MULTI__")
+; int EE_std_need_context_change(EE_TID tid);
+ .global EE_std_need_context_change
+ .endif
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ .text
+
+NVIC_INT_CTRL .word 0E000ED04h ; Interrupt control status register
+NVIC_SHPR2 .word 0E000ED1Ch ; System priority register (SVCall 11)
+NVIC_SHPR3 .word 0E000ED20h ; System priority register (PendSV 14)
+NVIC_PENDSV_PRI .word 000FF0000h ; PendSV priority OR-value (Lowest)
+NVIC_SVCALL_PRI .word 000FFFFFFh ; SVCall priority AND-value (Highest)
+NVIC_PENDSVSET .word 010000000h ; Value to trigger PendSV exception
+NVIC_PENDSVCLR .word 008000000h ; Value to un-trigger PendSV exception
+
+EPSR_T_BIT_VAL .word 001000000h ; Value to set the T-bit in EPSR
+ ; (always Thumb mode)
+
+EXC_RETURN .word 0xFFFFFFF9 ; No-FPU, Thread-Mode, MSP.
+
+ .if $$isdefed("__MONO__")
+TID_IS_STACKED_MARK .word 0x80000000
+ .endif
+
+_EE_cortex_mx_change_context_addr .word EE_cortex_mx_change_context
+_EE_std_endcycle_next_tid_addr .word EE_std_endcycle_next_tid
+_EE_cortex_mx_change_context_return_point_addr .word EE_cortex_mx_change_context_return_point
+
+
+; void EE_set_switch_context_pri(void)
+EE_set_switch_context_pri: .asmfunc
+
+;Set PendSV priority to the minumum one
+ LDR R0, NVIC_SHPR3
+ LDR R1, NVIC_PENDSV_PRI
+ LDR R2, [R0];
+ ORRS R2, R2, R1;
+ STR R2, [R0];
+
+;Set SVCall priority to the maximum one
+ LDR R0, NVIC_SHPR2
+ LDR R1, NVIC_SVCALL_PRI
+ LDR R2, [R0];
+ ANDS R2, R2, R1;
+ STR R2, [R0];
+
+ BX LR
+
+ .endasmfunc
+
+
+; void EE_switch_context(void)
+EE_switch_context: .asmfunc
+
+; Trigger the PendSV exception (causes context switch)
+ LDR R0, NVIC_INT_CTRL
+ LDR R1, NVIC_PENDSVSET
+ STR R1, [R0]
+ BX LR
+
+ .endasmfunc
+
+
+; void EE_cortex_mx_pendsv_handler(void)
+EE_cortex_mx_pendsv_handler: .asmfunc
+
+ CPSID I ; Disable all interrupts.
+
+; Clear the PendSV exception (preventing 2nd triggering)
+ LDR R0, NVIC_INT_CTRL
+ LDR R1, NVIC_PENDSVCLR
+ STR R1, [R0]
+
+ BL EE_IRQ_end_instance ; IRQ Scheduler.
+
+; R0 = EE_std_endcycle_next_tid.
+ LDR R0, _EE_std_endcycle_next_tid_addr
+ LDR R0, [R0]
+
+ .if $$isdefed("__MONO__")
+; #define EE_std_need_context_change(tid) ((tid) >= 0)
+ LDR R1, TID_IS_STACKED_MARK
+ ANDS R0, R0, R1
+ CBNZ R0, EE_cortex_mx_pendsv_handler_end
+ .endif
+
+ .if $$isdefed("__MULTI__")
+ BL EE_std_need_context_change
+ CBZ R0, EE_cortex_mx_pendsv_handler_end
+ .endif
+
+; Build a stack frame to jump into the EE_std_change_context(EE_TID) at the end
+; of PendSV_Handler.
+
+; R0 = EE_std_endcycle_next_tid (R12)
+ LDR R0, _EE_std_endcycle_next_tid_addr
+ LDR R0, [R0]
+
+; R3 = 0x01000000 (xPSR)
+ LDR R3, EPSR_T_BIT_VAL
+
+; R2 = EE_cortex_mx_change_context (PC)
+ LDR R2, _EE_cortex_mx_change_context_addr
+
+; R1 = exit_EE_cortex_mx_change_context (LR)
+ LDR R1, _EE_cortex_mx_change_context_return_point_addr
+
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+ PUSH {R0-R3}
+
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 |
+ PUSH {R0-R3}
+
+;Fake IRQ handler frame on top of PendSV frame:
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 | <- MSP
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, EXC_RETURN
+ BX R0 ; EXC_RETURN.
+
+ NOP ; Alignment.
+
+EE_cortex_mx_pendsv_handler_end:
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, EXC_RETURN
+ CPSIE I ; Enable all interrupts.
+ BX R0 ; EXC_RETURN.
+
+ .endasmfunc
+
+
+EE_cortex_mx_change_context_return_point: .asmfunc
+; Enable interrupts (clear PRIMASK)
+; NOTE: If SVC is executed when PRIMASK is set to 1, HardFault Exception will
+; occur. To solve this, instead of using PRIMASK to mask interrupts, use
+; BASEPRI to mask particular interrupts.
+ CPSIE I
+; SVCall exception to remove Original PendSV stack-frame.
+ SVC #0
+
+ .endasmfunc
+
+; void EE_cortex_mx_svc_ISR(void)
+EE_cortex_mx_svcall_handler: .asmfunc
+; Remove SVCall Stack-Frame.
+ ADD SP, SP, #(8*4)
+
+ BX LR ; EXC_RETURN.
+
+ .endasmfunc
+
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_irq_stack.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_irq_stack.s
new file mode 100644
index 0000000..95a5409
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_irq_stack.s
@@ -0,0 +1,100 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_ccs_irq_stack.s
+; @brief Context switch function for multistack on Cortex_MX
+; @brief Stack switch for ISRs on Cortex_MX.
+; Implementation of EE_cortex_mx_call_ISR_new_stack() as described in
+; pkg/cpu/cortex_mx/inc/ee_irq_internal.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+;
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+ .global EE_cortex_mx_change_IRQ_stack
+ .global EE_cortex_mx_change_IRQ_stack_back
+
+;*******************************************************************************
+; EXTERNAL DATA
+;*******************************************************************************
+
+ .global EE_cortex_mx_IRQ_tos
+
+;*******************************************************************************
+; DATA SECTION
+;*******************************************************************************
+ .data
+
+EE_cortex_mx_tmp_tos .word 00h ; EE_UREG EE_cortex_mx_tmp_tos;
+
+;*******************************************************************************
+; CODE SECTION
+;******************************************************************************
+ .text
+
+EE_cortex_mx_tmp_tos_addr .word EE_cortex_mx_tmp_tos
+EE_cortex_mx_IRQ_tos_addr .word EE_cortex_mx_IRQ_tos
+
+;void EE_cortex_mx_change_IRQ_stack(void);
+EE_cortex_mx_change_IRQ_stack:
+ MRS R0, MSP ; R0 = MSP (Main stack Pointer)
+ LDR R1, EE_cortex_mx_tmp_tos_addr; R1 = address of EE_cortex_mx_tmp_tos
+ STR R0, [R1] ; Save MSP in EE_cortex_mx_tmp_tos
+ LDR R0, EE_cortex_mx_IRQ_tos_addr; R0 = address of EE_cortex_mx_IRQ_tos
+ LDR R0, [R0] ; R0 = IRQ new stack pointer
+ MSR MSP, R0 ; change IRQ stack
+
+ BX LR ; return
+
+;void EE_cortex_mx_change_IRQ_stack_back(void);
+EE_cortex_mx_change_IRQ_stack_back:
+ LDR R0, EE_cortex_mx_tmp_tos_addr; R0 = address of EE_cortex_mx_tmp_tos
+ LDR R0, [R0] ; R0 = old MSP
+ MSR MSP, R0 ; Restore the stack pointer
+
+ BX LR ; return
+
+ .end
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_multi_context.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_multi_context.s
new file mode 100644
index 0000000..dbfa4c2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_multi_context.s
@@ -0,0 +1,191 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_ccs_multi_context.s
+; @brief Context switch function for multistack on Cortex_MX
+; Implementation of EE_cortex_mx_change_context as described in
+; pkg/cpu/common/inc/ee_context.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+;
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+ .global EE_cortex_mx_change_context ; void EE_cortex_mx_change_context(EE_TID tid);
+
+;*******************************************************************************
+; EXTERNAL FUNCTIONS
+;*******************************************************************************
+
+ .global EE_std_run_task_code
+
+;*******************************************************************************
+; EXTERNAL DATA
+;*******************************************************************************
+
+ .global EE_std_thread_tos
+ .global EE_cortex_mx_active_tos
+ .global EE_cortex_mx_system_tos
+
+;*******************************************************************************
+; CODE SECTION
+;******************************************************************************
+ .text
+
+EE_std_thread_tos_addr .word EE_std_thread_tos
+EE_cortex_mx_active_tos_addr .word EE_cortex_mx_active_tos
+EE_cortex_mx_system_tos_addr .word EE_cortex_mx_system_tos
+
+;
+;Pseudo code for EE_cortex_mx_change_context():
+; begin:
+; tos_index = EE_std_thread_tos[tid+1];
+; if is_not_the_current_stack(tos_index) {
+; save_caller_saved_registers();
+; switch_stacks(tos_index);
+; restore_caller_saved_registers();
+; }
+; if (is_not_marked_stacked(tid)) {
+; tid = EE_std_run_task_code(tid);
+; goto begin;
+; }
+;
+
+;void EE_cortex_mx_change_context(EE_TID tid);
+EE_cortex_mx_change_context:
+ ; R0 == tid
+ ; tos_index = EE_std_thread_tos[tid+1];
+ ADDS R1, R0, #1 ; R1 = tid+1
+ LSLS R1, R1, #2 ; R1 = (tid+1)*4 = correct offset in EE_std_thread_tos
+ ; The last shift, also gets rid of the `stacked' mark
+ LDR R2, EE_std_thread_tos_addr
+ ADD R1, R2, R1
+ LDR R1, [R1] ;R1 == tos_index
+
+ ;*
+ ;* if is_not_the_current_stack(tos_index) {
+ ;*
+ LDR R2, EE_cortex_mx_active_tos_addr ;R2 = & EE_cortex_mx_active_tos;
+ LDR R3, [R2] ; R3 = EE_cortex_mx_active_tos;
+ CMP R1, R3
+ BEQ end_change_stacks
+
+ ;save_caller_saved_registers();
+
+ ;Save all callee-saved registers
+ ;R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+
+ ;!!!!!!!!!!!!!!!
+ ; At this point the non scratch registers (R4...R11) are pushed into stack,
+ ; hence I can use them in the following.
+ ;!!!!!!!!!!!!!!!!
+
+ ; switch_stacks(tos_index);
+ LDR R4, EE_cortex_mx_system_tos_addr ; R4 = & cortex_mx_system_tos[0];
+ ; Note: although R4 is not a scratch register, it has been saved onto stack,
+ ; therefore we can used it in the follow without problem
+ ; EE_cortex_mx_system_tos[R3] = MSP;
+ LSLS R3, R3, #2
+ ADD R3, R4, R3
+ MRS R5, MSP
+ ; Note STR can only use the register range -> R0 to R4.
+ STR R5, [R3] ; save stack pointer
+
+ ; EE_cortex_mx_active_tos = tos_index;
+ STR R1, [R2]
+ ; MSP= EE_cortex_mx_system_tos[R1];
+ LSLS R1, R1, #2
+ ADD R1, R4, R1
+ LDR R1, [R1]
+ MSR MSP, R1
+ ; restore_caller_saved_registers();
+ POP {R1} ; Get link register from stack
+ MOV LR, R1 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ ; *
+ ; * }
+ ; *
+
+end_change_stacks:
+ ; R0 == tid
+
+ ; *
+ ; *if (is_not_marked_stacked(tid)) {
+ ; *
+
+ CMP R0, #0
+ BLT end_run_thread
+
+ ; tid = EE_std_run_task_code(tid);
+ PUSH {LR}
+ BL EE_std_run_task_code
+ ; R0 == tid
+ POP {R1}
+ MOV LR, R1
+
+ B EE_cortex_mx_change_context
+ ; goto begin
+
+ ; *
+ ; * }
+ ; *
+
+end_run_thread:
+
+ BX LR ; Return
+
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_oo.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_oo.s
new file mode 100644
index 0000000..9cc774d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_ccs_oo.s
@@ -0,0 +1,155 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_ccs_oo.S
+; @brief Functions to save and restore registers for Osek TerminateTask()
+; on Cortex_mX
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+;
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ ; Functions declared in this file
+ .global EE_hal_terminate_savestk ; void EE_hal_terminate_savestk(EE_TID tid)
+ .global EE_hal_terminate_task ; NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+;*******************************************************************************
+; EXTERNAL DATA
+;*******************************************************************************
+
+ .global EE_terminate_real_th_body
+ .global EE_terminate_data
+ .global EE_thread_not_terminated
+
+;*******************************************************************************
+; CODE SECTION
+;******************************************************************************
+ .text
+
+_EPSR_T_BIT_VAL .word 001000000h ; Value to set the T-bit in EPSR (always Thumb mode)
+
+_EE_terminate_real_th_body_addr .word EE_terminate_real_th_body
+_EE_terminate_data_addr .word EE_terminate_data
+_EE_thread_not_terminated_addr .word EE_thread_not_terminated
+
+ ;void EE_hal_terminate_savestk(EE_TID tid);
+EE_hal_terminate_savestk:
+ ; Save all callee-saved registers
+ ; R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+ MRS R3, XPSR ; Store xPSR to 8-bytes stack aligment
+ PUSH {R3}
+ ;R0 == tid
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, _EE_terminate_real_th_body_addr ; R1 == EE_terminate_real_th_body[tid]
+ ADD R1, R1, R0
+ LDR R1, [R1]
+ ; Save the stack pointer (including space for registers)
+ ; R2 == & EE_terminate_data[tid]
+ LDR R2, _EE_terminate_data_addr
+ ADD R2, R2, R0
+ MRS R3, MSP ; Get the stack pointer
+ STR R3, [R2] ; Save stack pointer
+
+ ;Start the thread body
+ BLX R1
+
+ ; The task terminated with a return: do the usual cleanup
+ LDR R0, _EE_thread_not_terminated_addr
+ BLX R0
+
+ ; NOTE: code never executed because EE_thread_not_terminated()
+ POP {R2} ; Get xPSR from stack
+ LDR R0, _EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR XPSR, R2 ; Restore xPSR register
+ POP {R0} ; Get link register from stack
+ MOV LR, R0 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+
+ ;void EE_hal_terminate_task(EE_TID tid) NORETURN; */
+EE_hal_terminate_task:
+ ; R0 == tid
+
+ ; Restore the stack pointer
+ ; R1 == & EE_terminate_data[tid]
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, _EE_terminate_data_addr ; R1 == & EE_terminate_data[tid]
+ ADD R1, R1, R0
+ LDR R2, [R1]
+ MSR MSP, R2
+
+ POP {R2} ; Get xPSR from stack
+ LDR R0, _EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR XPSR, R2 ; Restore xPSR register
+ POP {R3} ; Get link register from stack
+ MOV LR, R3 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_context.c b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_context.c
new file mode 100644
index 0000000..e6ecd8a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_context.c
@@ -0,0 +1,81 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Context switch functions used in HAL implementations
+ * Author: 2011 Gianluca Franchino
+ * 2011 Giuseppe Serano
+ */
+
+#include "ee_internal.h"
+
+#ifdef __MONO__
+
+void EE_cortex_mx_change_context(EE_TID tid)
+{
+ do {
+ tid = EE_std_run_task_code(tid);
+ } while (EE_std_need_context_change(tid));
+}
+
+#endif /* __MONO__ */
+
+#ifdef __MULTI__
+
+int EE_std_need_context_change(EE_TID tid)
+{
+ /* FIXME: "tid+1" can be used as an index for arrays even when marked if
+ * EE_TID is defined as an int. Otherwise, the mark will cause a memory
+ * access violation! */
+ EE_UTID utid;
+ int need_context_change = 1;
+
+ if (tid < 0) {
+ /* Unmark the tid to access the EE_std_thread_tos, otherwise undefined
+ * behaviour. (Index out of arrays boundaries)
+ * FIXME: #1
+ */
+ utid = (EE_UTID)tid & (~(EE_UTID)TID_IS_STACKED_MARK);
+ need_context_change = (EE_hal_active_tos != EE_std_thread_tos[utid + 1U]);
+ }
+ return need_context_change;
+}
+
+#endif /* __MULTI__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_change_context_isr.S b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_change_context_isr.S
new file mode 100644
index 0000000..a2e4904
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_change_context_isr.S
@@ -0,0 +1,262 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2012 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; @file ee_gnu_change_context_isr.s
+; @brief Functions to active and manage the context switch for Cortex_MX
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @author Mauro Marinoni
+; @author Alessandro Biondi
+; @date 2013
+*/
+
+@*******************************************************************************
+@ PUBLIC FUNCTIONS
+@*******************************************************************************
+
+#define EE_cortex_mx_pendsv_ISR mt_exc_pendsv
+#define EE_cortex_mx_svc_ISR mt_exc_svc
+
+@ void EE_switch_context(void);
+ .global EE_switch_context
+
+@ void EE_cortex_mx_pendsv_ISR(void);
+ .global EE_cortex_mx_pendsv_ISR
+
+@ void EE_cortex_mx_svc_ISR(void);
+ .global EE_cortex_mx_svc_ISR
+
+@ void EE_set_switch_context_pri(void)
+ .global EE_set_switch_context_pri
+
+@ void EE_IRQ_end_instance(void);
+ .global EE_IRQ_end_instance
+
+@ void EE_cortex_mx_change_context(EE_TID tid);
+ .global EE_cortex_mx_change_context
+
+@ EE_TID EE_std_endcycle_next_tid;
+ .global EE_std_endcycle_next_tid
+
+ .global EE_cortex_mx_change_context_return_point
+
+#ifdef __MULTI__
+@ int EE_std_need_context_change(EE_TID tid);
+ .global EE_std_need_context_change
+#endif
+
+@*******************************************************************************
+@ CODE SECTION
+@*******************************************************************************
+ .text
+
+@ kernel code is in ARM-mode
+ .syntax unified
+ .arch armv7e-m
+ .cpu cortex-m4
+
+
+#define NVIC_INT_CTRL 0xE000ED04 @ Interrupt control status register
+#define NVIC_SHPR2 0xE000ED1C @ System priority register (SVCall 11)
+#define NVIC_SHPR3 0xE000ED20 @ System priority register (PendSV 14)
+#define NVIC_PENDSV_PRI 0x00FF0000 @ PendSV priority OR-value (Lowest)
+#define NVIC_SVCALL_PRI 0x00FFFFFF @ SVCall priority AND-value (Highest)
+#define NVIC_PENDSVSET 0x10000000 @ Value to trigger PendSV exception
+#define NVIC_PENDSVCLR 0x08000000 @ Value to un-trigger PendSV exception
+
+#define EPSR_T_BIT_VAL 0x01000000 @ Value to set the T-bit in EPSR
+ @ (always Thumb mode)
+
+#define EXC_RETURN 0xFFFFFFF9 @ No-FPU, Thread-Mode, MSP.
+
+#ifdef __MONO__
+#define TID_IS_STACKED_MARK 0x80000000
+#endif
+
+#define _EE_cortex_mx_change_context_addr EE_cortex_mx_change_context
+#define _EE_std_endcycle_next_tid_addr EE_std_endcycle_next_tid
+#define _EE_cortex_mx_change_context_return_point_addr EE_cortex_mx_change_context_return_point
+
+
+@ void EE_set_switch_context_pri(void)
+ .type EE_set_switch_context_pri, #function
+EE_set_switch_context_pri:
+
+@Set PendSV priority to the minumum one
+ LDR R0, =NVIC_SHPR3
+ LDR R1, =NVIC_PENDSV_PRI
+ LDR R2, [R0];
+ ORRS R2, R2, R1;
+ STR R2, [R0];
+
+@Set SVCall priority to the maximum one
+ LDR R0, =NVIC_SHPR2
+ LDR R1, =NVIC_SVCALL_PRI
+ LDR R2, [R0];
+ ANDS R2, R2, R1;
+ STR R2, [R0];
+
+ BX LR
+
+ .size EE_set_switch_context_pri, . - EE_set_switch_context_pri
+
+
+@ void EE_switch_context(void)
+ .type EE_switch_context, #function
+EE_switch_context:
+
+@ Trigger the PendSV exception (causes context switch)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVSET
+ STR R1, [R0]
+ BX LR
+
+ .size EE_switch_context, . - EE_switch_context
+
+
+@ void EE_cortex_mx_pendsv_ISR(void)
+ .type EE_cortex_mx_pendsv_ISR, #function
+EE_cortex_mx_pendsv_ISR:
+
+ CPSID I @ Disable all interrupts.
+
+@ Clear the PendSV exception (preventing 2nd triggering)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVCLR
+ STR R1, [R0]
+
+ BL EE_IRQ_end_instance @ IRQ Scheduler.
+
+@ R0 = EE_std_endcycle_next_tid.
+ LDR R0, =_EE_std_endcycle_next_tid_addr
+ LDR R0, [R0]
+
+#ifdef __MONO__
+@ #define EE_std_need_context_change(tid) ((tid) >= 0)
+ LDR R1, =TID_IS_STACKED_MARK
+ ANDS R0, R0, R1
+ CBNZ R0, EE_cortex_mx_pendsv_ISR_end
+#endif
+
+#ifdef __MULTI__
+ BL EE_std_need_context_change
+ CBZ R0, EE_cortex_mx_pendsv_ISR_end
+#endif
+
+@ Build a stack frame to jump into the EE_std_change_context(EE_TID) at the end
+@ of PendSV_Handler.
+
+@ R0 = EE_std_endcycle_next_tid (R12)
+ LDR R0, =_EE_std_endcycle_next_tid_addr
+ LDR R0, [R0]
+
+@ R3 = 0x01000000 (xPSR)
+ LDR R3, =EPSR_T_BIT_VAL
+
+@ R2 = EE_cortex_mx_change_context (PC)
+ LDR R2, =_EE_cortex_mx_change_context_addr
+
+@ R1 = exit_EE_cortex_mx_change_context (LR)
+ LDR R1, =_EE_cortex_mx_change_context_return_point_addr
+
+@|xPSR|-> xPSR AND 0xFFFFFE0
+@| PC |-> EE_cortex_mx_change_context
+@| LR |-> EE_cortex_mx_change_context_return_point
+@| R12|
+ PUSH {R0-R3}
+
+@| R3 |
+@| R2 |
+@| R1 |
+@| R0 |
+ PUSH {R0-R3}
+
+@Fake IRQ handler frame on top of PendSV frame:
+@|xPSR|-> xPSR AND 0xFFFFFE0
+@| PC |-> EE_cortex_mx_change_context
+@| LR |-> EE_cortex_mx_change_context_return_point
+@| R12|
+@| R3 |
+@| R2 |
+@| R1 |
+@| R0 | <- MSP
+@ R0 = EXC_RETURN -> Return to Thread mode.
+@ -> Exception return gets state from MSP.
+@ -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ BX R0 @ EXC_RETURN.
+
+ NOP @ Alignment.
+
+EE_cortex_mx_pendsv_ISR_end:
+@ R0 = EXC_RETURN -> Return to Thread mode.
+@ -> Exception return gets state from MSP.
+@ -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ CPSIE I @ Enable all interrupts.
+ BX R0 @ EXC_RETURN.
+
+ .size EE_cortex_mx_pendsv_ISR, . - EE_cortex_mx_pendsv_ISR
+
+
+@ Enable interrupts (clear PRIMASK)
+ .type EE_cortex_mx_change_context_return_point, #function
+EE_cortex_mx_change_context_return_point:
+/*; NOTE: If SVC is executed when PRIMASK is set to 1, HardFault Exception will
+; occur. To solve this, instead of using PRIMASK to mask interrupts, use
+; BASEPRI to mask particular interrupts. */
+ CPSIE I
+@ SVCall exception to remove Original PendSV stack-frame.
+ SVC #0
+
+ .size EE_cortex_mx_change_context_return_point, . - EE_cortex_mx_change_context_return_point
+
+@ void EE_cortex_mx_svc_ISR(void)
+ .type EE_cortex_mx_svc_ISR, #function
+EE_cortex_mx_svc_ISR:
+@ Remove SVCall Stack-Frame.
+ ADD SP, SP, #(8*4)
+
+ BX LR @ EXC_RETURN.
+
+ .size EE_cortex_mx_svc_ISR, . - EE_cortex_mx_svc_ISR
+
+
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_irq_stack.S b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_irq_stack.S
new file mode 100644
index 0000000..3771038
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_irq_stack.S
@@ -0,0 +1,114 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_keil_irq_stack.s
+; @brief Context switch function for multistack on Cortex_MX
+; @brief Stack switch for ISRs on Cortex_MX.
+; Implementation of EE_cortex_mx_call_ISR_new_stack() as described in
+; pkg/cpu/cortex_mx/inc/ee_irq_internal.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @author Alessandro Biondi
+; @date 2013
+*/
+
+@*******************************************************************************
+@ PUBLIC FUNCTIONS
+@*******************************************************************************
+ .global EE_cortex_mx_change_IRQ_stack
+ .global EE_cortex_mx_change_IRQ_stack_back
+
+ .global EE_cortex_mx_IRQ_tos
+
+
+@*******************************************************************************
+@ DATA SECTION
+@*******************************************************************************
+ .data
+
+EE_cortex_mx_tmp_tos: .word 0 @ EE_UREG EE_cortex_mx_tmp_tos;
+
+@*******************************************************************************
+@ CODE SECTION
+@*******************************************************************************
+ .text
+
+@ kernel code is in ARM-mode
+ .syntax unified
+ .arch armv7e-m
+ .cpu cortex-m4
+
+@void EE_cortex_mx_change_IRQ_stack(void);
+ .type EE_cortex_mx_change_IRQ_stack, #function
+EE_cortex_mx_change_IRQ_stack:
+
+ MRS R0, MSP @ R0 = MSP (Main stack Pointer)
+ LDR R1, =EE_cortex_mx_tmp_tos @ R1 = address of EE_cortex_m0_tmp_tos
+ STR R0, [R1] @ Save MSP in EE_cortex_mx_tmp_tos
+ LDR R0, =EE_cortex_mx_IRQ_tos @ R0 = address of EE_cortex_mx_IRQ_tos
+ LDR R0, [R0] @ R0 = IRQ new stack pointer
+ MSR MSP, R0 @ change IRQ stack
+
+ BX LR @ return
+
+ .size EE_cortex_mx_change_IRQ_stack, . - EE_cortex_mx_change_IRQ_stack
+
+@*******************************************************************************
+
+@void EE_cortex_mx_change_IRQ_stack_back(void);
+ .type EE_cortex_mx_change_IRQ_stack_back, #function
+EE_cortex_mx_change_IRQ_stack_back:
+
+ LDR R0, =EE_cortex_mx_tmp_tos @ R0 = address of EE_cortex_mx_tmp_tos
+ LDR R0, [R0] @ R0 = old MSP
+ MSR MSP, R0 @ Restore the stack pointer
+
+ BX LR @ return
+
+ .size EE_cortex_mx_change_IRQ_stack_back, . - EE_cortex_mx_change_IRQ_stack_back
+
+@******************************************************************************
+@
+@ Tell the assembler that we're done.
+@
+@******************************************************************************
+ .end
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_multi_context.S b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_multi_context.S
new file mode 100644
index 0000000..daf7547
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_multi_context.S
@@ -0,0 +1,197 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_keil_multi_context.s
+; @brief Context switch function for multistack on Cortex MX
+; Implementation of EE_cortex_mx_change_context as described in
+; pkg/cpu/common/inc/ee_context.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @author Alessandro Biondi
+; @date 2013
+*/
+
+@*******************************************************************************
+@ PUBLIC FUNCTIONS
+@*******************************************************************************
+ .global EE_cortex_mx_change_context
+
+ .global EE_std_run_task_code
+ .global EE_std_thread_tos
+ .global EE_cortex_mx_active_tos
+ .global EE_cortex_mx_system_tos
+
+@*******************************************************************************
+@ CODE SECTION
+@*******************************************************************************
+ .text
+
+@ kernel code is in ARM-mode
+ .syntax unified
+ .arch armv7e-m
+ .cpu cortex-m4
+
+@Pseudo code for EE_cortex_mx_change_context():
+@ begin:
+@ tos_index = EE_std_thread_tos[tid+1];
+@ if is_not_the_current_stack(tos_index) {
+@ save_caller_saved_registers();
+@ switch_stacks(tos_index);
+@ restore_caller_saved_registers();
+@ }
+@ if (is_not_marked_stacked(tid)) {
+@ tid = EE_std_run_task_code(tid);
+@ goto begin;
+@ }
+@
+
+@void EE_cortex_mx_change_context(EE_TID tid);
+ .type EE_cortex_mx_change_context, #function
+EE_cortex_mx_change_context:
+ @ R0 == tid
+ @ tos_index = EE_std_thread_tos[tid+1];
+ ADDS R1, R0, #1 @ R1 = tid+1
+ LSLS R1, R1, #2 @ R1 = (tid+1)*4= correct offset in EE_std_thread_tos
+ @ The last shift, also gets rid of the `stacked' mark
+ LDR R2, =EE_std_thread_tos
+ ADD R1, R2, R1
+ LDR R1, [R1] @R1 == tos_index
+
+ @*
+ @* if is_not_the_current_stack(tos_index) {
+ @*
+ LDR R2, =EE_cortex_mx_active_tos @R2 = & EE_cortex_mx_active_tos;
+ LDR R3, [R2] @ R3 = EE_cortex_mx_active_tos;
+ CMP R1, R3
+ BEQ end_change_stacks
+
+ @save_caller_saved_registers();
+
+ @Save all callee-saved registers
+ @R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} @ Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} @ Store R8, R9, R10, R11 onto stack
+ PUSH {LR} @ Store link register (return address)
+
+ @!!!!!!!!!!!!!!!
+ @ At this point the non scratch registers (R4...R11) are pushed into stack,
+ @ hence I can use them in the following.
+ @!!!!!!!!!!!!!!!!
+
+ @ switch_stacks(tos_index);
+ LDR R4, =EE_cortex_mx_system_tos @ R4 = & cortex_mx_system_tos[0];
+ @ Note: although R4 is not a scratch register, it has been saved onto stack,
+ @ therefore we can used it in the follow without problem
+ @ EE_cortex_mx_system_tos[R3] = MSP;
+ LSLS R3, R3, #2
+ ADD R3, R4, R3
+ MRS R5, MSP
+ @ Note STR can only use the register range -> R0 to R4.
+ STR R5, [R3] @ save stack pointer
+
+ @ EE_cortex_mx_active_tos = tos_index;
+ STR R1, [R2]
+ @ MSP= EE_cortex_mx_system_tos[R1];
+ LSLS R1, R1, #2
+ ADD R1, R4, R1
+ LDR R1, [R1]
+ MSR MSP, R1
+ @; restore_caller_saved_registers();
+ POP {R1} @ Get link register from stack
+ MOV LR, R1 @ Restore the link register
+ @ Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} @ Restore R4, R5, R6, R7 from stack
+ @ *
+ @ * }
+ @ *
+
+
+
+end_change_stacks:
+ @ R0 == tid
+
+ @ *
+ @ *if (is_not_marked_stacked(tid)) {
+ @ *
+
+ CMP R0, #0
+ BLT end_run_thread
+
+ @ tid = EE_std_run_task_code(tid);
+ PUSH {LR}
+ @ maintain 8-byte align
+ SUB SP, SP, 4
+ BL EE_std_run_task_code
+ ADD SP, SP, 4
+ @ R0 == tid
+ POP {R1}
+ MOV LR, R1
+
+ B EE_cortex_mx_change_context
+ @ goto begin
+
+ @ *
+ @ * }
+ @ *
+
+end_run_thread:
+
+ BX LR @ Return
+
+ .size EE_cortex_mx_change_context, . - EE_cortex_mx_change_context
+
+
+@******************************************************************************
+@
+@ Tell the assembler that we're done.
+@
+@******************************************************************************
+ .end
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_oo.S b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_oo.S
new file mode 100644
index 0000000..26f0c5d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_gnu_oo.S
@@ -0,0 +1,174 @@
+/* ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;
+; @file ee_keil_oo.S
+; @brief Functions to save and restore registers for OSEK TerminateTask().
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @author Alessandro Biondi
+; @date 2013
+*/
+
+@*******************************************************************************
+@ PUBLIC FUNCTIONS
+@*******************************************************************************
+ @ Functions declared in this file
+ .global EE_hal_terminate_savestk @ void EE_hal_terminate_savestk(EE_TID tid)
+ .global EE_hal_terminate_task @ NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+ .global EE_terminate_real_th_body
+ .global EE_terminate_data
+ .global EE_thread_not_terminated
+
+@*******************************************************************************
+@ EQUATES
+@*******************************************************************************
+#define EPSR_T_BIT_VAL 0x01000000 @ Value to set the T-bit in EPSR (always Thumb mode)
+
+
+@*******************************************************************************
+@ CODE SECTION
+@*******************************************************************************
+
+ .text
+
+@ kernel code is in ARM-mode
+ .syntax unified
+ .arch armv7e-m
+ .cpu cortex-m4
+
+
+@void EE_hal_terminate_savestk(EE_TID tid);
+ .type EE_hal_terminate_savestk, #function
+EE_hal_terminate_savestk:
+ @ Save all callee-saved registers
+ @ R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} @ Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} @ Store R8, R9, R10, R11 onto stack
+ PUSH {LR} @ Store link register (return address)
+ MRS R3, PSR @ Store xPSR to 8-bytes stack aligment
+ PUSH {R3}
+ @R0 == tid
+ LSLS R0, R0, #2 @ R0 = tid << 2
+ LDR R1, =EE_terminate_real_th_body @ R1 == EE_terminate_real_th_body[tid]
+ ADD R1, R1, R0
+ LDR R1, [R1]
+ @ Save the stack pointer (including space for registers)
+ @ R2 == & EE_terminate_data[tid]
+ LDR R2, =EE_terminate_data
+ ADD R2, R2, R0
+ MRS R3, MSP @ Get the stack pointer
+ STR R3, [R2] @ Save stack pointer
+
+ @Start the thread body
+ BLX R1
+
+ @ The task terminated with a return: do the usual cleanup
+ LDR R0, =EE_thread_not_terminated
+ BLX R0
+
+ @ NOTE: code never executed because EE_thread_not_terminated()
+ POP {R2} @ Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL @ R0 = 0x01000000
+ ORRS R2, R2, R0 @ R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ @ to avoid an hard_fault exception
+ MSR XPSR_NZCVQ, R2 @ Restore xPSR register
+ POP {R0} @ Get link register from stack
+ MOV LR, R0 @ Restore the link register
+ @ Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} @ Restore R4, R5, R6, R7 from stack
+
+ BX LR @ Return
+
+ .size EE_hal_terminate_savestk, . - EE_hal_terminate_savestk
+
+
+@*******************************************************************************
+
+@void EE_hal_terminate_task(EE_TID tid) NORETURN
+ .type EE_hal_terminate_task, #function
+EE_hal_terminate_task:
+
+ @ R0 == tid
+
+ @ Restore the stack pointer
+ @ R1 == & EE_terminate_data[tid]
+ LSLS R0, R0, #2 @ R0 = tid << 2
+ LDR R1, =EE_terminate_data @ R1 == & EE_terminate_data[tid]
+ ADD R1, R1, R0
+ LDR R2, [R1]
+ MSR MSP, R2
+
+ POP {R2} @ Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL @ R0 = 0x01000000
+ ORRS R2, R2, R0 @ R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ @ to avoid an hard_fault exception
+ MSR XPSR_NZCVQ, R2 @ Restore xPSR register
+ POP {R3} @ Get link register from stack
+ MOV LR, R3 @ Restore the link register
+ @ Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} @ Restore R4, R5, R6, R7 from stack
+
+ BX LR @ Return
+
+ .size EE_hal_terminate_task, . - EE_hal_terminate_task
+
+
+@******************************************************************************
+@
+@ Tell the assembler that we're done.
+@
+@******************************************************************************
+ .end
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_change_context_isr.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_change_context_isr.s
new file mode 100644
index 0000000..e0bc14f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_change_context_isr.s
@@ -0,0 +1,235 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ @file ee_iar_change_context_isr.s
+ @brief Functions to active and manage the context switch for Cortex_MX
+ @author Gianluca Franchino
+ @author Giuseppe Serano
+ @date 2012
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+; void EE_switch_context(void)
+ PUBLIC EE_switch_context
+
+; void PendSV_Handler(void);
+ PUBLIC PendSV_Handler
+
+; void SVC_Handler(void);
+ PUBLIC SVC_Handler
+
+; void EE_set_switch_context_pri(void)
+ PUBLIC EE_set_switch_context_pri
+
+
+; void EE_IRQ_end_instance(void);
+ EXTERN EE_IRQ_end_instance
+
+; void EE_cortex_mx_change_context(EE_TID tid);
+ EXTERN EE_cortex_mx_change_context
+
+; EE_TID EE_std_endcycle_next_tid;
+ EXTERN EE_std_endcycle_next_tid
+
+#ifdef __MULTI__
+; int EE_std_need_context_change(EE_TID tid);
+ EXTERN EE_std_need_context_change
+#endif
+
+;*******************************************************************************
+; EQUATES
+;*******************************************************************************
+NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control status register
+NVIC_SHPR2 EQU 0xE000ED1C ; System priority register (SVCall 11)
+NVIC_SHPR3 EQU 0xE000ED20 ; System priority register (PendSV 14)
+NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority OR-value (Lowest)
+NVIC_SVCALL_PRI EQU 0x00FFFFFF ; SVCall priority AND-value (Highest)
+NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception
+NVIC_PENDSVCLR EQU 0x08000000 ; Value to un-trigger PendSV exception
+
+EPSR_T_BIT_VAL EQU 0x01000000 ; Value to set the T-bit in EPSR
+ ; (always Thumb mode)
+
+EXC_RETURN EQU 0xFFFFFFF9 ; No-FPU, Thread-Mode, MSP.
+
+#ifdef __MONO__
+TID_IS_STACKED_MARK EQU 0x80000000
+#endif
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ SECTION CODE : CODE(2)
+ THUMB
+
+
+; void EE_set_switch_context_pri(void)
+EE_set_switch_context_pri:
+
+;Set PendSV priority to the minumum one
+ LDR R0, =NVIC_SHPR3
+ LDR R1, =NVIC_PENDSV_PRI
+ LDR R2, [R0];
+ ORRS R2, R2, R1;
+ STR R2, [R0];
+
+;Set SVCall priority to the maximum one
+ LDR R0, =NVIC_SHPR2
+ LDR R1, =NVIC_SVCALL_PRI
+ LDR R2, [R0];
+ ANDS R2, R2, R1;
+ STR R2, [R0];
+
+ BX LR
+
+; void EE_switch_context(void)
+EE_switch_context:
+
+; Trigger the PendSV exception (causes context switch)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVSET
+ STR R1, [R0]
+
+ BX LR
+
+; void PendSV_Handler(void)
+PendSV_Handler:
+
+ CPSID I ; Disable all interrupts (set PRIMASK).
+
+; Clear the PendSV exception (preventing 2nd triggering)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVCLR
+ STR R1, [R0]
+
+ BL EE_IRQ_end_instance ; IRQ Scheduler.
+
+; R0 = EE_std_endcycle_next_tid.
+ LDR R0, =EE_std_endcycle_next_tid
+ LDR R0, [R0]
+
+#ifdef __MONO__
+; #define EE_std_need_context_change(tid) ((tid) >= 0)
+ LDR R1, =TID_IS_STACKED_MARK
+ ANDS R0, R0, R1
+ CMP R0, #0
+ BNE EE_cortex_mx_pendsv_ISR_end
+#endif
+
+#ifdef __MULTI__
+ BL EE_std_need_context_change
+ CMP R0, #0
+ BEQ EE_cortex_mx_pendsv_ISR_end
+#endif
+
+; Build a stack frame to jump into the EE_std_change_context(EE_TID) at the end
+; of PendSV_Handler.
+
+; R0 = EE_std_endcycle_next_tid (R12)
+ LDR R0, =EE_std_endcycle_next_tid
+ LDR R0, [R0]
+
+; R3 = 0x01000000 (xPSR)
+ LDR R3, =EPSR_T_BIT_VAL
+
+; R2 = EE_cortex_mx_change_context (PC)
+ LDR R2, =EE_cortex_mx_change_context
+
+; R1 = exit_EE_cortex_mx_change_context (LR)
+ LDR R1, =EE_cortex_mx_change_context_return_point
+
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+ PUSH {R0-R3}
+
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 |
+ PUSH {R0-R3}
+
+;Fake IRQ handler frame on top of PendSV frame:
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 | <- MSP
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ BX R0 ; EXC_RETURN.
+
+EE_cortex_mx_pendsv_ISR_end:
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ CPSIE I ; Enable all interrupts.
+ BX R0 ; EXC_RETURN.
+
+;
+EE_cortex_mx_change_context_return_point:
+; Enable interrupts (clear PRIMASK)
+; NOTE: If SVC is executed when PRIMASK is set to 1, HardFault Exception will
+; occur. To solve this, instead of using PRIMASK to mask interrupts, use
+; BASEPRI to mask particular interrupts.
+ CPSIE I
+; SVCall exception to remove Original PendSV stack-frame.
+ SVC #0
+
+; void EE_cortex_mx_svc_ISR(void)
+SVC_Handler:
+
+; Remove SVCall Stack-Frame.
+ ADD SP, SP, #(8*4)
+
+ BX LR ; EXC_RETURN.
+
+ END
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_irq_stack.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_irq_stack.s
new file mode 100644
index 0000000..8e95cc9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_irq_stack.s
@@ -0,0 +1,91 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ @file ee_iar_irq_stack.s
+ @brief Context switch function for multistack on Cortex_MX
+ @brief Stack switch for ISRs on Cortex_MX.
+ Implementation of EE_cortex_mx_call_ISR_new_stack() as described in
+ pkg/cpu/cortex_mx/inc/ee_irq_internal.h
+ @author Gianluca Franchino
+ @author Giuseppe Serano
+ @date 2011
+*/
+
+;*******************************************************************************
+; DATA SECTION
+;*******************************************************************************
+ SECTION CHN_C_DATA : DATA:NOROOT (2)
+
+EE_cortex_mx_tmp_tos: DS32 1 ; EE_UREG EE_cortex_mx_tmp_tos;
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ SECTION CODE:CODE(2)
+
+ PUBLIC EE_cortex_mx_change_IRQ_stack
+ PUBLIC EE_cortex_mx_change_IRQ_stack_back
+
+ EXTERN EE_cortex_mx_IRQ_tos
+
+ THUMB
+
+;void EE_cortex_mx_change_IRQ_stack(void);
+
+EE_cortex_mx_change_IRQ_stack:
+ MRS R0, MSP ; R0 = MSP (Main stack Pointer)
+ LDR R1, =EE_cortex_mx_tmp_tos ; R1 = address of EE_cortex_m0_tmp_tos
+ STR R0, [R1] ; Save MSP in EE_cortex_mx_tmp_tos
+ LDR R0, =EE_cortex_mx_IRQ_tos; R0 = address of EE_cortex_mx_IRQ_tos
+ LDR R0, [R0] ; R0 = IRQ new stack pointer
+ MSR MSP, R0 ; change IRQ stack
+
+ BX LR ; return
+
+;void EE_cortex_mx_change_IRQ_stack_back(void);
+EE_cortex_mx_change_IRQ_stack_back:
+ LDR R0, =EE_cortex_mx_tmp_tos ; R0 = address of EE_cortex_mx_tmp_tos
+ LDR R0, [R0] ; R0 = old MSP
+ MSR MSP, R0 ; Restore the stack pointer
+
+ BX LR ; return
+
+ END
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_multi_context.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_multi_context.s
new file mode 100644
index 0000000..c82f9ac
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_multi_context.s
@@ -0,0 +1,174 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ @file ee_iar_multi_context.s
+ @brief Context switch function for multistack on Cortex_M0
+ Implementation of EE_cortex_mx_change_context as described in
+ pkg/cpu/common/inc/ee_context.h
+ @author Gianluca Franchino
+ @author Giuseppe Serano
+ @date 2011
+*/
+
+/*
+
+Pseudo code for EE_cortex_mx_change_context():
+ begin:
+ tos_index = EE_std_thread_tos[tid+1];
+ if is_not_the_current_stack(tos_index) {
+ save_caller_saved_registers();
+ switch_stacks(tos_index);
+ restore_caller_saved_registers();
+ }
+ if (is_not_marked_stacked(tid)) {
+ tid = EE_std_run_task_code(tid);
+ goto begin;
+ }
+*/
+
+ SECTION CODE:CODE(2)
+
+ PUBLIC EE_cortex_mx_change_context
+
+ EXTERN EE_std_run_task_code
+ EXTERN EE_std_thread_tos
+ EXTERN EE_cortex_mx_active_tos
+ EXTERN EE_cortex_mx_system_tos
+
+ THUMB
+
+;void EE_cortex_mx_change_context(EE_TID tid);
+EE_cortex_mx_change_context:
+ ; R0 == tid
+ ; tos_index = EE_std_thread_tos[tid+1];
+ ADDS R1, R0, #1 ; R1 = tid+1
+ LSLS R1, R1, #2 ; R1 = (tid+1)*4= correct offset in EE_std_thread_tos
+ ; The last shift, also gets rid of the `stacked' mark
+ LDR R2, =EE_std_thread_tos
+ ADD R1, R2, R1
+ LDR R1, [R1];R1 == tos_index
+
+ ;*
+ ;* if is_not_the_current_stack(tos_index) {
+ ;*
+ LDR R2, =EE_cortex_mx_active_tos ;R2 = & EE_cortex_mx_active_tos;
+ LDR R3, [R2] ; R3 = EE_cortex_mx_active_tos;
+ CMP R1, R3
+ BEQ end_change_stacks
+
+ ;save_caller_saved_registers();
+
+ ;Save all callee-saved registers
+ ;R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+
+ ;!!!!!!!!!!!!!!!
+ ; At this point the non scratch registers (R4...R11) are pushed into stack,
+ ; hence I can use them in the following.
+ ;!!!!!!!!!!!!!!!!
+
+ ; switch_stacks(tos_index);
+ LDR R4, =EE_cortex_mx_system_tos ; R4 = & cortex_mx_system_tos[0];
+ ; Note: although R4 is not a scratch register, it has been saved onto stack,
+ ; therefore we can used it in the follow without problem
+ ; EE_cortex_mx_system_tos[R3] = MSP;
+ LSLS R3, R3, #2
+ ADD R3, R4, R3
+ MRS R5, MSP
+ ; Note STR can only use the register range -> R0 to R4.
+ STR R5, [R3] ; save stack pointer
+
+ ; EE_cortex_mx_active_tos = tos_index;
+ STR R1, [R2]
+ ; MSP= EE_cortex_mx_system_tos[R1];
+ LSLS R1, R1, #2
+ ADD R1, R4, R1
+ LDR R1, [R1]
+ MSR MSP, R1
+ ; restore_caller_saved_registers();
+ POP {R1} ; Get link register from stack
+ MOV LR, R1 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ ; *
+ ; * }
+ ; *
+
+end_change_stacks:
+ ; R0 == tid
+
+ ; *
+ ; *if (is_not_marked_stacked(tid)) {
+ ; *
+
+ CMP R0, #0
+ BLT end_run_thread
+
+ ; tid = EE_std_run_task_code(tid);
+ PUSH {LR}
+ BL EE_std_run_task_code
+ ; R0 == tid
+ POP {R1}
+ MOV LR, R1
+
+ B EE_cortex_mx_change_context
+ ; goto begin
+
+ ; *
+ ; * }
+ ; *
+
+end_run_thread:
+
+ BX LR ; Return
+
+ END
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_oo.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_oo.s
new file mode 100644
index 0000000..2f80e7a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_iar_oo.s
@@ -0,0 +1,147 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+ /**
+ @file ee_iar_oo.S
+ @brief Functions to save and restore registers for Osek TerminateTask() on Cortex_m0
+ @author Gianluca Franchino
+ @author Giuseppe Serano
+ @date 2011
+*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ ; Functions declared in this file
+ PUBLIC EE_hal_terminate_savestk ; void EE_hal_terminate_savestk(EE_TID tid)
+ PUBLIC EE_hal_terminate_task ; NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+ EXTERN EE_terminate_real_th_body
+ EXTERN EE_terminate_data
+ EXTERN EE_thread_not_terminated
+
+;*******************************************************************************
+; EQUATES
+;*******************************************************************************
+EPSR_T_BIT_VAL EQU 0x01000000 ; Value to set the T-bit in EPSR (always Thumb mode)
+
+ SECTION CODE:CODE(2)
+ THUMB
+
+ ;void EE_hal_terminate_savestk(EE_TID tid);
+EE_hal_terminate_savestk:
+ ; Save all callee-saved registers
+ ; R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+ MRS R3, PSR ; Store xPSR to 8-bytes stack aligment
+ PUSH {R3}
+ ;R0 == tid
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, =EE_terminate_real_th_body ; R1 == EE_terminate_real_th_body[tid]
+ ADD R1, R1, R0
+ LDR R1, [R1]
+ ; Save the stack pointer (including space for registers)
+ ; R2 == & EE_terminate_data[tid]
+ LDR R2, =EE_terminate_data
+ ADD R2, R2, R0
+ MRS R3, MSP ; Get the stack pointer
+ STR R3, [R2] ; Save stack pointer
+
+ ;Start the thread body
+ BLX R1
+
+ ; The task terminated with a return: do the usual cleanup
+ LDR R0, =EE_thread_not_terminated
+ BLX R0
+
+ ; NOTE: code never executed because EE_thread_not_terminated()
+ POP {R2} ; Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR PSR, R2 ; Restore xPSR register
+ POP {R0} ; Get link register from stack
+ MOV LR, R0 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+
+ ;void EE_hal_terminate_task(EE_TID tid) NORETURN; */
+EE_hal_terminate_task:
+ ; R0 == tid
+
+ ; Restore the stack pointer
+ ; R1 == & EE_terminate_data[tid]
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, =EE_terminate_data ; R1 == & EE_terminate_data[tid]
+ ADD R1, R1, R0
+ LDR R2, [R1]
+ MSR MSP, R2
+
+ POP {R2} ; Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR PSR, R2 ; Restore xPSR register
+ POP {R3} ; Get link register from stack
+ MOV LR, R3 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+
+ END
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_change_context_isr.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_change_context_isr.s
new file mode 100644
index 0000000..e613a0c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_change_context_isr.s
@@ -0,0 +1,291 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2012 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+;/**
+; @file ee_keil_change_context_isr.s
+; @brief Functions to active and manage the context switch for Cortex-MX
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2012
+;*/
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+
+; void EE_switch_context(void);
+ EXPORT EE_switch_context
+
+ IF :DEF: __CORTEX_M0__
+
+; void EE_cortex_mx_pendsv_ISR(void);
+ EXPORT PendSV_Handler
+
+; void EE_cortex_mx_svc_ISR(void);
+ EXPORT SVC_Handler
+
+ ELSE
+
+; void EE_cortex_mx_pendsv_ISR(void);
+ EXPORT EE_cortex_mx_pendsv_ISR
+
+; void EE_cortex_mx_svc_ISR(void);
+ EXPORT EE_cortex_mx_svc_ISR
+
+ ENDIF
+
+; void EE_set_switch_context_pri(void);
+ EXPORT EE_set_switch_context_pri
+
+; EE_UREG EE_cortex_mx_change_context_active;
+; EXPORT EE_cortex_mx_change_context_active
+
+; void EE_IRQ_end_instance(void);
+ IMPORT EE_IRQ_end_instance
+
+; void EE_cortex_mx_change_context(EE_TID tid);
+ IMPORT EE_cortex_mx_change_context
+
+; EE_TID EE_std_endcycle_next_tid;
+ IMPORT EE_std_endcycle_next_tid
+
+ IF :DEF: __MULTI__
+; int EE_std_need_context_change(EE_TID tid);
+ IMPORT EE_std_need_context_change
+ ENDIF
+
+;*******************************************************************************
+; EQUATES
+;*******************************************************************************
+NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control status register
+NVIC_SHPR2 EQU 0xE000ED1C ; System priority register (SVCall 11)
+NVIC_SHPR3 EQU 0xE000ED20 ; System priority register (PendSV 14)
+NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority OR-value (Lowest)
+NVIC_SVCALL_PRI EQU 0x00FFFFFF ; SVCall priority AND-value (Highest)
+NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception
+NVIC_PENDSVCLR EQU 0x08000000 ; Value to un-trigger PendSV exception
+
+EPSR_T_BIT_VAL EQU 0x01000000 ; Value to set the T-bit in EPSR
+ ; (always Thumb mode)
+
+EXC_RETURN EQU 0xFFFFFFF9 ; No-FPU, Thread-Mode, MSP.
+
+ IF :DEF: __MONO__
+TID_IS_STACKED_MARK EQU 0x80000000
+ ENDIF
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+ PRESERVE8
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ AREA |.text|, CODE, READONLY
+ THUMB
+
+; void EE_set_switch_context_pri(void)
+EE_set_switch_context_pri FUNCTION
+
+;Set PendSV priority to the minumum one
+ LDR R0, =NVIC_SHPR3
+ LDR R1, =NVIC_PENDSV_PRI
+ LDR R2, [R0];
+ ORRS R2, R2, R1;
+ STR R2, [R0];
+
+;Set SVCall priority to the maximum one
+ LDR R0, =NVIC_SHPR2
+ LDR R1, =NVIC_SVCALL_PRI
+ LDR R2, [R0];
+ ANDS R2, R2, R1;
+ STR R2, [R0];
+
+ BX LR
+
+ ENDFUNC
+
+; void EE_switch_context(void)
+EE_switch_context FUNCTION
+
+; Trigger the PendSV exception (causes context switch)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVSET
+ STR R1, [R0]
+ BX LR
+
+ ENDFUNC
+
+; void EE_cortex_mx_pendsv_ISR(void)
+ IF :DEF: __CORTEX_M0__
+PendSV_Handler FUNCTION
+ ELSE
+EE_cortex_mx_pendsv_ISR FUNCTION
+ ENDIF
+
+ CPSID I ; Disable all interrupts (set PRIMASK).
+
+; Clear the PendSV exception (preventing 2nd triggering)
+ LDR R0, =NVIC_INT_CTRL
+ LDR R1, =NVIC_PENDSVCLR
+ STR R1, [R0]
+
+ BL EE_IRQ_end_instance ; IRQ Scheduler.
+
+; R0 = EE_std_endcycle_next_tid.
+ LDR R0, =EE_std_endcycle_next_tid
+ LDR R0, [R0]
+
+ IF :DEF: __MONO__
+; #define EE_std_need_context_change(tid) ((tid) >= 0)
+ LDR R1, =TID_IS_STACKED_MARK
+ ANDS R0, R0, R1
+ IF :DEF: __CORTEX_M0__
+ CMP R0, #0
+ BNE EE_cortex_mx_pendsv_ISR_end
+ ELSE
+ CBNZ R0, EE_cortex_mx_pendsv_ISR_end
+ ENDIF
+ ENDIF
+
+ IF :DEF: __MULTI__
+ BL EE_std_need_context_change
+ IF :DEF: __CORTEX_M0__
+ CMP R0, #0
+ BNE EE_cortex_mx_pendsv_ISR_continue
+ B EE_cortex_mx_pendsv_ISR_end
+EE_cortex_mx_pendsv_ISR_continue
+ ELSE
+ CBZ R0, EE_cortex_mx_pendsv_ISR_end
+ ENDIF
+ ENDIF
+
+; Build a stack frame to jump into the EE_std_change_context(EE_TID) at the end
+; of PendSV_Handler.
+
+; R0 = EE_std_endcycle_next_tid (R12)
+ LDR R0, =EE_std_endcycle_next_tid
+ LDR R0, [R0]
+
+; R3 = 0x01000000 (xPSR)
+ LDR R3, =EPSR_T_BIT_VAL
+
+; R2 = EE_cortex_mx_change_context (PC)
+ LDR R2, =EE_cortex_mx_change_context
+
+; R1 = exit_EE_cortex_mx_change_context (LR)
+ LDR R1, =EE_cortex_mx_change_context_return_point
+
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+ PUSH {R0-R3}
+
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 |
+ PUSH {R0-R3}
+
+;Fake IRQ handler frame on top of PendSV frame:
+;|xPSR|-> xPSR AND 0xFFFFFE0
+;| PC |-> EE_cortex_mx_change_context
+;| LR |-> EE_cortex_mx_change_context_return_point
+;| R12|
+;| R3 |
+;| R2 |
+;| R1 |
+;| R0 | <- MSP
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ BX R0 ; EXC_RETURN.
+
+EE_cortex_mx_pendsv_ISR_end
+; R0 = EXC_RETURN -> Return to Thread mode.
+; -> Exception return gets state from MSP.
+; -> Execution uses MSP after return.
+ LDR R0, =EXC_RETURN
+ CPSIE I ; Enable all interrupts.
+ BX R0 ; EXC_RETURN.
+
+ ENDFUNC
+
+EE_cortex_mx_change_context_return_point FUNCTION
+; Enable interrupts (clear PRIMASK)
+; NOTE: If SVC is executed when PRIMASK is set to 1, HardFault Exception will
+; occur. To solve this, instead of using PRIMASK to mask interrupts, use
+; BASEPRI to mask particular interrupts.
+ CPSIE I
+; SVCall exception to remove Original PendSV stack-frame.
+ SVC #0
+ ENDFUNC
+
+; void EE_cortex_mx_svc_ISR(void)
+ IF :DEF: __CORTEX_M0__
+SVC_Handler FUNCTION
+ ELSE
+EE_cortex_mx_svc_ISR FUNCTION
+ ENDIF
+; Remove SVCall Stack-Frame.
+ ADD SP, SP, #(8*4)
+
+ BX LR ; EXC_RETURN.
+ ENDFUNC
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ END
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_irq_stack.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_irq_stack.s
new file mode 100644
index 0000000..8d87de2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_irq_stack.s
@@ -0,0 +1,111 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; /**
+; @file ee_keil_irq_stack.s
+; @brief Context switch function for multistack on Cortex_MX
+; @brief Stack switch for ISRs on Cortex_MX.
+; Implementation of EE_cortex_mx_call_ISR_new_stack() as described in
+; pkg/cpu/cortex_mx/inc/ee_irq_internal.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+; */
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ EXPORT EE_cortex_mx_change_IRQ_stack
+ EXPORT EE_cortex_mx_change_IRQ_stack_back
+
+ IMPORT EE_cortex_mx_IRQ_tos
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+ PRESERVE8
+
+;*******************************************************************************
+; DATA SECTION
+;*******************************************************************************
+ AREA |.data|, READWRITE, ALIGN=3
+EE_cortex_mx_tmp_tos DCD 0 ; EE_UREG EE_cortex_mx_tmp_tos;
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ AREA |.text|, CODE, READONLY
+ THUMB
+
+;void EE_cortex_mx_change_IRQ_stack(void);
+EE_cortex_mx_change_IRQ_stack
+ MRS R0, MSP ; R0 = MSP (Main stack Pointer)
+ LDR R1, =EE_cortex_mx_tmp_tos ; R1 = address of EE_cortex_m0_tmp_tos
+ STR R0, [R1] ; Save MSP in EE_cortex_mx_tmp_tos
+ LDR R0, =EE_cortex_mx_IRQ_tos; R0 = address of EE_cortex_mx_IRQ_tos
+ LDR R0, [R0] ; R0 = IRQ new stack pointer
+ MSR MSP, R0 ; change IRQ stack
+
+ BX LR ; return
+
+;void EE_cortex_mx_change_IRQ_stack_back(void);
+EE_cortex_mx_change_IRQ_stack_back
+ LDR R0, =EE_cortex_mx_tmp_tos ; R0 = address of EE_cortex_mx_tmp_tos
+ LDR R0, [R0] ; R0 = old MSP
+ MSR MSP, R0 ; Restore the stack pointer
+
+ BX LR ; return
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ END
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_multi_context.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_multi_context.s
new file mode 100644
index 0000000..7b269d0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_multi_context.s
@@ -0,0 +1,196 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; /**
+; @file ee_keil_multi_context.s
+; @brief Context switch function for multistack on Cortex MX
+; Implementation of EE_cortex_mx_change_context as described in
+; pkg/cpu/common/inc/ee_context.h
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+; */
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ EXPORT EE_cortex_mx_change_context
+
+ IMPORT EE_std_run_task_code
+ IMPORT EE_std_thread_tos
+ IMPORT EE_cortex_mx_active_tos
+ IMPORT EE_cortex_mx_system_tos
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+ PRESERVE8
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ AREA |.text|, CODE, READONLY
+ THUMB
+
+;Pseudo code for EE_cortex_mx_change_context():
+; begin:
+; tos_index = EE_std_thread_tos[tid+1];
+; if is_not_the_current_stack(tos_index) {
+; save_caller_saved_registers();
+; switch_stacks(tos_index);
+; restore_caller_saved_registers();
+; }
+; if (is_not_marked_stacked(tid)) {
+; tid = EE_std_run_task_code(tid);
+; goto begin;
+; }
+;
+;void EE_cortex_mx_change_context(EE_TID tid);
+EE_cortex_mx_change_context
+ ; R0 == tid
+ ; tos_index = EE_std_thread_tos[tid+1];
+ ADDS R1, R0, #1 ; R1 = tid+1
+ LSLS R1, R1, #2 ; R1 = (tid+1)*4= correct offset in EE_std_thread_tos
+ ; The last shift, also gets rid of the `stacked' mark
+ LDR R2, =EE_std_thread_tos
+ ADD R1, R2, R1
+ LDR R1, [R1] ;R1 == tos_index
+
+ ;*
+ ;* if is_not_the_current_stack(tos_index) {
+ ;*
+ LDR R2, =EE_cortex_mx_active_tos ;R2 = & EE_cortex_mx_active_tos;
+ LDR R3, [R2] ; R3 = EE_cortex_mx_active_tos;
+ CMP R1, R3
+ BEQ end_change_stacks
+
+ ;save_caller_saved_registers();
+
+ ;Save all callee-saved registers
+ ;R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+
+ ;!!!!!!!!!!!!!!!
+ ; At this point the non scratch registers (R4...R11) are pushed into stack,
+ ; hence I can use them in the following.
+ ;!!!!!!!!!!!!!!!!
+
+ ; switch_stacks(tos_index);
+ LDR R4, =EE_cortex_mx_system_tos ; R4 = & cortex_mx_system_tos[0];
+ ; Note: although R4 is not a scratch register, it has been saved onto stack,
+ ; therefore we can used it in the follow without problem
+ ; EE_cortex_mx_system_tos[R3] = MSP;
+ LSLS R3, R3, #2
+ ADD R3, R4, R3
+ MRS R5, MSP
+ ; Note STR can only use the register range -> R0 to R4.
+ STR R5, [R3] ; save stack pointer
+
+ ; EE_cortex_mx_active_tos = tos_index;
+ STR R1, [R2]
+ ; MSP= EE_cortex_mx_system_tos[R1];
+ LSLS R1, R1, #2
+ ADD R1, R4, R1
+ LDR R1, [R1]
+ MSR MSP, R1
+ ; restore_caller_saved_registers();
+ POP {R1} ; Get link register from stack
+ MOV LR, R1 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+ ; *
+ ; * }
+ ; *
+
+end_change_stacks
+ ; R0 == tid
+
+ ; *
+ ; *if (is_not_marked_stacked(tid)) {
+ ; *
+
+ CMP R0, #0
+ BLT end_run_thread
+
+ ; tid = EE_std_run_task_code(tid);
+ PUSH {LR}
+ BL EE_std_run_task_code
+ ; R0 == tid
+ POP {R1}
+ MOV LR, R1
+
+ B EE_cortex_mx_change_context
+ ; goto begin
+
+ ; *
+ ; * }
+ ; *
+
+end_run_thread
+
+ BX LR ; Return
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ END
+
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_oo.s b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_oo.s
new file mode 100644
index 0000000..479bb5e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_keil_oo.s
@@ -0,0 +1,171 @@
+; ###*B*###
+; ERIKA Enterprise - a tiny RTOS for small microcontrollers
+;
+; Copyright (C) 2002-2011 Evidence Srl
+;
+; This file is part of ERIKA Enterprise.
+;
+; ERIKA Enterprise is free software; you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; version 2 as published by the Free Software Foundation,
+; (with a special exception described below).
+;
+; Linking this code statically or dynamically with other modules is
+; making a combined work based on this code. Thus, the terms and
+; conditions of the GNU General Public License cover the whole
+; combination.
+;
+; As a special exception, the copyright holders of this library give you
+; permission to link this code with independent modules to produce an
+; executable, regardless of the license terms of these independent
+; modules, and to copy and distribute the resulting executable under
+; terms of your choice, provided that you also meet, for each linked
+; independent module, the terms and conditions of the license of that
+; module. An independent module is a module which is not derived from
+; or based on this library. If you modify this code, you may extend
+; this exception to your version of the code, but you are not
+; obligated to do so. If you do not wish to do so, delete this
+; exception statement from your version.
+;
+; ERIKA Enterprise is distributed in the hope that it will be
+; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License version 2 for more details.
+;
+; You should have received a copy of the GNU General Public License
+; version 2 along with ERIKA Enterprise; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+; Boston, MA 02110-1301 USA.
+; ###*E*###
+
+; /**
+; @file ee_keil_oo.S
+; @brief Functions to save and restore registers for OSEK TerminateTask().
+; @author Gianluca Franchino
+; @author Giuseppe Serano
+; @date 2011
+; */
+
+;*******************************************************************************
+; PUBLIC FUNCTIONS
+;*******************************************************************************
+ ; Functions declared in this file
+ EXPORT EE_hal_terminate_savestk ; void EE_hal_terminate_savestk(EE_TID tid)
+ EXPORT EE_hal_terminate_task ; NORETURN void EE_hal_terminate_task(EE_TID tid);
+
+ IMPORT EE_terminate_real_th_body
+ IMPORT EE_terminate_data
+ IMPORT EE_thread_not_terminated
+
+;*******************************************************************************
+; EQUATES
+;*******************************************************************************
+EPSR_T_BIT_VAL EQU 0x01000000 ; Value to set the T-bit in EPSR (always Thumb mode)
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+ PRESERVE8
+
+;*******************************************************************************
+; CODE SECTION
+;*******************************************************************************
+ AREA |.text|, CODE, READONLY
+ THUMB
+
+;void EE_hal_terminate_savestk(EE_TID tid);
+EE_hal_terminate_savestk FUNCTION
+ ; Save all callee-saved registers
+ ; R0-R3 and R12 are scratch registers, R13 ->(MSP), R14 ->(LR), R15 -> (PC)
+ PUSH {R4-R7} ; Store R4, R5, R6, R7 onto stack
+ MOV R4, R8
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ PUSH {R4-R7} ; Store R8, R9, R10, R11 onto stack
+ PUSH {LR} ; Store link register (return address)
+ MRS R3, PSR ; Store xPSR to 8-bytes stack aligment
+ PUSH {R3}
+ ;R0 == tid
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, =EE_terminate_real_th_body ; R1 == EE_terminate_real_th_body[tid]
+ ADD R1, R1, R0
+ LDR R1, [R1]
+ ; Save the stack pointer (including space for registers)
+ ; R2 == & EE_terminate_data[tid]
+ LDR R2, =EE_terminate_data
+ ADD R2, R2, R0
+ MRS R3, MSP ; Get the stack pointer
+ STR R3, [R2] ; Save stack pointer
+
+ ;Start the thread body
+ BLX R1
+
+ ; The task terminated with a return: do the usual cleanup
+ LDR R0, =EE_thread_not_terminated
+ BLX R0
+
+ ; NOTE: code never executed because EE_thread_not_terminated()
+ POP {R2} ; Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR PSR, R2 ; Restore xPSR register
+ POP {R0} ; Get link register from stack
+ MOV LR, R0 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+ ENDFUNC
+
+;void EE_hal_terminate_task(EE_TID tid) /* NORETURN; */
+EE_hal_terminate_task FUNCTION
+ ; R0 == tid
+
+ ; Restore the stack pointer
+ ; R1 == & EE_terminate_data[tid]
+ LSLS R0, R0, #2 ; R0 = tid << 2
+ LDR R1, =EE_terminate_data ; R1 == & EE_terminate_data[tid]
+ ADD R1, R1, R0
+ LDR R2, [R1]
+ MSR MSP, R2
+
+ POP {R2} ; Get xPSR from stack
+ LDR R0, =EPSR_T_BIT_VAL ; R0 = 0x01000000
+ ORRS R2, R2, R0 ; R2 = (xPSR OR 0x01000000). This guarantees that Thumbs bit is set
+ ; to avoid an hard_fault exception
+ MSR PSR, R2 ; Restore xPSR register
+ POP {R3} ; Get link register from stack
+ MOV LR, R3 ; Restore the link register
+ ; Restore R8, R9, R10, R11 from stack
+ POP {R4-R7}
+ MOV R8, R4
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+ POP {R4-R7} ; Restore R4, R5, R6, R7 from stack
+
+ BX LR ; Return
+ ENDFUNC
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ END
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_system_timer.c b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_system_timer.c
new file mode 100644
index 0000000..f379f90
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_system_timer.c
@@ -0,0 +1,85 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2012 Errico Guidieri
+ */
+
+#include <ee.h>
+#include <ee_irq.h>
+#include <ee_internal.h>
+
+/* This file is needed only if System Timer is defined */
+#if (defined(ENABLE_SYSTEM_TIMER) && defined(EE_SYSTEM_TIMER_DEVICE))
+
+/* Legit devices as system timer */
+#define EE_CORTEX_MX_SYSTICK 1
+
+/* Used for compiler error */
+#define PREPROC(s) s
+
+/* System Timer Handler */
+ISR(EE_cortex_system_timer_handler){
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || \
+ defined(__OO_ECC2__) || defined(__AS_SC4__)
+ IncrementCounterHardware(EE_SYSTEM_TIMER);
+#else
+ CounterTick(EE_SYSTEM_TIMER);
+#endif
+}
+
+/* System Timer Initialization */
+void EE_cortex_mx_initialize_system_timer(void)
+{
+#if (EE_SYSTEM_TIMER_DEVICE == EE_CORTEX_MX_SYSTICK)
+ /* OSTICKDURATION is defined as nanoseconds macro */
+ EE_systick_set_period(MICROSECONDS_TO_TICKS(
+ (OSTICKDURATION / 1000U),
+ EE_CPU_CLOCK)
+ );
+ EE_systick_enable_int();
+ EE_systick_start();
+#else
+#error Unsupported Device: PREPROC(EE_SYSTEM_TIMER_DEVICE) as \
+ System Timer !
+#endif
+}
+
+#endif /* ENABLE_SYSTEM_TIMER */
diff --git a/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_utils.c b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_utils.c
new file mode 100644
index 0000000..aa348d6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/cpu/cortex_mx/src/ee_utils.c
@@ -0,0 +1,1145 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @file ee_utils.c
+ * @brief Functions to initialize the RTOS services
+ * @author Gianluca Franchino
+ * @author Giuseppe Serano
+ * @date 2011
+ */
+
+#include "ee_internal.h"
+#include "ee_irq.h"
+/* ~ #include "cpu/cortex_mx/inc/ee_nvic.h" */
+
+extern void EE_set_switch_context_pri(void);
+
+/* Function used to calculate the initialize the system */
+void EE_system_init(void)
+{
+ register EE_UREG flags;
+
+ flags = EE_hal_suspendIRQ();
+
+ /*
+ * Set the priority of PendSV to the minimum one
+ * PendSV is the software interrupt used for context switch
+ */
+ EE_set_switch_context_pri();
+
+#ifdef __CORTEX_MX__
+
+#ifdef EE_CORTEX_MX_SYSTICK_ISR
+#ifdef EE_CORTEX_MX_SYSTICK_ISR_PRI
+ NVIC_SYS_PRI3_R |= (
+ EE_CORTEX_MX_SYSTICK_ISR_PRI << NVIC_SYS_PRI3_TICK_S
+ );
+#endif
+#endif
+
+#ifdef EE_CORTEX_MX_INT_00_ISR
+#ifdef EE_CORTEX_MX_INT_00_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_00_NUM, EE_CORTEX_MX_INT_00_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_00_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_00_NUM);
+#endif /* EE_CORTEX_MX_INT_00_ISR */
+
+#ifdef EE_CORTEX_MX_INT_01_ISR
+#ifdef EE_CORTEX_MX_INT_01_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_01_NUM, EE_CORTEX_MX_INT_01_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_01_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_01_NUM);
+#endif /* EE_CORTEX_MX_INT_01_ISR */
+
+#ifdef EE_CORTEX_MX_INT_02_ISR
+#ifdef EE_CORTEX_MX_INT_02_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_02_NUM, EE_CORTEX_MX_INT_02_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_02_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_02_NUM);
+#endif /* EE_CORTEX_MX_INT_02_ISR */
+
+#ifdef EE_CORTEX_MX_INT_03_ISR
+#ifdef EE_CORTEX_MX_INT_03_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_03_NUM, EE_CORTEX_MX_INT_03_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_03_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_03_NUM);
+#endif /* EE_CORTEX_MX_INT_03_ISR */
+
+#ifdef EE_CORTEX_MX_INT_04_ISR
+#ifdef EE_CORTEX_MX_INT_04_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_04_NUM, EE_CORTEX_MX_INT_04_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_04_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_04_NUM);
+#endif /* EE_CORTEX_MX_INT_04_ISR */
+
+#ifdef EE_CORTEX_MX_INT_05_ISR
+#ifdef EE_CORTEX_MX_INT_05_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_05_NUM, EE_CORTEX_MX_INT_05_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_05_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_05_NUM);
+#endif /* EE_CORTEX_MX_INT_05_ISR */
+
+#ifdef EE_CORTEX_MX_INT_06_ISR
+#ifdef EE_CORTEX_MX_INT_06_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_06_NUM, EE_CORTEX_MX_INT_06_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_06_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_06_NUM);
+#endif /* EE_CORTEX_MX_INT_06_ISR */
+
+#ifdef EE_CORTEX_MX_INT_07_ISR
+#ifdef EE_CORTEX_MX_INT_07_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_07_NUM, EE_CORTEX_MX_INT_07_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_07_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_07_NUM);
+#endif /* EE_CORTEX_MX_INT_07_ISR */
+
+#ifdef EE_CORTEX_MX_INT_08_ISR
+#ifdef EE_CORTEX_MX_INT_08_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_08_NUM, EE_CORTEX_MX_INT_08_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_08_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_08_NUM);
+#endif /* EE_CORTEX_MX_INT_08_ISR */
+
+#ifdef EE_CORTEX_MX_INT_09_ISR
+#ifdef EE_CORTEX_MX_INT_09_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_09_NUM, EE_CORTEX_MX_INT_09_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_09_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_09_NUM);
+#endif /* EE_CORTEX_MX_INT_09_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0A_ISR
+#ifdef EE_CORTEX_MX_INT_0A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0A_NUM, EE_CORTEX_MX_INT_0A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0A_NUM);
+#endif /* EE_CORTEX_MX_INT_0A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0B_ISR
+#ifdef EE_CORTEX_MX_INT_0B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0B_NUM, EE_CORTEX_MX_INT_0B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0B_NUM);
+#endif /* EE_CORTEX_MX_INT_0B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0C_ISR
+#ifdef EE_CORTEX_MX_INT_0C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0C_NUM, EE_CORTEX_MX_INT_0C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0C_NUM);
+#endif /* EE_CORTEX_MX_INT_0C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0D_ISR
+#ifdef EE_CORTEX_MX_INT_0D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0D_NUM, EE_CORTEX_MX_INT_0D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0D_NUM);
+#endif /* EE_CORTEX_MX_INT_0D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0E_ISR
+#ifdef EE_CORTEX_MX_INT_0E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0E_NUM, EE_CORTEX_MX_INT_0E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0E_NUM);
+#endif /* EE_CORTEX_MX_INT_0E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_0F_ISR
+#ifdef EE_CORTEX_MX_INT_0F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_0F_NUM, EE_CORTEX_MX_INT_0F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_0F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_0F_NUM);
+#endif /* EE_CORTEX_MX_INT_0F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_10_ISR
+#ifdef EE_CORTEX_MX_INT_10_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_10_NUM, EE_CORTEX_MX_INT_10_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_10_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_10_NUM);
+#endif /* EE_CORTEX_MX_INT_10_ISR */
+
+#ifdef EE_CORTEX_MX_INT_11_ISR
+#ifdef EE_CORTEX_MX_INT_11_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_11_NUM, EE_CORTEX_MX_INT_11_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_11_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_11_NUM);
+#endif /* EE_CORTEX_MX_INT_11_ISR */
+
+#ifdef EE_CORTEX_MX_INT_12_ISR
+#ifdef EE_CORTEX_MX_INT_12_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_12_NUM, EE_CORTEX_MX_INT_12_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_12_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_12_NUM);
+#endif /* EE_CORTEX_MX_INT_12_ISR */
+
+#ifdef EE_CORTEX_MX_INT_13_ISR
+#ifdef EE_CORTEX_MX_INT_13_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_13_NUM, EE_CORTEX_MX_INT_13_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_13_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_13_NUM);
+#endif /* EE_CORTEX_MX_INT_13_ISR */
+
+#ifdef EE_CORTEX_MX_INT_14_ISR
+#ifdef EE_CORTEX_MX_INT_14_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_14_NUM, EE_CORTEX_MX_INT_14_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_14_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_14_NUM);
+#endif /* EE_CORTEX_MX_INT_14_ISR */
+
+#ifdef EE_CORTEX_MX_INT_15_ISR
+#ifdef EE_CORTEX_MX_INT_15_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_15_NUM, EE_CORTEX_MX_INT_15_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_15_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_15_NUM);
+#endif /* EE_CORTEX_MX_INT_15_ISR */
+
+#ifdef EE_CORTEX_MX_INT_16_ISR
+#ifdef EE_CORTEX_MX_INT_16_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_16_NUM, EE_CORTEX_MX_INT_16_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_16_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_16_NUM);
+#endif /* EE_CORTEX_MX_INT_16_ISR */
+
+#ifdef EE_CORTEX_MX_INT_17_ISR
+#ifdef EE_CORTEX_MX_INT_17_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_17_NUM, EE_CORTEX_MX_INT_17_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_17_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_17_NUM);
+#endif /* EE_CORTEX_MX_INT_17_ISR */
+
+#ifdef EE_CORTEX_MX_INT_18_ISR
+#ifdef EE_CORTEX_MX_INT_18_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_18_NUM, EE_CORTEX_MX_INT_18_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_18_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_18_NUM);
+#endif /* EE_CORTEX_MX_INT_18_ISR */
+
+#ifdef EE_CORTEX_MX_INT_19_ISR
+#ifdef EE_CORTEX_MX_INT_19_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_19_NUM, EE_CORTEX_MX_INT_19_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_19_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_19_NUM);
+#endif /* EE_CORTEX_MX_INT_19_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1A_ISR
+#ifdef EE_CORTEX_MX_INT_1A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1A_NUM, EE_CORTEX_MX_INT_1A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1A_NUM);
+#endif /* EE_CORTEX_MX_INT_1A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1B_ISR
+#ifdef EE_CORTEX_MX_INT_1B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1B_NUM, EE_CORTEX_MX_INT_1B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1B_NUM);
+#endif /* EE_CORTEX_MX_INT_1B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1C_ISR
+#ifdef EE_CORTEX_MX_INT_1C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1C_NUM, EE_CORTEX_MX_INT_1C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1C_NUM);
+#endif /* EE_CORTEX_MX_INT_1C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1D_ISR
+#ifdef EE_CORTEX_MX_INT_1D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1D_NUM, EE_CORTEX_MX_INT_1D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1D_NUM);
+#endif /* EE_CORTEX_MX_INT_1D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1E_ISR
+#ifdef EE_CORTEX_MX_INT_1E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1E_NUM, EE_CORTEX_MX_INT_1E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1E_NUM);
+#endif /* EE_CORTEX_MX_INT_1E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_1F_ISR
+#ifdef EE_CORTEX_MX_INT_1F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_1F_NUM, EE_CORTEX_MX_INT_1F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_1F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_1F_NUM);
+#endif /* EE_CORTEX_MX_INT_1F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_20_ISR
+#ifdef EE_CORTEX_MX_INT_20_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_20_NUM, EE_CORTEX_MX_INT_20_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_20_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_20_NUM);
+#endif /* EE_CORTEX_MX_INT_20_ISR */
+
+#ifdef EE_CORTEX_MX_INT_21_ISR
+#ifdef EE_CORTEX_MX_INT_21_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_21_NUM, EE_CORTEX_MX_INT_21_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_21_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_21_NUM);
+#endif /* EE_CORTEX_MX_INT_21_ISR */
+
+#ifdef EE_CORTEX_MX_INT_22_ISR
+#ifdef EE_CORTEX_MX_INT_22_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_22_NUM, EE_CORTEX_MX_INT_22_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_22_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_22_NUM);
+#endif /* EE_CORTEX_MX_INT_22_ISR */
+
+#ifdef EE_CORTEX_MX_INT_23_ISR
+#ifdef EE_CORTEX_MX_INT_23_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_23_NUM, EE_CORTEX_MX_INT_23_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_23_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_23_NUM);
+#endif /* EE_CORTEX_MX_INT_23_ISR */
+
+#ifdef EE_CORTEX_MX_INT_24_ISR
+#ifdef EE_CORTEX_MX_INT_24_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_24_NUM, EE_CORTEX_MX_INT_24_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_24_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_24_NUM);
+#endif /* EE_CORTEX_MX_INT_24_ISR */
+
+#ifdef EE_CORTEX_MX_INT_25_ISR
+#ifdef EE_CORTEX_MX_INT_25_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_25_NUM, EE_CORTEX_MX_INT_25_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_25_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_25_NUM);
+#endif /* EE_CORTEX_MX_INT_25_ISR */
+
+#ifdef EE_CORTEX_MX_INT_26_ISR
+#ifdef EE_CORTEX_MX_INT_26_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_26_NUM, EE_CORTEX_MX_INT_26_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_26_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_26_NUM);
+#endif /* EE_CORTEX_MX_INT_26_ISR */
+
+#ifdef EE_CORTEX_MX_INT_27_ISR
+#ifdef EE_CORTEX_MX_INT_27_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_27_NUM, EE_CORTEX_MX_INT_27_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_27_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_27_NUM);
+#endif /* EE_CORTEX_MX_INT_27_ISR */
+
+#ifdef EE_CORTEX_MX_INT_28_ISR
+#ifdef EE_CORTEX_MX_INT_28_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_28_NUM, EE_CORTEX_MX_INT_28_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_28_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_28_NUM);
+#endif /* EE_CORTEX_MX_INT_28_ISR */
+
+#ifdef EE_CORTEX_MX_INT_29_ISR
+#ifdef EE_CORTEX_MX_INT_29_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_29_NUM, EE_CORTEX_MX_INT_29_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_29_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_29_NUM);
+#endif /* EE_CORTEX_MX_INT_29_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2A_ISR
+#ifdef EE_CORTEX_MX_INT_2A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2A_NUM, EE_CORTEX_MX_INT_2A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2A_NUM);
+#endif /* EE_CORTEX_MX_INT_2A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2B_ISR
+#ifdef EE_CORTEX_MX_INT_2B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2B_NUM, EE_CORTEX_MX_INT_2B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2B_NUM);
+#endif /* EE_CORTEX_MX_INT_2B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2C_ISR
+#ifdef EE_CORTEX_MX_INT_2C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2C_NUM, EE_CORTEX_MX_INT_2C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2C_NUM);
+#endif /* EE_CORTEX_MX_INT_2C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2D_ISR
+#ifdef EE_CORTEX_MX_INT_2D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2D_NUM, EE_CORTEX_MX_INT_2D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2D_NUM);
+#endif /* EE_CORTEX_MX_INT_2D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2E_ISR
+#ifdef EE_CORTEX_MX_INT_2E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2E_NUM, EE_CORTEX_MX_INT_2E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2E_NUM);
+#endif /* EE_CORTEX_MX_INT_2E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_2F_ISR
+#ifdef EE_CORTEX_MX_INT_2F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_2F_NUM, EE_CORTEX_MX_INT_2F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_2F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_2F_NUM);
+#endif /* EE_CORTEX_MX_INT_2F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_30_ISR
+#ifdef EE_CORTEX_MX_INT_30_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_30_NUM, EE_CORTEX_MX_INT_30_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_30_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_30_NUM);
+#endif /* EE_CORTEX_MX_INT_30_ISR */
+
+#ifdef EE_CORTEX_MX_INT_31_ISR
+#ifdef EE_CORTEX_MX_INT_31_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_31_NUM, EE_CORTEX_MX_INT_31_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_31_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_31_NUM);
+#endif /* EE_CORTEX_MX_INT_31_ISR */
+
+#ifdef EE_CORTEX_MX_INT_32_ISR
+#ifdef EE_CORTEX_MX_INT_32_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_32_NUM, EE_CORTEX_MX_INT_32_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_32_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_32_NUM);
+#endif /* EE_CORTEX_MX_INT_32_ISR */
+
+#ifdef EE_CORTEX_MX_INT_33_ISR
+#ifdef EE_CORTEX_MX_INT_33_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_33_NUM, EE_CORTEX_MX_INT_33_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_33_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_33_NUM);
+#endif /* EE_CORTEX_MX_INT_33_ISR */
+
+#ifdef EE_CORTEX_MX_INT_34_ISR
+#ifdef EE_CORTEX_MX_INT_34_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_34_NUM, EE_CORTEX_MX_INT_34_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_34_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_34_NUM);
+#endif /* EE_CORTEX_MX_INT_34_ISR */
+
+#ifdef EE_CORTEX_MX_INT_35_ISR
+#ifdef EE_CORTEX_MX_INT_35_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_35_NUM, EE_CORTEX_MX_INT_35_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_35_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_35_NUM);
+#endif /* EE_CORTEX_MX_INT_35_ISR */
+
+#ifdef EE_CORTEX_MX_INT_36_ISR
+#ifdef EE_CORTEX_MX_INT_36_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_36_NUM, EE_CORTEX_MX_INT_36_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_36_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_36_NUM);
+#endif /* EE_CORTEX_MX_INT_36_ISR */
+
+#ifdef EE_CORTEX_MX_INT_37_ISR
+#ifdef EE_CORTEX_MX_INT_37_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_37_NUM, EE_CORTEX_MX_INT_37_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_37_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_37_NUM);
+#endif /* EE_CORTEX_MX_INT_37_ISR */
+
+#ifdef EE_CORTEX_MX_INT_38_ISR
+#ifdef EE_CORTEX_MX_INT_38_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_38_NUM, EE_CORTEX_MX_INT_38_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_38_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_38_NUM);
+#endif /* EE_CORTEX_MX_INT_38_ISR */
+
+#ifdef EE_CORTEX_MX_INT_39_ISR
+#ifdef EE_CORTEX_MX_INT_39_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_39_NUM, EE_CORTEX_MX_INT_39_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_39_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_39_NUM);
+#endif /* EE_CORTEX_MX_INT_39_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3A_ISR
+#ifdef EE_CORTEX_MX_INT_3A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3A_NUM, EE_CORTEX_MX_INT_3A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3A_NUM);
+#endif /* EE_CORTEX_MX_INT_3A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3B_ISR
+#ifdef EE_CORTEX_MX_INT_3B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3B_NUM, EE_CORTEX_MX_INT_3B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3B_NUM);
+#endif /* EE_CORTEX_MX_INT_3B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3C_ISR
+#ifdef EE_CORTEX_MX_INT_3C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3C_NUM, EE_CORTEX_MX_INT_3C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3C_NUM);
+#endif /* EE_CORTEX_MX_INT_3C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3D_ISR
+#ifdef EE_CORTEX_MX_INT_3D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3D_NUM, EE_CORTEX_MX_INT_3D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3D_NUM);
+#endif /* EE_CORTEX_MX_INT_3D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3E_ISR
+#ifdef EE_CORTEX_MX_INT_3E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3E_NUM, EE_CORTEX_MX_INT_3E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3E_NUM);
+#endif /* EE_CORTEX_MX_INT_3E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_3F_ISR
+#ifdef EE_CORTEX_MX_INT_3F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_3F_NUM, EE_CORTEX_MX_INT_3F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_3F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_3F_NUM);
+#endif /* EE_CORTEX_MX_INT_3F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_40_ISR
+#ifdef EE_CORTEX_MX_INT_40_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_40_NUM, EE_CORTEX_MX_INT_40_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_40_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_40_NUM);
+#endif /* EE_CORTEX_MX_INT_40_ISR */
+
+#ifdef EE_CORTEX_MX_INT_41_ISR
+#ifdef EE_CORTEX_MX_INT_41_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_41_NUM, EE_CORTEX_MX_INT_41_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_41_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_41_NUM);
+#endif /* EE_CORTEX_MX_INT_41_ISR */
+
+#ifdef EE_CORTEX_MX_INT_42_ISR
+#ifdef EE_CORTEX_MX_INT_42_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_42_NUM, EE_CORTEX_MX_INT_42_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_42_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_42_NUM);
+#endif /* EE_CORTEX_MX_INT_42_ISR */
+
+#ifdef EE_CORTEX_MX_INT_43_ISR
+#ifdef EE_CORTEX_MX_INT_43_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_43_NUM, EE_CORTEX_MX_INT_43_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_43_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_43_NUM);
+#endif /* EE_CORTEX_MX_INT_43_ISR */
+
+#ifdef EE_CORTEX_MX_INT_44_ISR
+#ifdef EE_CORTEX_MX_INT_44_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_44_NUM, EE_CORTEX_MX_INT_44_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_44_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_44_NUM);
+#endif /* EE_CORTEX_MX_INT_44_ISR */
+
+#ifdef EE_CORTEX_MX_INT_45_ISR
+#ifdef EE_CORTEX_MX_INT_45_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_45_NUM, EE_CORTEX_MX_INT_45_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_45_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_45_NUM);
+#endif /* EE_CORTEX_MX_INT_45_ISR */
+
+#ifdef EE_CORTEX_MX_INT_46_ISR
+#ifdef EE_CORTEX_MX_INT_46_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_46_NUM, EE_CORTEX_MX_INT_46_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_46_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_46_NUM);
+#endif /* EE_CORTEX_MX_INT_46_ISR */
+
+#ifdef EE_CORTEX_MX_INT_47_ISR
+#ifdef EE_CORTEX_MX_INT_47_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_47_NUM, EE_CORTEX_MX_INT_47_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_47_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_47_NUM);
+#endif /* EE_CORTEX_MX_INT_47_ISR */
+
+#ifdef EE_CORTEX_MX_INT_48_ISR
+#ifdef EE_CORTEX_MX_INT_48_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_48_NUM, EE_CORTEX_MX_INT_48_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_48_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_48_NUM);
+#endif /* EE_CORTEX_MX_INT_48_ISR */
+
+#ifdef EE_CORTEX_MX_INT_49_ISR
+#ifdef EE_CORTEX_MX_INT_49_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_49_NUM, EE_CORTEX_MX_INT_49_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_49_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_49_NUM);
+#endif /* EE_CORTEX_MX_INT_49_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4A_ISR
+#ifdef EE_CORTEX_MX_INT_4A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4A_NUM, EE_CORTEX_MX_INT_4A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4A_NUM);
+#endif /* EE_CORTEX_MX_INT_4A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4B_ISR
+#ifdef EE_CORTEX_MX_INT_4B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4B_NUM, EE_CORTEX_MX_INT_4B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4B_NUM);
+#endif /* EE_CORTEX_MX_INT_4B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4C_ISR
+#ifdef EE_CORTEX_MX_INT_4C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4C_NUM, EE_CORTEX_MX_INT_4C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4C_NUM);
+#endif /* EE_CORTEX_MX_INT_4C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4D_ISR
+#ifdef EE_CORTEX_MX_INT_4D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4D_NUM, EE_CORTEX_MX_INT_4D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4D_NUM);
+#endif /* EE_CORTEX_MX_INT_4D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4E_ISR
+#ifdef EE_CORTEX_MX_INT_4E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4E_NUM, EE_CORTEX_MX_INT_4E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4E_NUM);
+#endif /* EE_CORTEX_MX_INT_4E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_4F_ISR
+#ifdef EE_CORTEX_MX_INT_4F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_4F_NUM, EE_CORTEX_MX_INT_4F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_4F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_4F_NUM);
+#endif /* EE_CORTEX_MX_INT_4F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_50_ISR
+#ifdef EE_CORTEX_MX_INT_50_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_50_NUM, EE_CORTEX_MX_INT_50_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_50_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_50_NUM);
+#endif /* EE_CORTEX_MX_INT_50_ISR */
+
+#ifdef EE_CORTEX_MX_INT_51_ISR
+#ifdef EE_CORTEX_MX_INT_51_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_51_NUM, EE_CORTEX_MX_INT_51_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_51_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_51_NUM);
+#endif /* EE_CORTEX_MX_INT_51_ISR */
+
+#ifdef EE_CORTEX_MX_INT_52_ISR
+#ifdef EE_CORTEX_MX_INT_52_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_52_NUM, EE_CORTEX_MX_INT_52_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_52_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_52_NUM);
+#endif /* EE_CORTEX_MX_INT_52_ISR */
+
+#ifdef EE_CORTEX_MX_INT_53_ISR
+#ifdef EE_CORTEX_MX_INT_53_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_53_NUM, EE_CORTEX_MX_INT_53_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_53_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_53_NUM);
+#endif /* EE_CORTEX_MX_INT_53_ISR */
+
+#ifdef EE_CORTEX_MX_INT_54_ISR
+#ifdef EE_CORTEX_MX_INT_54_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_54_NUM, EE_CORTEX_MX_INT_54_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_54_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_54_NUM);
+#endif /* EE_CORTEX_MX_INT_54_ISR */
+
+#ifdef EE_CORTEX_MX_INT_55_ISR
+#ifdef EE_CORTEX_MX_INT_55_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_55_NUM, EE_CORTEX_MX_INT_55_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_55_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_55_NUM);
+#endif /* EE_CORTEX_MX_INT_55_ISR */
+
+#ifdef EE_CORTEX_MX_INT_56_ISR
+#ifdef EE_CORTEX_MX_INT_56_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_56_NUM, EE_CORTEX_MX_INT_56_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_56_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_56_NUM);
+#endif /* EE_CORTEX_MX_INT_56_ISR */
+
+#ifdef EE_CORTEX_MX_INT_57_ISR
+#ifdef EE_CORTEX_MX_INT_57_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_57_NUM, EE_CORTEX_MX_INT_57_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_57_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_57_NUM);
+#endif /* EE_CORTEX_MX_INT_57_ISR */
+
+#ifdef EE_CORTEX_MX_INT_58_ISR
+#ifdef EE_CORTEX_MX_INT_58_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_58_NUM, EE_CORTEX_MX_INT_58_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_58_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_58_NUM);
+#endif /* EE_CORTEX_MX_INT_58_ISR */
+
+#ifdef EE_CORTEX_MX_INT_59_ISR
+#ifdef EE_CORTEX_MX_INT_59_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_59_NUM, EE_CORTEX_MX_INT_59_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_59_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_59_NUM);
+#endif /* EE_CORTEX_MX_INT_59_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5A_ISR
+#ifdef EE_CORTEX_MX_INT_5A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5A_NUM, EE_CORTEX_MX_INT_5A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5A_NUM);
+#endif /* EE_CORTEX_MX_INT_5A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5B_ISR
+#ifdef EE_CORTEX_MX_INT_5B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5B_NUM, EE_CORTEX_MX_INT_5B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5B_NUM);
+#endif /* EE_CORTEX_MX_INT_5B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5C_ISR
+#ifdef EE_CORTEX_MX_INT_5C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5C_NUM, EE_CORTEX_MX_INT_5C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5C_NUM);
+#endif /* EE_CORTEX_MX_INT_5C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5D_ISR
+#ifdef EE_CORTEX_MX_INT_5D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5D_NUM, EE_CORTEX_MX_INT_5D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5D_NUM);
+#endif /* EE_CORTEX_MX_INT_5D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5E_ISR
+#ifdef EE_CORTEX_MX_INT_5E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5E_NUM, EE_CORTEX_MX_INT_5E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5E_NUM);
+#endif /* EE_CORTEX_MX_INT_5E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_5F_ISR
+#ifdef EE_CORTEX_MX_INT_5F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_5F_NUM, EE_CORTEX_MX_INT_5F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_5F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_5F_NUM);
+#endif /* EE_CORTEX_MX_INT_5F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_60_ISR
+#ifdef EE_CORTEX_MX_INT_60_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_60_NUM, EE_CORTEX_MX_INT_60_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_60_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_60_NUM);
+#endif /* EE_CORTEX_MX_INT_60_ISR */
+
+#ifdef EE_CORTEX_MX_INT_61_ISR
+#ifdef EE_CORTEX_MX_INT_61_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_61_NUM, EE_CORTEX_MX_INT_61_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_61_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_61_NUM);
+#endif /* EE_CORTEX_MX_INT_61_ISR */
+
+#ifdef EE_CORTEX_MX_INT_62_ISR
+#ifdef EE_CORTEX_MX_INT_62_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_62_NUM, EE_CORTEX_MX_INT_62_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_62_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_62_NUM);
+#endif /* EE_CORTEX_MX_INT_62_ISR */
+
+#ifdef EE_CORTEX_MX_INT_63_ISR
+#ifdef EE_CORTEX_MX_INT_63_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_63_NUM, EE_CORTEX_MX_INT_63_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_63_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_63_NUM);
+#endif /* EE_CORTEX_MX_INT_63_ISR */
+
+#ifdef EE_CORTEX_MX_INT_64_ISR
+#ifdef EE_CORTEX_MX_INT_64_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_64_NUM, EE_CORTEX_MX_INT_64_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_64_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_64_NUM);
+#endif /* EE_CORTEX_MX_INT_64_ISR */
+
+#ifdef EE_CORTEX_MX_INT_65_ISR
+#ifdef EE_CORTEX_MX_INT_65_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_65_NUM, EE_CORTEX_MX_INT_65_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_65_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_65_NUM);
+#endif /* EE_CORTEX_MX_INT_65_ISR */
+
+#ifdef EE_CORTEX_MX_INT_66_ISR
+#ifdef EE_CORTEX_MX_INT_66_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_66_NUM, EE_CORTEX_MX_INT_66_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_66_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_66_NUM);
+#endif /* EE_CORTEX_MX_INT_66_ISR */
+
+#ifdef EE_CORTEX_MX_INT_67_ISR
+#ifdef EE_CORTEX_MX_INT_67_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_67_NUM, EE_CORTEX_MX_INT_67_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_67_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_67_NUM);
+#endif /* EE_CORTEX_MX_INT_67_ISR */
+
+#ifdef EE_CORTEX_MX_INT_68_ISR
+#ifdef EE_CORTEX_MX_INT_68_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_68_NUM, EE_CORTEX_MX_INT_68_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_68_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_68_NUM);
+#endif /* EE_CORTEX_MX_INT_68_ISR */
+
+#ifdef EE_CORTEX_MX_INT_69_ISR
+#ifdef EE_CORTEX_MX_INT_69_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_69_NUM, EE_CORTEX_MX_INT_69_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_69_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_69_NUM);
+#endif /* EE_CORTEX_MX_INT_69_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6A_ISR
+#ifdef EE_CORTEX_MX_INT_6A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6A_NUM, EE_CORTEX_MX_INT_6A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6A_NUM);
+#endif /* EE_CORTEX_MX_INT_6A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6B_ISR
+#ifdef EE_CORTEX_MX_INT_6B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6B_NUM, EE_CORTEX_MX_INT_6B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6B_NUM);
+#endif /* EE_CORTEX_MX_INT_6B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6C_ISR
+#ifdef EE_CORTEX_MX_INT_6C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6C_NUM, EE_CORTEX_MX_INT_6C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6C_NUM);
+#endif /* EE_CORTEX_MX_INT_6C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6D_ISR
+#ifdef EE_CORTEX_MX_INT_6D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6D_NUM, EE_CORTEX_MX_INT_6D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6D_NUM);
+#endif /* EE_CORTEX_MX_INT_6D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6E_ISR
+#ifdef EE_CORTEX_MX_INT_6E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6E_NUM, EE_CORTEX_MX_INT_6E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6E_NUM);
+#endif /* EE_CORTEX_MX_INT_6E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_6F_ISR
+#ifdef EE_CORTEX_MX_INT_6F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_6F_NUM, EE_CORTEX_MX_INT_6F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_6F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_6F_NUM);
+#endif /* EE_CORTEX_MX_INT_6F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_70_ISR
+#ifdef EE_CORTEX_MX_INT_70_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_70_NUM, EE_CORTEX_MX_INT_70_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_70_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_70_NUM);
+#endif /* EE_CORTEX_MX_INT_70_ISR */
+
+#ifdef EE_CORTEX_MX_INT_71_ISR
+#ifdef EE_CORTEX_MX_INT_71_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_71_NUM, EE_CORTEX_MX_INT_71_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_71_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_71_NUM);
+#endif /* EE_CORTEX_MX_INT_71_ISR */
+
+#ifdef EE_CORTEX_MX_INT_72_ISR
+#ifdef EE_CORTEX_MX_INT_72_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_72_NUM, EE_CORTEX_MX_INT_72_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_72_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_72_NUM);
+#endif /* EE_CORTEX_MX_INT_72_ISR */
+
+#ifdef EE_CORTEX_MX_INT_73_ISR
+#ifdef EE_CORTEX_MX_INT_73_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_73_NUM, EE_CORTEX_MX_INT_73_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_73_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_73_NUM);
+#endif /* EE_CORTEX_MX_INT_73_ISR */
+
+#ifdef EE_CORTEX_MX_INT_74_ISR
+#ifdef EE_CORTEX_MX_INT_74_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_74_NUM, EE_CORTEX_MX_INT_74_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_74_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_74_NUM);
+#endif /* EE_CORTEX_MX_INT_74_ISR */
+
+#ifdef EE_CORTEX_MX_INT_75_ISR
+#ifdef EE_CORTEX_MX_INT_75_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_75_NUM, EE_CORTEX_MX_INT_75_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_75_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_75_NUM);
+#endif /* EE_CORTEX_MX_INT_75_ISR */
+
+#ifdef EE_CORTEX_MX_INT_76_ISR
+#ifdef EE_CORTEX_MX_INT_76_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_76_NUM, EE_CORTEX_MX_INT_76_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_76_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_76_NUM);
+#endif /* EE_CORTEX_MX_INT_76_ISR */
+
+#ifdef EE_CORTEX_MX_INT_77_ISR
+#ifdef EE_CORTEX_MX_INT_77_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_77_NUM, EE_CORTEX_MX_INT_77_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_77_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_77_NUM);
+#endif /* EE_CORTEX_MX_INT_77_ISR */
+
+#ifdef EE_CORTEX_MX_INT_78_ISR
+#ifdef EE_CORTEX_MX_INT_78_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_78_NUM, EE_CORTEX_MX_INT_78_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_78_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_78_NUM);
+#endif /* EE_CORTEX_MX_INT_78_ISR */
+
+#ifdef EE_CORTEX_MX_INT_79_ISR
+#ifdef EE_CORTEX_MX_INT_79_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_79_NUM, EE_CORTEX_MX_INT_79_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_79_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_79_NUM);
+#endif /* EE_CORTEX_MX_INT_79_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7A_ISR
+#ifdef EE_CORTEX_MX_INT_7A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7A_NUM, EE_CORTEX_MX_INT_7A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7A_NUM);
+#endif /* EE_CORTEX_MX_INT_7A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7B_ISR
+#ifdef EE_CORTEX_MX_INT_7B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7B_NUM, EE_CORTEX_MX_INT_7B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7B_NUM);
+#endif /* EE_CORTEX_MX_INT_7B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7C_ISR
+#ifdef EE_CORTEX_MX_INT_7C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7C_NUM, EE_CORTEX_MX_INT_7C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7C_NUM);
+#endif /* EE_CORTEX_MX_INT_7C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7D_ISR
+#ifdef EE_CORTEX_MX_INT_7D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7D_NUM, EE_CORTEX_MX_INT_7D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7D_NUM);
+#endif /* EE_CORTEX_MX_INT_7D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7E_ISR
+#ifdef EE_CORTEX_MX_INT_7E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7E_NUM, EE_CORTEX_MX_INT_7E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7E_NUM);
+#endif /* EE_CORTEX_MX_INT_7E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_7F_ISR
+#ifdef EE_CORTEX_MX_INT_7F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_7F_NUM, EE_CORTEX_MX_INT_7F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_7F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_7F_NUM);
+#endif /* EE_CORTEX_MX_INT_7F_ISR */
+
+#ifdef EE_CORTEX_MX_INT_80_ISR
+#ifdef EE_CORTEX_MX_INT_80_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_80_NUM, EE_CORTEX_MX_INT_80_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_80_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_80_NUM);
+#endif /* EE_CORTEX_MX_INT_80_ISR */
+
+#ifdef EE_CORTEX_MX_INT_81_ISR
+#ifdef EE_CORTEX_MX_INT_81_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_81_NUM, EE_CORTEX_MX_INT_81_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_81_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_81_NUM);
+#endif /* EE_CORTEX_MX_INT_81_ISR */
+
+#ifdef EE_CORTEX_MX_INT_82_ISR
+#ifdef EE_CORTEX_MX_INT_82_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_82_NUM, EE_CORTEX_MX_INT_82_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_82_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_82_NUM);
+#endif /* EE_CORTEX_MX_INT_82_ISR */
+
+#ifdef EE_CORTEX_MX_INT_83_ISR
+#ifdef EE_CORTEX_MX_INT_83_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_83_NUM, EE_CORTEX_MX_INT_83_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_83_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_83_NUM);
+#endif /* EE_CORTEX_MX_INT_83_ISR */
+
+#ifdef EE_CORTEX_MX_INT_84_ISR
+#ifdef EE_CORTEX_MX_INT_84_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_84_NUM, EE_CORTEX_MX_INT_84_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_84_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_84_NUM);
+#endif /* EE_CORTEX_MX_INT_84_ISR */
+
+#ifdef EE_CORTEX_MX_INT_85_ISR
+#ifdef EE_CORTEX_MX_INT_85_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_85_NUM, EE_CORTEX_MX_INT_85_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_85_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_85_NUM);
+#endif /* EE_CORTEX_MX_INT_85_ISR */
+
+#ifdef EE_CORTEX_MX_INT_86_ISR
+#ifdef EE_CORTEX_MX_INT_86_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_86_NUM, EE_CORTEX_MX_INT_86_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_86_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_86_NUM);
+#endif /* EE_CORTEX_MX_INT_86_ISR */
+
+#ifdef EE_CORTEX_MX_INT_87_ISR
+#ifdef EE_CORTEX_MX_INT_87_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_87_NUM, EE_CORTEX_MX_INT_87_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_87_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_87_NUM);
+#endif /* EE_CORTEX_MX_INT_87_ISR */
+
+#ifdef EE_CORTEX_MX_INT_88_ISR
+#ifdef EE_CORTEX_MX_INT_88_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_88_NUM, EE_CORTEX_MX_INT_88_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_88_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_88_NUM);
+#endif /* EE_CORTEX_MX_INT_88_ISR */
+
+#ifdef EE_CORTEX_MX_INT_89_ISR
+#ifdef EE_CORTEX_MX_INT_89_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_89_NUM, EE_CORTEX_MX_INT_89_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_89_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_89_NUM);
+#endif /* EE_CORTEX_MX_INT_89_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8A_ISR
+#ifdef EE_CORTEX_MX_INT_8A_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8A_NUM, EE_CORTEX_MX_INT_8A_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8A_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8A_NUM);
+#endif /* EE_CORTEX_MX_INT_8A_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8B_ISR
+#ifdef EE_CORTEX_MX_INT_8B_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8B_NUM, EE_CORTEX_MX_INT_8B_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8B_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8B_NUM);
+#endif /* EE_CORTEX_MX_INT_8B_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8C_ISR
+#ifdef EE_CORTEX_MX_INT_8C_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8C_NUM, EE_CORTEX_MX_INT_8C_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8C_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8C_NUM);
+#endif /* EE_CORTEX_MX_INT_8C_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8D_ISR
+#ifdef EE_CORTEX_MX_INT_8D_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8D_NUM, EE_CORTEX_MX_INT_8D_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8D_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8D_NUM);
+#endif /* EE_CORTEX_MX_INT_8D_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8E_ISR
+#ifdef EE_CORTEX_MX_INT_8E_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8E_NUM, EE_CORTEX_MX_INT_8E_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8E_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8E_NUM);
+#endif /* EE_CORTEX_MX_INT_8E_ISR */
+
+#ifdef EE_CORTEX_MX_INT_8F_ISR
+#ifdef EE_CORTEX_MX_INT_8F_ISR_PRI
+ NVIC_SET_PRI(EE_CORTEX_MX_INT_8F_NUM, EE_CORTEX_MX_INT_8F_ISR_PRI);
+#endif /* EE_CORTEX_MX_INT_8F_ISR_PRI */
+ NVIC_INT_ENABLE(EE_CORTEX_MX_INT_8F_NUM);
+#endif /* EE_CORTEX_MX_INT_8F_ISR */
+
+#endif /* __CORTEX_M4__ */
+
+ EE_hal_resumeIRQ(flags);
+}
+
+#define EPSR_T_BIT_VAL 0x01000000 /* Value to set the T-bit in EPSR */
+ /* (always Thumb mode) */
+extern void __end(void);
+extern void EE_cortex_mx_change_context_return_point(void);
+void EE_init_task_private_stack(void)
+{
+ int i;
+
+ for (i = EE_CORTEX_MX_SYSTEM_TOS_SIZE - 1; i > 0; i--) {
+ unsigned int *s = (unsigned int *)EE_cortex_mx_system_tos[i].SYS_tos;
+ /* adjust stack address to 8-byte align */
+ s = (unsigned int *)((unsigned int)s & (unsigned int)(~0x7));
+
+ /* task end frame
+ * |xPSR|-> xPSR AND 0xFFFFFE0
+ * | PC |-> EE_cortex_mx_change_context
+ * | LR |-> EE_cortex_mx_change_context_return_point
+ * | R12|
+ * | R3 |
+ * | R2 |
+ * | R1 |
+ * | R0 | <- MSP
+ */
+ *(--s) = EPSR_T_BIT_VAL; /* enable IRQ, IRQ prio level 15 */
+ *(--s) = (int)__end; /* an infinite loop after return from main */
+ *(--s) = (int)__end;
+ *(--s) = 12;
+ *(--s) = 3;
+ *(--s) = 2;
+ *(--s) = 1;
+ *(--s) = 0;
+ /* task context frame
+ * | R7 |
+ * | R6 |
+ * | R5 |
+ * | R4 |
+ * | R11 |
+ * | R10 |
+ * | R9 |
+ * | R8 |
+ * | LR |
+ */
+ *(--s) = 7;
+ *(--s) = 6;
+ *(--s) = 5;
+ *(--s) = 4;
+ *(--s) = 11;
+ *(--s) = 10;
+ *(--s) = 9;
+ *(--s) = 8;
+ *(--s) = (int)EE_cortex_mx_change_context_return_point;
+ EE_cortex_mx_system_tos[i].SYS_tos = (EE_ADDR)s;
+ }
+
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/ee.h b/src/bsp/hsm/os/erika2/pkg/ee.h
new file mode 100644
index 0000000..9cb405f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee.h
@@ -0,0 +1,519 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2014 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2000-2004 Paolo Gai
+ * 2009 Bernardo Dal Seno
+ */
+
+
+#ifndef PKG_EE_H
+#define PKG_EE_H
+
+#include "eecfg.h"
+
+#include "ee_rtdruid_versions.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ *
+ * CPU
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "cpu/hs12xs/inc/ee_cpu.h"
+#endif
+
+#ifdef __ST10__
+#include "st10mono/arch.h"
+#endif
+
+#ifdef __ST10SEGM__
+#include "st10segm/arch.h"
+#endif
+
+#if (defined(__ARM7GNU__)) || (defined(__ARM7ADS__))
+#include "cpu/arm7tdmi/inc/ee_cpu.h"
+#endif
+
+#ifdef __X86__
+#include "cpu/x86/inc/ee_cpu.h"
+#endif
+
+
+#ifdef __AVR8__
+#include "cpu/avr8/inc/ee_avr8_cpu.h"
+#endif
+
+#ifdef __H8__
+#include "h8/arch.h"
+#include "h8/drivers.h"
+#include "h8/fmath.h"
+#include "h8/inline_k.h"
+#include "h8/inline_d.h"
+#endif
+
+#ifdef __NIOS2__
+#include "cpu/nios2/inc/ee_cpu.h"
+#endif
+
+#ifdef __MPC5XX__
+#include "cpu/mpc5xx/inc/ee_cpu.h"
+#endif
+
+#ifdef __MPC5PROTECTED__
+#include "cpu/mpc5protected/inc/ee_cpu.h"
+#endif
+
+#ifdef __PIC30__
+#include "cpu/pic30/inc/ee_cpu.h"
+#endif
+
+#ifdef __PIC32__
+#include "cpu/pic32/inc/ee_cpu.h"
+#endif
+
+#ifdef __RH850__
+#include "cpu/rh850/inc/ee_cpu.h"
+#endif
+
+#ifdef __TRICORE1__
+#include "cpu/tricore1/inc/ee_cpu.h"
+
+#ifdef __INT__
+#include "cpu/tricore1/inc/ee_int.h"
+#endif
+
+#ifdef __TRAP__
+#include "cpu/tricore1/inc/ee_trap.h"
+#endif
+
+#endif /* __TRICORE1__ */
+
+#ifdef EE_CORTEX_AX_XENPV__
+#include "cpu/cortex_ax_xenpv/inc/ee_cax_cpu.h"
+#endif /* EE_CORTEX_AX_XENPV__ */
+
+#ifdef __LM32__
+#include "cpu/mico32/inc/ee_cpu.h"
+#endif
+
+#if (defined(__PPCE200Z7__)) || (defined(__PPCE200ZX__))
+#include "cpu/e200zx/inc/ee_cpu.h"
+#endif /* defined __PPCE200Z7__ || defined __PPCE200ZX__ */
+
+#ifdef __ESI_RISC__
+#include "cpu/esi_risc/inc/ee_cpu.h"
+#endif
+
+#ifdef __MSP430__
+#include "cpu/msp430/inc/ee_cpu.h"
+#endif
+
+#ifdef __CORTEX_MX__
+#include "cpu/cortex_mx/inc/ee_cpu.h"
+#endif
+
+#ifdef __RX200__
+#include "cpu/rx200/inc/ee_cpu.h"
+#endif
+
+#ifdef __CORTEX_RX__
+#include "cpu/cortex_rx/inc/ee_cpu.h"
+#endif
+
+#ifdef __ARC_EM6__
+#include "cpu/arc_em6/inc/ee_cpu.h"
+#endif
+
+/*
+ *
+ * MCU
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "mcu/hs12xs/inc/ee_mcu.h"
+#endif
+
+/* Atmel AVR */
+#ifdef __ATMEGA__
+#include "mcu/atmel_atmega/inc/ee_mcu.h"
+#endif
+
+#ifdef __ATTINY__
+#include "mcu/atmel_attiny/inc/ee_mcu.h"
+#endif
+
+#ifdef __ATXMEGA__
+#include "mcu/atmel_atxmega/inc/ee_atmel_atxmega_mcu.h"
+#endif
+
+/* ARM */
+#ifdef __SAMSUNG_KS32C50100__
+#include "mcu/samsung_ks32c50100/inc/ee_mcu.h"
+#endif
+
+#ifdef __ST_STA2051__
+#include "mcu/st_sta2051/inc/ee_mcu.h"
+#endif
+
+#ifdef __UNIBO_MPARM__
+#include "mcu/unibo_mparm/inc/ee_mcu.h"
+#endif
+
+/* PPC */
+#ifdef __MPC566EVB__
+#include "mcu/motorola_mpc566/inc/ee_mcu.h"
+#endif
+
+/* dsPIC */
+#ifdef __PIC30__
+#include "mcu/microchip_dspic/inc/ee_mcu.h"
+#endif
+
+/* dsPIC */
+#ifdef __PIC32__
+#include "mcu/microchip_pic32/inc/ee_mcu.h"
+#endif
+
+/* NIOS 2 */
+#ifdef __NIOS2__
+#include "mcu/altera_nios2/inc/ee_mcu.h"
+#endif
+
+/* MICO32 */
+#ifdef __LM32__
+#include "mcu/mico32/inc/ee_mcu.h"
+#endif
+
+/* Tricore1 TC179x */
+#ifdef __TC179x__
+#include "mcu/tc179x/inc/ee_mcu.h"
+#endif
+
+/* X86 */
+#ifdef __X86__
+#include "mcu/x86/inc/ee_mcu.h"
+#endif
+
+/* MSP430 */
+#ifdef __MSP430__
+#include "mcu/msp430/inc/ee_mcu.h"
+#endif
+
+/* LPCXpresso */
+#if (defined(__LPCXPRESSO__)) && (defined(__LPC12xx__))
+#include "mcu/nxp_lpcxpresso_lpc12xx/inc/ee_mcu.h"
+#endif
+
+/* Stellaris */
+#if (defined(__STELLARIS__)) && (defined(__LM4F232xxxx__))
+#include "mcu/ti_stellaris_lm4f232xxxx/inc/ee_mcu.h"
+#endif
+
+/* ST */
+#if (defined(__STM32__)) && (defined(__STM32F4xx__))
+#include "mcu/st_stm32_stm32f4xx/inc/ee_mcu.h"
+#endif
+
+/* NORDIC */
+#if (defined(__NORDIC__)) && (defined(__NRF51X22__))
+#include "mcu/nordic_nrf51x22/inc/ee_mcu.h"
+#endif
+
+/* Renesas RX200*/
+#if (defined(__RX200__)) && (defined(__R5F5210x__))
+#include "mcu/renesas_r5f5210x/inc/ee_mcu.h"
+#endif
+
+/* Renesas R7F701503 F1H */
+#if defined(__R7F701503__)
+#include "mcu/renesas_r7f701503/inc/ee_mcu.h"
+#endif
+
+/* Renesas R7F701057 F1L */
+#if defined(__R7F701057__)
+#include "mcu/renesas_r7f701057/inc/ee_mcu.h"
+#endif
+
+#if (defined(__TI__)) && (defined(__TMS570__))
+#include "mcu/ti_tms570/inc/ee_mcu.h"
+#endif
+
+/*
+ *
+ * BOARD
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#ifdef __DEMO9S12XSFAME__
+#include "board/hs12xs_demo9s12xsfame/inc/ee_board.h"
+#endif
+#ifdef __TWRS12G128__
+#include "board/twrs12g128/inc/ee_board.h"
+#endif
+#endif
+
+/* Atmel */
+#ifdef __ATMEL_STK50X__
+#include "board/atmel_stk500/inc/ee_board.h"
+#endif
+
+#ifdef __XBOW_MIB5X0__
+#include "board/xbow_mib5x0/inc/ee_board.h"
+#endif
+
+#ifdef __ARDUINO_UNO__
+#include "board/arduino_uno/inc/ee_board.h"
+#endif
+
+#ifdef __ATMEL_STK600__
+#include "board/atmel_stk600/inc/ee_atmel_stk600_board.h"
+#endif
+
+/* ARM */
+#ifdef __EVALUATOR7T__
+#include "board/arm_evaluator7t/inc/ee_board.h"
+#endif
+
+#ifdef __UNIBO_MPARM__
+#include "board/unibo_mparm/inc/ee_board.h"
+#endif
+
+#ifdef __TRISCENDA7S__
+#include "board/triscend_a7s/drivers.h"
+#endif
+
+/* dsPIC */
+#ifdef __MICROCHIP_EXPLORER16__
+#include "board/microchip_explorer16/inc/ee_board.h"
+#endif
+
+#ifdef __MICROCHIP_DSPICDEM11PLUS__
+#include "board/microchip_dspicdem11plus/inc/ee_board.h"
+#endif
+
+#ifdef __EE_FLEX__
+#include "board/ee_flex/inc/ee_board.h"
+#endif
+
+#ifdef __EE_MINIFLEX__
+#include "board/ee_miniflex/inc/ee_board.h"
+#endif
+
+#ifdef __EE_FLEX32__
+#include "board/ee_flex32/inc/ee_board.h"
+#endif
+
+/* PIC32 */
+#ifdef __IPERMOB_MB_PIC32__
+#include "board/ipermob_mb_pic32/inc/ee_board.h"
+#endif
+
+#ifdef __IPERMOB_DB_PIC32__
+#include "board/ipermob_db_pic32/inc/ee_board.h"
+#endif
+
+#ifdef __IPERMOB_BOARD_V2__
+#include "board/ipermob_board_v2/inc/ee_board.h"
+#endif
+
+#ifdef __MICROCHIP_ESK__
+#include "board/microchip_esk/inc/ee_board.h"
+#endif
+
+/* MICO32 */
+#ifdef __FPG_EYE__
+#include "board/fpg-eye/inc/ee_board.h"
+#endif
+
+#ifdef __LATTICE_XP2_EV_BOARD__
+#include "board/lattice_xp2_ev_board/inc/ee_board.h"
+#endif
+
+#ifdef __TC1796__
+#include "board/infineon_tc1796b/inc/ee_board.h"
+#endif
+
+/* Infineon Applikation Kit */
+#if (defined(EE_TRICORE__)) && (defined(EE_APPKIT_TC2X5))
+#include "board/infineon_Applikation_Kit_TC2X5/inc/ee_board.h"
+#endif
+
+#ifdef __ESI_RISC__
+#include "board/esi_risc/inc/ee_board.h"
+#endif
+
+#ifdef __UTMOST__
+#include "board/utmost/inc/ee_board.h"
+#endif
+
+#ifdef __MSP430_LAUNCHPAD__
+#include "board/msp430/launchpad/inc/ee_board.h"
+#endif
+
+#ifdef __EE_EASYLAB__
+#include "board/ee_easylab/inc/ee_board.h"
+#endif
+
+/* Stellaris */
+#if (defined(__STELLARIS__)) && (defined(__LM4F232xxxx__))
+#include "board/ti_stellaris_lm4f232xxxx/inc/ee_board.h"
+#endif
+
+#ifdef __RSKRX210__
+#include "board/renesas_rskrx210/inc/ee_board.h"
+#endif
+
+/* Nordic NRF51x22 */
+#ifdef __EE_NORDIC_PCA__
+#include "board/nordic_pca/inc/ee_board.h"
+#endif
+
+/* TMS570 */
+#if (defined(__TI__)) && (defined(__TMS570__))
+#include "board/ti_tms570/inc/ee_board.h"
+#endif
+
+/* Renesas RH850F1x StarterKit V2 */
+#ifdef __Y_ASK_RH850F1X_V2__
+#include "board/y_ask_rh850f1x_v2/inc/ee_board.h"
+#endif
+
+/*
+ *
+ * Kernel
+ *
+ */
+
+#ifdef __FP__
+#include "kernel/fp/inc/ee_kernel.h"
+#endif
+
+#ifdef __EDF__
+#include "kernel/edf/inc/ee_kernel.h"
+#endif
+
+#ifdef __FRSH__
+#ifdef __SEM_FRSH__
+#include "kernel/frsh/syncobj/inc/ee_sem.h"
+#endif
+#include "kernel/frsh/inc/ee_kernel.h"
+#endif
+
+/* HR */
+#ifdef __HR__
+#include "kernel/hr/inc/ee_kernel.h"
+#endif
+
+/* OO */
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__)) || (defined(__AS_SC4__))
+#include "kernel/oo/inc/ee_oo_kernel.h"
+#include "kernel/as/inc/ee_as_kernel.h"
+/* Moved inline interrupt services inclusion here, because they need to see TP
+ * declarations */
+#include "kernel/oo/inc/ee_oo_inline.h"
+
+#ifdef EE_AS_IOC__
+#include "kernel/as/inc/ee_as_ioc.h"
+/* WARNING
+ * The following file SHALL be generated by IOC Generator: if you are using
+ * Erika IOC implementation without a generator you MUST provide it in your
+ * project root. */
+#include "ioc_common.h"
+#endif /* EE_AS_IOC__ */
+
+#ifdef EE_AS_SCHEDULETABLES__
+#include "kernel/as/inc/ee_as_schedule_tables.h"
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#endif /* OO */
+
+/* SEM */
+#ifdef __SEM__
+#include "kernel/sem/inc/ee_sem.h"
+#endif
+
+/* ALARMS */
+#ifdef __ALARMS__
+#include "kernel/alarms/inc/ee_alarms.h"
+#endif
+
+/* RN */
+#if (defined(__RN__)) || (defined(EE_AS_RPC__))
+#include "kernel/rn/inc/ee_rn.h"
+#endif /* __RN__ || EE_AS_RPC__ */
+
+/*
+ *
+ * API
+ *
+ */
+
+#include "ee_api.h"
+
+/*
+ *
+ * IRQ
+ *
+ */
+
+#include "ee_irq.h"
+
+/* Assert inclusion if enabled */
+#ifdef __ASSERT__
+#include "test/assert/inc/ee_assert.h"
+#endif /* __ASSERT__ */
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif /* __INCLUDE_PKG_EE_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/ee_api.h b/src/bsp/hsm/os/erika2/pkg/ee_api.h
new file mode 100644
index 0000000..01477f1
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee_api.h
@@ -0,0 +1,154 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2014 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2004 Paolo Gai
+ */
+
+#ifndef PKG_EE_API_H
+#define PKG_EE_API_H
+
+/*
+ * ee_api.h contains the definition of all the interfaces exported to
+ * the user. Typically, they are just "#define apifunction
+ * internal_function" in case of kernels without memory protection, or
+ * they are something like "apifunction
+ * {assembler_stub_that_calls_SWI}" in case of a kernel with memory
+ * protection.
+ */
+
+
+
+/*
+ *
+ * CPU
+ *
+ */
+
+/*
+ *
+ * MCU
+ *
+ */
+
+/*
+ *
+ * BOARD
+ *
+ */
+
+/*
+ *
+ * Kernel
+ *
+ */
+
+#ifdef __FP__
+#include "kernel/fp/inc/ee_api.h"
+#endif
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+#include "kernel/oo/inc/ee_oo_api.h"
+
+/* Multicore API introduced from AS */
+#ifdef __MSRP__
+#include "kernel/as/inc/ee_as_multicore_api.h"
+#endif /* __MSRP__ */
+
+#endif /* __OO_XXXX__ */
+
+#ifdef __EDF__
+#include "kernel/edf/inc/ee_api.h"
+#endif
+
+#ifdef __SEM__
+#include "kernel/sem/inc/ee_api.h"
+#endif
+
+#ifdef __ALARMS__
+#include "kernel/alarms/inc/ee_api.h"
+#endif
+
+#ifdef __FRSH__
+#include "kernel/frsh/inc/ee_api.h"
+#endif
+
+#ifdef __HR__
+#include "kernel/hr/inc/ee_api.h"
+#endif
+
+/*
+ *
+ * Com
+ *
+ */
+
+#if (defined(__COM_CCCA__)) || (defined(__COM_CCCB__)) \
+ || (defined(__COM_CCC0__)) || (defined(__COM_CCC1__))
+#include "com/com/inc/ee_api.h"
+#endif
+
+/*
+ *
+ *
+ */
+#if defined(__AS_SC4__)
+#include "kernel/as/inc/ee_os.h"
+#include "kernel/as/inc/ee_os_internal.h"
+/* Multicore API introduced from AS */
+#ifdef __MSRP__
+#include "kernel/as/inc/ee_as_multicore_api.h"
+#endif /* __MSRP__ */
+
+/*
+ * Some autosar functionalities are implemented as architecture-dependent
+ * macros, but they need the definitions in the above header files.
+ */
+#ifdef __PPCE200ZX__
+#include "cpu/e200zx/inc/ee_as_cpu.h"
+#endif
+#endif /* __AS_SC4__ */
+
+#if (defined(__EE_MEMORY_PROTECTION__)) && (!defined(__AS_SC4__))
+#include "kernel/as/inc/ee_as_api.h"
+#endif /* __EE_MEMORY_PROTECTION__ && !__AS_SC4__ */
+
+#endif /* __INCLUDE_EE_API_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/ee_internal.h
new file mode 100644
index 0000000..001ac74
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee_internal.h
@@ -0,0 +1,416 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2014 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2000-2006 Paolo Gai
+ */
+
+#ifndef PKG_EE_INTERNAL_H
+#define PKG_EE_INTERNAL_H
+
+#include "eecfg.h"
+
+#include "ee_rtdruid_versions.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ *
+ * CPU
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "cpu/hs12xs/inc/ee_internal.h"
+#endif
+
+#ifdef __X86__
+#include "cpu/x86/inc/ee_internal.h"
+#endif
+
+#ifdef __AVR8__
+#include "cpu/avr8/inc/ee_avr8_internal.h"
+#endif
+
+#ifdef __ST10__
+#include "st10mono/internal.h"
+#endif
+
+#ifdef __ST10SEGM__
+#include "st10segm/internal.h"
+#endif
+
+#if (defined(__ARM7GNU__)) || (defined(__ARM7ADS__))
+#include "cpu/arm7tdmi/inc/ee_internal.h"
+#endif
+
+#ifdef __MPC5XX__
+#include "cpu/mpc5xx/inc/ee_internal.h"
+#endif
+
+#ifdef __MPC5PROTECTED__
+#include "cpu/mpc5protected/inc/ee_internal.h"
+#endif
+
+#ifdef __NIOS2__
+#include "cpu/nios2/inc/ee_internal.h"
+#endif
+
+#ifdef __PIC30__
+#include "cpu/pic30/inc/ee_internal.h"
+#endif
+
+#ifdef __PIC32__
+#include "cpu/pic32/inc/ee_internal.h"
+#endif
+
+#ifdef EE_CORTEX_AX_XENPV__
+#include "cpu/cortex_ax_xenpv/inc/ee_cax_internal.h"
+#endif /* EE_CORTEX_AX_XENPV__ */
+
+#ifdef __LM32__
+#include "cpu/mico32/inc/ee_internal.h"
+#endif
+
+#if (defined(__PPCE200Z7__)) || (defined(__PPCE200ZX__))
+#include "cpu/e200zx/inc/ee_internal.h"
+#endif
+
+#ifdef __ESI_RISC__
+#include "cpu/esi_risc/inc/ee_internal.h"
+#endif
+
+#ifdef __MSP430__
+#include "cpu/msp430/inc/ee_internal.h"
+#endif
+
+/* ARM */
+#ifdef __CORTEX_MX__
+#include "cpu/cortex_mx/inc/ee_internal.h"
+#endif
+
+/* Renesas RX200 */
+#ifdef __RX200__
+#include "cpu/rx200/inc/ee_internal.h"
+#endif
+
+/* Renesas RH850 */
+#ifdef __RH850__
+#include "cpu/rh850/inc/ee_internal.h"
+#endif
+
+#ifdef __CORTEX_RX__
+#include "cpu/cortex_rx/inc/ee_internal.h"
+#endif
+
+#ifdef __ARC_EM6__
+#include "cpu/arc_em6/inc/ee_internal.h"
+#endif
+
+/*
+ *
+ * MCU
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "mcu/hs12xs/inc/ee_internal.h"
+#endif
+
+/* Atmel AVR */
+#ifdef __ATMEGA__
+#include "mcu/atmel_atmega/inc/ee_internal.h"
+#endif
+
+#ifdef __ATTINY__
+#include "mcu/atmel_attiny/inc/ee_internal.h"
+#endif
+
+#ifdef __ATXMEGA__
+#include "mcu/atmel_atxmega/inc/ee_atmel_atxmega_internal.h"
+#endif
+
+
+/* ARM */
+#if defined(__SAMSUNG_KS32C50100__)
+#include "mcu/samsung_ks32c50100/inc/ee_internal.h"
+#endif
+
+#if defined(__UNIBO_MPARM__)
+#include "mcu/unibo_mparm/inc/ee_internal.h"
+#endif
+
+#if defined __TRISCENDA7S__
+#include "mcu/triscend_a7s/internal.h"
+#endif
+
+#if defined(__ST_STA2051__)
+#include "mcu/st_sta2051/inc/ee_internal.h"
+#endif
+
+/* PPC */
+#ifdef __MPC566EVB__
+#include "mcu/motorola_mpc566/inc/ee_mcu.h"
+#endif
+
+/* Microchip dsPIC */
+#ifdef __MICROCHIP_DSPIC30__
+#include "mcu/microchip_dspic/inc/ee_internal.h"
+#endif
+
+/* NIOS 2 */
+#ifdef __NIOS2__
+#include "mcu/altera_nios2/inc/ee_internal.h"
+#endif
+
+/* MICO32 */
+#ifdef __LM32__
+#include "mcu/mico32/inc/ee_internal.h"
+#endif
+
+/* Tricore1 */
+
+#ifdef __TC179x__
+#include "mcu/tc179x/inc/ee_internal.h"
+#endif
+
+/* LPCXpresso */
+#if (defined(__LPCXPRESSO__)) && (defined(__LPC12xx__))
+#include "mcu/nxp_lpcxpresso_lpc12xx/inc/ee_internal.h"
+#endif
+
+/* Stellaris */
+#if (defined(__STELLARIS__)) && (defined(__LM4F232xxxx__))
+#include "mcu/ti_stellaris_lm4f232xxxx/inc/ee_internal.h"
+#endif
+
+/* ST */
+#if (defined(__STM32__)) && (defined(__STM32F4xx__))
+#include "mcu/st_stm32_stm32f4xx/inc/ee_internal.h"
+#endif
+
+/* NORDIC */
+#if (defined(__NORDIC__)) && (defined(__NRF51X22__))
+#include "mcu/nordic_nrf51x22/inc/ee_internal.h"
+#endif
+
+/* Renesas RX200*/
+#if (defined(__RX200__)) && (defined(__R5F5210x__))
+#include "mcu/renesas_r5f5210x/inc/ee_internal.h"
+#endif
+
+/* Renesas R7F701503 */
+#if defined(__RH850__) && defined(__R7F701503__)
+#include "mcu/renesas_r7f701503/inc/ee_internal.h"
+#endif
+
+/* Renesas R7F701057 */
+#if defined(__RH850__) && defined(__R7F701057__)
+#include "mcu/renesas_r7f701057/inc/ee_internal.h"
+#endif
+
+#if (defined(__TI__)) && (defined(__TMS570__))
+#include "mcu/ti_tms570/inc/ee_internal.h"
+#endif
+
+/*
+ *
+ * Board
+ *
+ */
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#ifdef __DEMO9S12XSFAME__
+#include "board/hs12xs_demo9s12xsfame/inc/ee_internal.h"
+#endif
+#ifdef __TWRS12G128__
+#include "board/twrs12g128/inc/ee_internal.h"
+#endif
+#endif
+
+/* Atmel */
+#ifdef __ATMEL_STK50X__
+#include "board/atmel_stk500/inc/ee_internal.h"
+#endif
+
+#ifdef __XBOW_MIB5X0__
+#include "board/xbow_mib5x0/inc/ee_board.h"
+#endif
+
+#ifdef __ARDUINO_UNO__
+#include "board/arduino_uno/inc/ee_internal.h"
+#endif
+
+#ifdef __ATMEL_STK600__
+#include "board/atmel_stk600/inc/ee_atmel_stk600_internal.h"
+#endif
+
+/* ARM */
+#ifdef __EVALUATOR7T__
+#include "board/arm_evaluator7t/inc/ee_internal.h"
+#endif
+
+#if defined(__unibo_mparm__)
+#include "board/unibo_mparm/inc/ee_internal.h"
+#endif
+
+/* Microchip dsPIC */
+#ifdef __MICROCHIP_DSPICDEM11PLUS__
+#include "board/microchip_dspicdem11plus/inc/ee_internal.h"
+#endif
+
+#ifdef __MICROCHIP_EXPLORER16__
+#include "board/microchip_explorer16/inc/ee_internal.h"
+#endif
+
+#ifdef __EE_FLEX__
+#include "board/ee_flex/inc/ee_internal.h"
+#endif
+
+#ifdef __EE_MINIFLEX__
+#include "board/ee_miniflex/inc/ee_internal.h"
+#endif
+
+#ifdef __MICROCHIP_ESK__
+#include "board/microchip_esk/inc/ee_internal.h"
+#endif
+
+/* MICO32 */
+#ifdef __LM32__
+#include "board/fpg-eye/inc/ee_internal.h"
+#endif
+
+#ifdef __TC1796__
+#include "board/infineon_tc1796b/inc/ee_internal.h"
+#endif
+
+#ifdef __ESI_RISC__
+#include "board/esi_risc/inc/ee_board.h"
+#endif
+
+#ifdef __RSKRX210__
+#include "board/renesas_rskrx210/inc/ee_board.h"
+#endif
+
+/*
+ *
+ * Kernel
+ *
+ */
+
+
+#ifdef __FP__
+#include "kernel/fp/inc/ee_internal.h"
+/* API prototypes should be visible when defining API functions; also, some
+ * types are defined in ee_kernel.h */
+#include "kernel/fp/inc/ee_kernel.h"
+#endif
+
+#ifdef __EDF__
+#include "kernel/edf/inc/ee_internal.h"
+#endif
+
+#ifdef __FRSH__
+#ifdef __SEM_FRSH__
+#include "kernel/frsh/syncobj/inc/ee_sem.h"
+#endif
+#include "kernel/frsh/inc/ee_internal.h"
+#endif
+
+#ifdef __HR__
+#include "kernel/hr/inc/ee_internal.h"
+#endif
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+/* API prototypes should be visible when defining API functions */
+#include "kernel/oo/inc/ee_oo_kernel.h"
+#include "kernel/as/inc/ee_as_kernel.h"
+/* Moved inline interrupt services inclusion here, because they need to see TP
+ * declarations */
+#include "kernel/oo/inc/ee_oo_inline.h"
+
+/* XXX: IT CAN HAPPEN THAT SOME OSEK INLINES NEED SOME INTERNALS FROM AS LAYER */
+#include "kernel/as/inc/ee_as_internal.h"
+#include "kernel/oo/inc/ee_oo_internal.h"
+
+#ifdef EE_AS_IOC__
+#include "kernel/as/inc/ee_as_ioc.h"
+/* WARNING
+ * The following file SHALL be generated by IOC Generator: if you are using
+ * Erika IOC implementation without a generator you MUST provide it in your
+ * project root. */
+#include "ioc_common.h"
+#endif /* EE_AS_IOC__ */
+
+#ifdef EE_AS_SCHEDULETABLES__
+#include "kernel/as/inc/ee_as_schedule_tables.h"
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#endif /* OO */
+
+#ifdef __SEM__
+#include "kernel/sem/inc/ee_sem.h"
+#endif
+
+#ifdef __ALARMS__
+#include "kernel/alarms/inc/ee_alarms.h"
+#endif
+
+#if (defined(__RN__)) || (defined(EE_AS_RPC__))
+#include "kernel/rn/inc/ee_rn_internal.h"
+#endif /* __RN__ || EE_AS_RPC__ */
+
+#if defined(__AS_SC4__)
+#include "kernel/as/inc/ee_os_internal.h"
+#endif
+
+
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/ee_irq.h
new file mode 100644
index 0000000..1680975
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee_irq.h
@@ -0,0 +1,190 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2014 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @author Errico Guidieri
+ * @date 2012
+ **/
+
+/*******************************************************************************
+ * Interface header to access IRQ API and Macros support.
+ ******************************************************************************/
+
+#ifndef PKG_EE_IRQ_H
+#define PKG_EE_IRQ_H
+
+#include "eecfg.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ *
+ * CPU
+ *
+ */
+
+#ifdef __AVR8__
+#include "cpu/avr8/inc/ee_avr8_cpu.h"
+#endif
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "cpu/hs12xs/inc/ee_cpu.h"
+#endif
+
+#ifdef __PIC30__
+#include "cpu/pic30/inc/ee_cpu.h"
+#endif
+
+#ifdef __LM32__
+#include "cpu/mico32/inc/ee_cpu.h"
+#endif
+
+#if (defined(__PPCE200Z7__)) || (defined(__PPCE200ZX__))
+#include "cpu/e200zx/inc/ee_cpu.h"
+#endif /* defined __PPCE200Z7__ || defined __PPCE200ZX__ */
+
+#ifdef __CORTEX_MX__
+#include "cpu/cortex_mx/inc/ee_cpu.h"
+#endif
+
+#ifdef __X86__
+#include "cpu/x86/inc/ee_cpu.h"
+#endif
+
+#ifdef EE_CORTEX_AX_XENPV__
+#include "cpu/cortex_ax_xenpv/inc/ee_cax_cpu.h"
+#endif /* EE_CORTEX_AX_XENPV__ */
+
+#ifdef __CORTEX_RX__
+#include "cpu/cortex_rx/inc/ee_cpu.h"
+#endif
+
+#ifdef __ARC_EM6__
+#include "cpu/arc_em6/inc/ee_cpu.h"
+#endif /* __ARC_EM6__ */
+/*
+ * I need kernel inclusion before IRQ CPU inclusion because is CPU layer that
+ * have to see Kernel API for IRQ Handling
+ */
+
+/*
+ * Kernel
+ *
+ */
+#ifdef __FP__
+#include "kernel/fp/inc/ee_irq.h"
+#endif
+
+#ifdef __EDF__
+#include "kernel/edf/inc/ee_irq.h"
+#endif
+
+#ifdef __FRSH__
+#include "kernel/frsh/inc/ee_irq.h"
+#endif
+
+/* OO */
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__)) || (defined(__AS_SC4__))
+#include "kernel/oo/inc/ee_oo_irq.h"
+#endif
+
+/*
+ * CPU
+ */
+
+#ifdef __AVR8__
+#include "cpu/avr8/inc/ee_avr8_irq.h"
+#endif
+
+/* Freescale */
+#if (defined(__MC9S12__)) || (defined(__HCS12XS__))
+#include "cpu/hs12xs/inc/ee_irqstub.h"
+#endif
+
+#ifdef __PIC30__
+#include "cpu/pic30/inc/ee_irqstub.h"
+#endif
+
+#ifdef __X86__
+#include "cpu/x86/inc/ee_irqstub.h"
+#endif
+
+#ifdef __LM32__
+#include "cpu/mico32/inc/ee_irq.h"
+#endif
+
+#if (defined(__PPCE200Z7__)) || (defined(__PPCE200ZX__))
+#include "cpu/e200zx/inc/ee_irq.h"
+#endif
+
+#ifdef __CORTEX_MX__
+#include "cpu/cortex_mx/inc/ee_irq.h"
+#endif
+
+#ifdef __CORTEX_RX__
+#include "cpu/cortex_rx/inc/ee_irq.h"
+#endif
+
+#ifdef __RX200__
+#include "cpu/rx200/inc/ee_irq.h"
+#endif
+
+#ifdef __RH850__
+#include "cpu/rh850/inc/ee_irq.h"
+#endif
+
+#ifdef EE_TRICORE__
+/* #include "cpu/tricore/inc/ee_tc_irq.h" */
+/* #include "cpu/tricore/inc/ee_tc_trap.h" */
+#endif /* EE_TRICORE__ */
+
+#ifdef __ARC_EM6__
+#include "cpu/arc_em6/inc/ee_irq.h"
+#endif
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif /* INCLUDE_PKG_EE_IRQ_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/ee_os.h b/src/bsp/hsm/os/erika2/pkg/ee_os.h
new file mode 100644
index 0000000..9111fa9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee_os.h
@@ -0,0 +1,126 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @author Errico Guidieri
+ * @date 2012
+ **/
+
+/*******************************************************************************
+ * Interface header to Erika Kernel support.
+ ******************************************************************************/
+
+#ifndef INCLUDE_PKG_OS_H__
+#define INCLUDE_PKG_OS_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ *
+ * CPU minimal support for OS
+ *
+ */
+
+#if defined __PPCE200Z7__ || defined __PPCE200ZX__
+#include "cpu/e200zx/inc/ee_cpu_os.h"
+#endif /* defined __PPCE200Z7__ || defined __PPCE200ZX__ */
+
+/*
+ * I need kernel inclusion before IRQ CPU inclusion because is CPU layer that
+ * have to see Kernel API for IRQ Handling
+ */
+
+/*
+ * Kernel
+ *
+ */
+#ifdef __FP__
+#include "kernel/fp/inc/ee_kernel.h"
+#include "kernel/fp/inc/ee_irq.h"
+#endif
+
+#ifdef __EDF__
+#include "kernel/edf/inc/ee_kernel.h"
+#include "kernel/edf/inc/ee_irq.h"
+#endif
+
+#ifdef __FRSH__
+#include "kernel/frsh/inc/ee_kernel.h"
+#include "kernel/frsh/inc/ee_irq.h"
+#endif
+
+/* OO */
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || \
+ defined(__OO_ECC2__) || defined(__AS_SC4__)
+#include "kernel/oo/inc/ee_oo_kernel.h"
+#include "kernel/oo/inc/ee_oo_irq.h"
+#if defined(__MSRP__) || defined(EE_AS_OSAPPLICATIONS__)
+#include "kernel/as/inc/ee_as_kernel.h"
+
+#ifdef EE_AS_IOC__
+#include "kernel/as/inc/ee_as_ioc.h"
+/* WARNING
+ * The following file SHALL be generated by IOC Generator: if you are using
+ * Erika IOC implementation without a generator you MUST provide it in your
+ * project root. */
+#include "ioc_common.h"
+#endif /* EE_AS_IOC__ */
+#endif /* __MSRP__ || EE_AS_OSAPPLICATIONS__ */
+#endif
+
+/*
+ * CPU IRQ support
+ */
+
+#if defined __PPCE200Z7__ || defined __PPCE200ZX__
+#include "cpu/e200zx/inc/ee_irq.h"
+#endif
+
+/* kernel API inclusion */
+#include "ee_api.h"
+
+#if defined(__cplusplus)
+};
+#endif
+
+
+#endif /* INCLUDE_PKG_OS_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/ee_rtdruid_versions.h b/src/bsp/hsm/os/erika2/pkg/ee_rtdruid_versions.h
new file mode 100644
index 0000000..7a2f2c6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/ee_rtdruid_versions.h
@@ -0,0 +1,37 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise. ERIKA Enterprise is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GPLv2 + Linking Exception license (contained in the file `ee/LICENSE').
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
+ *
+ * ###*E*### */
+
+/*
+ * This file contains the version numbers indicating changes in the
+ * interface between RT-Druid and ERIKA source code. Values can be checked
+ * against RT-Druid's version in RTDRUID_CONFIGURATOR_NUMBER.
+ */
+
+#ifndef PKG_EE_RTDRUID_VERSIONS_H
+#define PKG_EE_RTDRUID_VERSIONS_H
+
+/* ORTI variables are no longer defined inside eecfg.c */
+#define RTDRUID_CONFNUM_NO_ORTI_VARS 1273
+
+/* Added syscall for ORTI service tracing */
+#define RTDRUID_CONFNUM_ORTI_SERVICE_API 1274
+
+/* Added stack address in EE_APP_SEC_INFO_T */
+#define RTDRUID_CONFNUM_STACK_IN_APP_SEC_INFO 1275
+
+/* Added support for S12G, S12XS CPU support based on the common folder */
+#define RTDRUID_CONFNUM_S12_COMMON_SUPPORT 1276
+
+#endif /* EE_RTDRUID_VERSIONS_H */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/cfg/cfg.mk
new file mode 100644
index 0000000..e5e89d8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/cfg/cfg.mk
@@ -0,0 +1,50 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.6 2007/06/01 09:00:21 pj Exp $
+
+ifeq ($(call iseeopt, __ALARMS__), yes)
+EE_SRCS += pkg/kernel/alarms/src/ee_alcancel.c
+EE_SRCS += pkg/kernel/alarms/src/ee_altick.c
+EE_SRCS += pkg/kernel/alarms/src/ee_alget.c
+EE_SRCS += pkg/kernel/alarms/src/ee_alsetabs.c
+EE_SRCS += pkg/kernel/alarms/src/ee_alsetrel.c
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_alarms.h b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_alarms.h
new file mode 100644
index 0000000..b4a0f97
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_alarms.h
@@ -0,0 +1,180 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author 2002 Paolo Gai
+ * CVS: $Id: ee_alarms.h,v 1.4 2006/12/03 22:03:53 pj Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_ALARMS_ALARMS_H__
+#define __INCLUDE_KERNEL_ALARMS_ALARMS_H__
+
+
+/*************************************************************************
+* Alarm Types
+*************************************************************************/
+
+
+/* alarm id type (signed!) */
+#ifndef EE_TYPEALARM
+#define EE_TYPEALARM EE_SREG
+#endif
+
+/* counter id type (signed!) */
+#ifndef EE_TYPECOUNTER
+#define EE_TYPECOUNTER EE_SREG
+#endif
+
+/* counter tick type (signed!) */
+#ifndef EE_TYPETICK
+#define EE_TYPETICK EE_SREG
+#endif
+
+/* notification type (signed!) */
+#ifndef EE_TYPENOTIFY
+#define EE_TYPENOTIFY EE_UINT8
+#endif
+
+
+/*************************************************************************
+* Variables defined by the application
+*************************************************************************/
+
+/* initvalue: {0, -1} */
+typedef struct {
+ EE_TYPETICK value; /* current value of the counter */
+ EE_TYPEALARM first; /* first alarm queued on the counter */
+} EE_counter_RAM_type;
+
+/* these are the different types of alarm notifications... */
+#define EE_ALARM_ACTION_TASK 0U
+#define EE_ALARM_ACTION_CALLBACK 1U
+
+/* initvalue: {a_valid_counter, a_valid_action, then you must put the correct
+ * parameters depending on the action } */
+typedef struct {
+ EE_TYPECOUNTER c; /* the counter linked to the alarm */
+
+ EE_TYPENOTIFY action;
+
+ EE_TID TaskID;
+
+ EE_VOID_CALLBACK f;
+} EE_alarm_ROM_type;
+
+/* initvalue: all zeroes --> no initialization! */
+typedef struct {
+ EE_TYPETICK cycle; /* cycle for periodic alarms */
+ EE_TYPETICK delta; /* delta expiration time (into a queue!) */
+ EE_TYPEALARM next; /* next alarm in the delta queue */
+} EE_alarm_RAM_type;
+
+/* this is the RAM part of a counter.
+ * Initvalue = an array of {0,-1} elements */
+extern EE_counter_RAM_type EE_counter_RAM[];
+
+/* this is the fixed part of the configuration of an alarm
+ * Initvalue= depends on how the alarm notification have to be configured */
+extern const EE_alarm_ROM_type EE_alarm_ROM[];
+
+/* this part is the variable part of an alarm.
+ * Initvalue: an array of {0,0,0,-1} */
+extern EE_alarm_RAM_type EE_alarm_RAM[];
+
+
+/***************************************************************************
+* Public Types
+***************************************************************************/
+
+typedef EE_TYPEALARM AlarmType;
+typedef EE_TYPECOUNTER CounterType;
+typedef EE_TYPETICK TickType;
+typedef EE_TYPETICK *TickRefType;
+
+
+/***************************************************************************
+* Implementation defined functions
+***************************************************************************/
+
+/* This function notifies a tick to a counter. That is, the counter is
+ * incremented by 1. It must be called into an ISR or into a
+ * thread notify that the event linked to the counter occurred.
+ *
+ * The function will also implement the notification of expired alarms
+ * (calling an alarm callback or activating a thread).
+ *
+ * The function is NOT atomic, and NO RESCHEDULING will take place
+ * after the execution of this function. To implement the
+ * rescheduling at task level, you can use the Schedule() function
+ * just after this notification.
+ *
+ * These functions can be called both into a thread and into an ISR.
+ */
+#ifndef __PRIVATE_COUNTER_TICK__
+void EE_alarm_CounterTick(CounterType c);
+#endif
+
+#ifndef __PRIVATE_ALARM_GET__
+void EE_alarm_GetAlarm(AlarmType AlarmID,
+ TickType *Tick);
+#endif
+
+#ifndef __PRIVATE_ALARM_SETREL__
+void EE_alarm_SetRelAlarm(AlarmType AlarmID,
+ TickType increment,
+ TickType cycle);
+#endif
+
+#ifndef __PRIVATE_ALARM_SETABS__
+void EE_alarm_SetAbsAlarm(AlarmType AlarmID,
+ TickType start,
+ TickType cycle);
+#endif
+
+#ifndef __PRIVATE_ALARM_CANCEL__
+void EE_alarm_CancelAlarm(AlarmType AlarmID);
+#endif
+
+/* Internal function */
+void EE_alarm_insert(AlarmType AlarmID,
+ TickType increment);
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_api.h
new file mode 100644
index 0000000..40c96d2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/inc/ee_api.h
@@ -0,0 +1,79 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ * CVS: $Id: ee_api.h,v 1.4 2006/12/03 22:03:53 pj Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_ALARMS_EE_API__
+#define __INCLUDE_KERNEL_ALARMS_EE_API__
+
+
+#ifdef __ALARMS__
+
+#ifndef CounterTick
+#define CounterTick EE_alarm_CounterTick
+#endif
+
+#ifndef IncrementCounter
+#define IncrementCounter EE_alarm_CounterTick
+#endif
+
+#ifndef GetAlarm
+#define GetAlarm EE_alarm_GetAlarm
+#endif
+
+#ifndef SetRelAlarm
+#define SetRelAlarm EE_alarm_SetRelAlarm
+#endif
+
+#ifndef SetAbsAlarm
+#define SetAbsAlarm EE_alarm_SetAbsAlarm
+#endif
+
+#ifndef CancelAlarm
+#define CancelAlarm EE_alarm_CancelAlarm
+#endif
+
+#endif /* __ALARMS__ */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alcancel.c b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alcancel.c
new file mode 100644
index 0000000..c4ed2c9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alcancel.c
@@ -0,0 +1,92 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alcancel.c,v 1.3 2006/12/03 22:03:53 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_ALARM_CANCEL__
+void EE_alarm_CancelAlarm(AlarmType AlarmID)
+{
+ register AlarmType current, previous;
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* to compute the relative value in ticks, we have to follow the counter
+ * delay chain */
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first;
+
+ /* check if there are alarms pending*/
+ if (current == (AlarmType)-1) {
+ /* alarm not present */
+ EE_hal_end_nested_primitive(flag);
+ return;
+ }
+
+ if (current == AlarmID) {
+ /* the alarm is the first one in the delta queue */
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first =
+ EE_alarm_RAM[AlarmID].next;
+ } else {
+ /* the alarm is not the first one in the delta queue */
+ do {
+ previous = current;
+ current = EE_alarm_RAM[current].next;
+ if (current == (AlarmType)-1) {
+ /* alarm not present */
+ EE_hal_end_nested_primitive(flag);
+ return;
+ }
+ } while (current != AlarmID);
+ EE_alarm_RAM[previous].next = EE_alarm_RAM[AlarmID].next;
+ }
+
+ if (EE_alarm_RAM[AlarmID].next != (EE_TYPEALARM)-1) {
+ EE_alarm_RAM[EE_alarm_RAM[AlarmID].next].delta +=
+ EE_alarm_RAM[AlarmID].delta;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alget.c b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alget.c
new file mode 100644
index 0000000..e050b40
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alget.c
@@ -0,0 +1,71 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alget.c,v 1.3 2006/12/03 22:03:53 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_ALARM_GET__
+void EE_alarm_GetAlarm(AlarmType AlarmID,
+ TickType *Tick)
+{
+ register AlarmType current;
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* to compute the relative value in ticks, we have to follow the counter
+ * delay chain */
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first;
+
+ if (Tick != NULL) {
+ *Tick = EE_alarm_RAM[current].delta;
+ while (current != AlarmID) {
+ current = EE_alarm_RAM[current].next;
+ *Tick += EE_alarm_RAM[current].delta;
+ }
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetabs.c b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetabs.c
new file mode 100644
index 0000000..41a3995
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetabs.c
@@ -0,0 +1,64 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alsetabs.c,v 1.3 2006/12/03 22:03:53 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_ALARM_SETABS__
+void EE_alarm_SetAbsAlarm(AlarmType AlarmID,
+ TickType start,
+ TickType cycle)
+{
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ EE_alarm_RAM[AlarmID].cycle = cycle;
+
+ EE_alarm_insert(AlarmID, start -
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c].value);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetrel.c b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetrel.c
new file mode 100644
index 0000000..6322205
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_alsetrel.c
@@ -0,0 +1,64 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alsetrel.c,v 1.3 2006/12/03 22:03:53 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_ALARM_SETREL__
+void EE_alarm_SetRelAlarm(AlarmType AlarmID,
+ TickType increment,
+ TickType cycle)
+{
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ EE_alarm_RAM[AlarmID].cycle = cycle;
+
+ /* then, insert the task into the delta queue with a value = interval */
+ EE_alarm_insert(AlarmID, increment);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_altick.c b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_altick.c
new file mode 100644
index 0000000..368a976
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/alarms/src/ee_altick.c
@@ -0,0 +1,210 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_altick.c,v 1.9 2008/07/14 10:41:58 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+void EE_alarm_insert(AlarmType AlarmID,
+ TickType increment)
+{
+ register AlarmType current, previous;
+
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first;
+
+ if (current == (AlarmType)-1) {
+ /* the alarm becomes the first into the delta queue */
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first = AlarmID;
+ } else if (EE_alarm_RAM[current].delta > increment) {
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c].first = AlarmID;
+ EE_alarm_RAM[current].delta -= increment;
+ } else {
+ /* the alarm is not the first into the delta queue */
+
+ /* follow the delta chain until I reach the right place */
+ do {
+ increment -= EE_alarm_RAM[current].delta;
+ previous = current;
+ current = EE_alarm_RAM[current].next;
+ } while ((current != (AlarmType)-1) && (EE_alarm_RAM[current].delta <= increment));
+
+ /* insert the alarm between previous and current */
+ if (current != (AlarmType)-1) {
+ EE_alarm_RAM[current].delta -= increment;
+ }
+ EE_alarm_RAM[previous].next = AlarmID;
+ }
+
+ EE_alarm_RAM[AlarmID].delta = increment;
+ EE_alarm_RAM[AlarmID].next = current;
+}
+
+#ifndef __PRIVATE_COUNTER_TICK__
+void EE_alarm_CounterTick(CounterType c)
+{
+ register EE_TYPEALARM current;
+ register EE_TID t;
+ register EE_FREG flag;
+
+#ifdef __RN_TASK__
+ int rn_return_val;
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* increment the counter value */
+ EE_counter_RAM[c].value++;
+
+ /* if there are queued alarms */
+ if (EE_counter_RAM[c].first != (EE_TYPEALARM)-1) {
+ /* decrement first queued alarm delta */
+ EE_alarm_RAM[EE_counter_RAM[c].first].delta--;
+
+ /* execute all the alarms with counter 0 */
+ current = EE_counter_RAM[c].first;
+ while (EE_alarm_RAM[current].delta == 0) {
+ /* remove the current entry */
+ EE_counter_RAM[c].first = EE_alarm_RAM[current].next;
+
+ /* the alarm is cyclic? */
+ if (EE_alarm_RAM[current].cycle) {
+ /* enqueue it again
+ * note: this can modify EE_counter_RAM[c].first!!! see (*)
+ */
+ EE_alarm_insert(current, EE_alarm_RAM[current].cycle);
+ }
+
+ /* execute it */
+ switch (EE_alarm_ROM[current].action) {
+ case EE_ALARM_ACTION_TASK:
+ /* activate the task; NOTE: no preemption at all...
+ * This code was directly copied from ActivateTask */
+
+ t = EE_alarm_ROM[current].TaskID;
+
+ /* this code is similar to the first part of thread_activate */
+#ifdef __RN_TASK__
+ if ((EE_UTID)t & (EE_UTID)EE_REMOTE_TID) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1U;
+ /* forward the request to another CPU whether the thread do
+ * not become to the current CPU */
+ rn_return_val = EE_rn_send((EE_SREG)EE_MARK_REMOTE_TID(t),
+ EE_RN_TASK, par);
+ } else {
+#endif
+
+
+
+#if defined(__FRSH__) || defined(__HR__)
+
+ {
+ register EE_TIME tmp_time;
+ tmp_time = EE_hal_gettime();
+
+
+ if (EE_th[t].nact == 0) {
+#ifdef __HR__
+ if (EE_ct[EE_th[t].vres].sched_algo == EE_SCHED_EDF) {
+ EE_th[t].absdline = tmp_time + EE_th[t].reldline;
+ }
+
+ if (EE_hr_updatecapacity(t, tmp_time) == EE_UC_InsertRDQueue) {
+#else
+ if (EE_frsh_updatecapacity(t, tmp_time) == EE_UC_InsertRDQueue) {
+#endif
+ EE_rq_insert(t);
+ }
+#ifdef __HR__
+ else {
+ /* EE_UC_InsertedRCGQueue */
+ EE_insert_in_vres(t);
+ }
+ EE_vres[EE_th[t].vres].act_tasks++;
+#endif
+ EE_th[t].status = EE_TASK_READY;
+ }
+ EE_th[t].nact++;
+ }
+#else
+ if (EE_th_nact[t] == (EE_TYPENACT)0U) {
+#ifdef __EDF__
+ /* compute the deadline */
+ EE_th_absdline[t] = EE_hal_gettime() + EE_th_reldline[t];
+#endif
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_READY;
+#endif
+ EE_rq_insert(t);
+ }
+ EE_th_nact[t]++;
+#endif
+
+
+
+
+#ifdef __RN_TASK__
+ }
+#endif
+
+ break;
+
+ case EE_ALARM_ACTION_CALLBACK:
+ (EE_alarm_ROM[current].f)();
+ break;
+ default:
+ /* Invalid action: this should never happen, as `action' is
+ * initialized by RT-Druid */
+ break;
+ }
+
+ /* (*) here we need EE_counter_RAM[c].first again... */
+ if ((current = EE_counter_RAM[c].first) == (EE_TYPEALARM)-1) {
+ break;
+ }
+ }
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/cfg.mk
new file mode 100644
index 0000000..33a2002
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/cfg.mk
@@ -0,0 +1,113 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2011 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+
+ifeq ($(call iseeopt, __AS_SC4__), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_mem_prot.c
+EE_SRCS += pkg/kernel/as/src/ee_as_base.c
+EE_SRCS += pkg/kernel/as/src/ee_as_osapp.c
+endif
+
+ifeq ($(call iseeopt, __OO_BCC1__), yes)
+KERNEL_OO=yes
+endif
+ifeq ($(call iseeopt, __OO_BCC2__), yes)
+KERNEL_OO=yes
+endif
+ifeq ($(call iseeopt, __OO_ECC1__), yes)
+KERNEL_OO=yes
+endif
+ifeq ($(call iseeopt, __OO_ECC2__), yes)
+KERNEL_OO=yes
+endif
+
+ifeq ($(and $(call iseeopt, __MSRP__), $(KERNEL_OO)), yes)
+
+#
+# Temporary workaround, to make compile Multicore PPC,
+# until full AS porting will be completed!!!
+#
+ifneq ($(or $(call iseeopt, __PPCE200ZX__), $(call iseeopt, __PPCE200Z7__)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_multicore.c
+endif # !(__PPCE200ZX__ || __PPCE200Z7__)
+
+ifeq ($(call iseeopt, EE_AS_USER_SPINLOCKS__), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_spinlocks.c
+endif # EE_AS_USER_SPINLOCKS__
+
+ifeq ($(call iseeopt, EE_AS_RPC__), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_rpc.c
+endif # EE_AS_RPC__
+endif # __MSRP__
+
+ifeq ($(and $(call iseeopt, EE_AS_IOC__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_ioc.c
+endif # EE_AS_IOC__ && KERNEL_OO
+
+ifneq ($(call iseeopt, __AS_SC4__), yes)
+
+ifeq ($(or $(call iseeopt, __MSRP__), $(call iseeopt, EE_AS_OSAPPLICATIONS__), $(call iseeopt, EE_SERVICE_PROTECTION__)), yes)
+ifeq ($(KERNEL_OO), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_base.c
+endif # KERNEL_OO
+endif # __MSRP__ || EE_AS_OSAPPLICATIONS__ || EE_AS_SERVICE_PROTECTION__
+
+ifeq ($(and $(call iseeopt, EE_AS_OSAPPLICATIONS__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_osapp.c
+endif # EE_AS_OSAPPLICATIONS__
+
+ifeq ($(and $(call iseeopt, __EE_MEMORY_PROTECTION__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_mem_prot.c
+endif # __EE_MEMORY_PROTECTION__ && KERNEL_OO
+
+ifeq ($(and $(call iseeopt, EE_AS_SCHEDULETABLES__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_schedule_tables.c
+endif # EE_AS_SCHEDULETABLES__ && KERNEL_OO
+
+ifeq ($(and $(call iseeopt, EE_TIMING_PROTECTION__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_timing_prot.c
+endif # EE_TIMING_PROTECTION__ && KERNEL_OO
+
+ifeq ($(and $(call iseeopt, EE_AS_HAS_PROTECTIONHOOK__), $(KERNEL_OO)), yes)
+EE_SRCS += pkg/kernel/as/src/ee_as_prot_error.c
+endif # EE_AS_HAS_PROTECTIONHOOK__ && KERNEL_OO
+
+endif # !__AS_SC4__
+
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/generate_syscall.sh b/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/generate_syscall.sh
new file mode 100755
index 0000000..d74dbe8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/cfg/generate_syscall.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2011 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+# Author: 2011, Bernardo Dal Seno
+
+# This script generates all system call defintions to standard output,
+# using templates specified by the definitions of the functions
+# EE_SYSCALL_0, EE_SYSCALL_1... Such functions are specific for each
+# architecture, and are defined in scripts contained in pkg/cpu/XXX/cfg.
+# One of those script must be sourced (i.e., executed with the shell command
+# "source") before executing this script.
+
+set -e
+
+if [ "$(type -t EE_SYSCALL_0)" != "function" ]; then
+ echo >&2 "No template definitions"
+ echo >&2 "Please source the architecture-specific generate_syscall_XXX.sh"
+ exit 2
+fi
+
+EE_SYSCALL_1 StatusType ActivateTask TaskType TaskID EE_ID_ActivateTask
+EE_SYSCALL_0 StatusType TerminateTask EE_ID_TerminateTask
+EE_SYSCALL_1 StatusType ChainTask TaskType TaskID EE_ID_ChainTask
+EE_SYSCALL_0 StatusType Schedule EE_ID_Schedule
+EE_SYSCALL_0 StatusType ForceSchedule EE_ID_ForceSchedule
+EE_SYSCALL_1 StatusType GetTaskID TaskRefType TaskID EE_ID_GetTaskID
+EE_SYSCALL_2 StatusType GetTaskState TaskType TaskID TaskStateRefType State EE_ID_GetTaskState
+EE_SYSCALL_0 void EnableAllInterrupts EE_ID_EnableAllInterrupts
+EE_SYSCALL_0 void DisableAllInterrupts EE_ID_DisableAllInterrupts
+EE_SYSCALL_0 void ResumeAllInterrupts EE_ID_ResumeAllInterrupts
+EE_SYSCALL_0 void SuspendAllInterrupts EE_ID_SuspendAllInterrupts
+EE_SYSCALL_0 void ResumeOSInterrupts EE_ID_ResumeOSInterrupts
+EE_SYSCALL_0 void SuspendOSInterrupts EE_ID_SuspendOSInterrupts
+echo '#ifndef __OO_NO_RESOURCES__'
+EE_SYSCALL_1 StatusType GetResource ResourceType ResID EE_ID_GetResource
+EE_SYSCALL_1 StatusType ReleaseResource ResourceType ResID EE_ID_ReleaseResource
+echo '#endif /* ! __OO_NO_RESOURCES__ */'
+echo '#ifndef __OO_NO_EVENTS__'
+EE_SYSCALL_2 StatusType SetEvent TaskType TaskID EventMaskType Mask EE_ID_SetEvent
+EE_SYSCALL_1 StatusType ClearEvent EventMaskType Mask EE_ID_ClearEvent
+EE_SYSCALL_2 StatusType GetEvent TaskType TaskID EventMaskRefType Event EE_ID_GetEvent
+EE_SYSCALL_1 StatusType WaitEvent EventMaskType Mask EE_ID_WaitEvent
+echo '#endif /* ! __OO_NO_EVENTS__ */'
+echo '#ifndef __OO_NO_ALARMS__'
+EE_SYSCALL_1 void CounterTick CounterType c EE_ID_counter_tick
+EE_SYSCALL_2 StatusType GetAlarmBase AlarmType AlarmID AlarmBaseRefType Info EE_ID_GetAlarmBase
+EE_SYSCALL_2 StatusType GetAlarm AlarmType AlarmID TickRefType Tick EE_ID_GetAlarm
+EE_SYSCALL_3 StatusType SetRelAlarm AlarmType AlarmID TickType increment TickType cycle EE_ID_SetRelAlarm
+EE_SYSCALL_3 StatusType SetAbsAlarm AlarmType AlarmID TickType start TickType cycle EE_ID_SetAbsAlarm
+EE_SYSCALL_1 StatusType CancelAlarm AlarmType AlarmID EE_ID_CancelAlarm
+echo '#endif /* ! __OO_NO_ALARMS__ */'
+EE_SYSCALL_0 AppModeType GetActiveApplicationMode EE_ID_GetActiveApplicationMode
+EE_SYSCALL_1 StatusType StartOS AppModeType Mode EE_ID_StartOS
+EE_SYSCALL_1 void ShutdownOS StatusType Error EE_ID_ShutdownOS
+echo '#ifdef __OO_SEM__'
+EE_SYSCALL_1 StatusType WaitSem SemRefType Sem EE_ID_WaitSem
+EE_SYSCALL_1 void WaitSem SemRefType Sem EE_ID_WaitSem
+EE_SYSCALL_1 int TryWaitSem SemRefType Sem EE_ID_TryWaitSem
+EE_SYSCALL_1 StatusType PostSem SemRefType Sem EE_ID_PostSem
+EE_SYSCALL_1 int GetValueSem SemRefType Sem EE_ID_GetValueSem
+echo '#endif /* __OO_SEM__ */'
+
+#This should go into a different header
+echo
+echo '#ifdef __OO_ORTI_SERVICETRACE__'
+echo '#if defined(RTDRUID_CONFIGURATOR_NUMBER) \'
+echo ' && RTDRUID_CONFIGURATOR_NUMBER >= RTDRUID_CONFNUM_ORTI_SERVICE_API'
+EE_SYSCALL_1 void EE_ORTI_ext_set_service EE_UINT8 srv EE_ID_ORTI_ext_set_service
+echo '#else /* __EE_MEMORY_PROTECTION__ && RTDRUID_CONFNUM_ORTI_SERVICE_API */'
+echo '__INLINE__ void EE_ORTI_ext_set_service(EE_UINT8 srv)'
+echo '{'
+echo '}'
+echo '#endif /* else __EE_MEMORY_PROTECTION__ && RTDRUID_CONFNUM_ORTI_SERVICE_API */'
+echo '#endif /* __OO_ORTI_SERVICETRACE__ */'
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_api.h
new file mode 100644
index 0000000..2b93295
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_api.h
@@ -0,0 +1,480 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_api.h
+ * @brief Autosar API declaration
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#ifndef INCLUDE_EE_KERNEL_AS_API_H__
+#define INCLUDE_EE_KERNEL_AS_API_H__
+
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* This declaration is needed by eecfg.c for syscalls table definitions.
+ * Usually it is declared as internal kernel funtion, unfortunatly eecfg.c
+ * include only public layer (ee.h) so I have to put this somewere in a
+ * public included file */
+extern void EE_thread_not_terminated(void);
+
+/* Stop ee_kernel_text section */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following code belong to ERIKA API section ee_api_text */
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/***************************************************************************
+* 13.3 Interrupt handling
+***************************************************************************/
+
+/* 13.3.2.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_ENABLEALLINTERRUPTS__
+void EnableAllInterrupts(void);
+#endif /* ! __PRIVATE_ENABLEALLINTERRUPTS__ */
+
+/* 13.3.2.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_DISABLEALLINTERRUPTS__
+void DisableAllInterrupts(void);
+#endif /* ! __PRIVATE_DISABLEALLINTERRUPTS__ */
+
+/* 13.3.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEALLINTERRUPTS__
+void ResumeAllInterrupts(void);
+#endif /* ! __PRIVATE_RESUMEALLINTERRUPTS__ */
+
+/* 13.3.2.4: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDALLINTERRUPTS__
+void SuspendAllInterrupts(void);
+#endif /* ! __PRIVATE_SUSPENDALLINTERRUPTS__ */
+
+/* 13.3.2.5: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEOSINTERRUPTS__
+void ResumeOSInterrupts(void);
+#endif /* ! __PRIVATE_RESUMEOSINTERRUPTS__ */
+
+/* 13.3.2.6: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDOSINTERRUPTS__
+void SuspendOSInterrupts(void);
+#endif /* ! __PRIVATE_SUSPENDOSINTERRUPTS__ */
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/* 13.2.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.2.3.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_ACTIVATETASK__
+StatusType ActivateTask(TaskType TaskID);
+#endif /* __PRIVATE_ACTIVATETASK__ */
+
+/* 13.2.3.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_TERMINATETASK__
+StatusType TerminateTask(void);
+#endif /* __PRIVATE_TERMINATETASK__ */
+
+/* 13.2.3.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_CHAINTASK__
+StatusType ChainTask(TaskType TaskID);
+#endif /* __PRIVATE_CHAINTASK__ */
+
+/* 13.2.3.4: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SCHEDULE__
+StatusType Schedule(void);
+#endif /* __PRIVATE_SCHEDULE__ */
+
+/* Needed for counters (see later) */
+#ifndef __PRIVATE_FORCESCHEDULE__
+StatusType ForceSchedule(void);
+#endif /* __PRIVATE_FORCESCHEDULE__ */
+
+/***************************************************************************
+* 13.4 Resource management
+***************************************************************************/
+
+#ifndef __OO_NO_RESOURCES__
+
+/* 13.4.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.4.3.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETRESOURCE__
+StatusType GetResource(ResourceType ResID);
+#endif /* __PRIVATE_GETRESOURCE__ */
+
+/* 13.4.3.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RELEASERESOURCE__
+StatusType ReleaseResource(ResourceType ResID);
+#endif /* __PRIVATE_RELEASERESOURCE__ */
+
+#endif /* !__OO_NO_RESOURCES__ */
+
+/***************************************************************************
+* 13.5 Event control
+***************************************************************************/
+
+/* 13.5.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* see also internal.h */
+/* 13.5.3.1: ECC1, ECC2 */
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+
+#ifndef __PRIVATE_SETEVENT__
+StatusType SetEvent(TaskType TaskID,
+ EventMaskType Mask);
+#endif /* __PRIVATE_SETEVENT__ */
+
+/* 13.5.3.2: ECC1, ECC2 */
+#ifndef __PRIVATE_CLEAREVENT__
+StatusType ClearEvent(EventMaskType Mask);
+#endif /* __PRIVATE_CLEAREVENT__ */
+
+/* 13.5.3.4: ECC1, ECC2 */
+#ifndef __PRIVATE_WAITEVENT__
+StatusType WaitEvent(EventMaskType Mask);
+#endif /* __PRIVATE_WAITEVENT__ */
+
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+/***************************************************************************
+* 13.6 Alarms
+***************************************************************************/
+
+#ifndef __OO_NO_ALARMS__
+
+/* Implementation defined functions */
+
+/* Counter initialization
+ * ----------------------
+ *
+ * Counter initialization is done at initialization time OUTSIDE
+ * StartOS. Since software counters are stored in RAM, their
+ * initialization values are typically set to 0. That also conforms to
+ * note 10 page 43 of the specification version 2.2.1 that says:
+ *
+ * "Counters are - if possible - set to zero by the system
+ * initialization before alarms are autostarted. Exception: calendar
+ * timers, etc. For autostarted alarms, all values are relative
+ * values.
+ *
+ */
+
+/*
+ * AS 4.0 OS SWS 8.4.16
+ * AS OS requirement OS399:
+ *
+ * This function notifies a tick to a counter. That is, the counter is
+ * incremented by 1.
+ *
+ * The function will also implement the notification of expired alarms
+ * (calling an alarm callback, setting an event, or activating a
+ * task).
+ *
+ * And DO RESCHEDULING.
+ * see also internal.h
+ */
+#if (!defined(__PRIVATE_INCREMENTCOUNTER__)) && (EE_MAX_COUNTER > 0U)
+StatusType IncrementCounter(CounterType CounterID);
+#endif /* __PRIVATE_INCREMENTCOUNTER__ */
+
+#ifndef __PRIVATE_GETALARMBASE__
+StatusType GetAlarmBase(AlarmType AlarmID,
+ AlarmBaseRefType Info);
+#endif /* __PRIVATE_GETALARMBASE__ */
+
+/* 13.6.3.2 BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETALARM_
+StatusType GetAlarm(AlarmType AlarmID,
+ TickRefType Tick);
+#endif /* __PRIVATE_GETALARM_ */
+
+/* 13.6.3.3 BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2 */
+#ifndef __PRIVATE_SETRELALARM__
+StatusType SetRelAlarm(AlarmType AlarmID,
+ TickType increment,
+ TickType cycle);
+#endif /* __PRIVATE_SETRELALARM__ */
+
+/* 13.6.3.4 BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2 */
+#ifndef __PRIVATE_SETABSALARM__
+StatusType SetAbsAlarm(AlarmType AlarmID,
+ TickType start,
+ TickType cycle);
+#endif /* __PRIVATE_SETABSALARM__ */
+
+/* 13.6.3.5 BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_CANCELALARM__
+StatusType CancelAlarm(AlarmType AlarmID);
+#endif
+
+#endif /* !__OO_NO_ALARMS__ */
+
+/***************************************************************************
+* 13.7 Operating system execution control
+***************************************************************************/
+
+/***************************************************************************
+* 13.7 Operating system execution control
+***************************************************************************/
+
+/* 13.7.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SHUTDOWNOS__
+void ShutdownOS(StatusType Error);
+#endif /* !__PRIVATE_SHUTDOWNOS__ */
+
+#ifdef EE_AS_SCHEDULETABLES__
+/*******************************************************************************
+ * Schedule Tables API
+ ******************************************************************************/
+/** 8.4.8 StartScheduleTableRel [OS347]
+ *
+ * @brief This service starts the processing of a schedule table at "Offset"
+ * relative to the "Now" value on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID Schedule table to be started.
+ *
+ * @param Offset Number of ticks on the counter before the the schedule table
+ * processing is started
+ *
+ * @return StatusType -
+ * E_OK: No Error
+ * E_OS_ID: (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE: (only in EXTENDED status): Offset is greater than
+ * (OsCounterMaxAllowedValue - InitialOffset) or is equal to 0.
+ * E_OS_STATE: Schedule table was already started.
+ */
+StatusType StartScheduleTableRel(ScheduleTableType ScheduleTableID,
+ TickType Offset);
+
+/** 8.4.9 StartScheduleTableAbs [SWS_Os_00358]
+ *
+ * @brief This service starts the processing of a schedule table at an absolute
+ * value "Start" on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID: Schedule table to be started
+ * @param Start: Absolute counter tick value at which the schedule table is
+ * started
+ *
+ * @return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE (only in EXTENDED status): "Start" is greater than
+ * OsCounterMaxAllowedValue
+ * E_OS_STATE: Schedule table was already started Description:
+ */
+StatusType StartScheduleTableAbs(ScheduleTableType ScheduleTableID,
+ TickType Start);
+
+/** 8.4.10 StopScheduleTable [SWS_Os_00006]
+ *
+ * @brief This service cancels the processing of a schedule table immediately
+ * at any point while the schedule table is running.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID: Schedule table to be stopped
+ *
+ * @return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_NOFUNC: Schedule table was already stopped.
+ */
+StatusType StopScheduleTable(ScheduleTableType ScheduleTableID);
+
+/* The following primitives are available only on local objects */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+/** 8.4.11 NextScheduleTable [SWS_Os_00191]
+ *
+ * @brief This service switches the processing from one schedule table to
+ * another schedule table.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID_From: Currently processed schedule table
+ * @param ScheduleTableID_To: Schedule table that provides its series of
+ * expiry points
+ *
+ * @return StatusType
+ * E_OK: No error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID_From or
+ * ScheduleTableID_To not valid.
+ * E_OS_NOFUNC: ScheduleTableID_From not started
+ * E_OS_STATE: ScheduleTableID_To is started or next
+ *
+ * (SRS_Os_00099)
+ */
+StatusType NextScheduleTable(ScheduleTableType ScheduleTableID_From,
+ ScheduleTableType ScheduleTableID_To);
+
+/** 8.4.13 SyncScheduleTable [SWS_Os_00199]
+ *
+ * @brief This service provides the schedule table with a synchronization
+ * count and start synchronization.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID (in): Schedule table to be synchronized
+ * @param Value (in): The current value of the synchronization counter
+ *
+ * @return StatusType:
+ * E_OK: No errors
+ * E_OS_ID (only in EXTENDED status): The ScheduleTableID was not valid or
+ * schedule table can not be synchronized (OsScheduleTblSyncStrategy not
+ * set or OsScheduleTblSyncStrategy = IMPLICIT)
+ * E_OS_VALUE (only in EXETENDED status): The <Value> is out of range.
+ * E_OS_STATE: The state of schedule table <ScheduleTableID> is equal to
+ * SCHEDULETABLE_STOPPED
+ * (SRS_Os_11002)
+ */
+StatusType SyncScheduleTable(ScheduleTableType ScheduleTableID,
+ TickType Value);
+
+/* The following primitives are available only on local objects */
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/*******************************************************************************
+ * OSApplication API
+ ******************************************************************************/
+
+/**
+ * @brief This service terminates the OS-Application to which the calling
+ * Task/Category 2 ISR/application specific error hook belongs.
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ * @param Application The identifier of the OS-Application to be terminated.
+ * If the caller belongs to <Application> the call results in a self
+ * termination.
+ * @param RestartOption Either RESTART for doing a restart of the
+ * OS-Application or NO_RESTART if OS-Application shall not be restarted.
+ * @return E_OK: No errors
+ * E_OS_ID: <Application> was not valid (only in EXTENDED status)
+ * E_OS_VALUE: <RestartOption> was neither RESTART nor NO_RESTART
+ * (only in EXTENDED status)
+ * E_OS_ACCESS: The caller does not have the right to terminate
+ * <Application> (only in EXTENDED status)
+ * E_OS_STATE: The state of <Application> does not allow
+ * terminating <Application>
+ */
+StatusType TerminateApplication(ApplicationType Application,
+ RestartType RestartOption);
+
+/**
+ * @brief This service sets the own state of an OS-Application from
+ * APPLICATION_RESTARTING to APPLICATION_ACCESSIBLE. (Supposed to be called
+ * by OS-Application restarting TASK).
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ * @return E_OK: No errors
+ * E_OS_STATE: The OS-Application of the caller is in the wrong state
+ */
+StatusType AllowAccess(void);
+
+/*******************************************************************************
+ * Memory Protection Support
+ ******************************************************************************/
+#ifdef __EE_MEMORY_PROTECTION__
+#if defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+
+/**
+ * @brief A (trusted or non-trusted) OS-Application uses this service to call
+ * a trusted function
+ * Sync/Async: Depends on called function. If called function is synchronous
+ * then service is synchronous. May cause rescheduling.
+ * Reentrancy: Reentrant.
+ * @param FunctionIndex Index of the function to be called.
+ * @param FunctionParams Pointer to the parameters for the function - specified
+ * by the FunctionIndex - to be called. If no parameters are provided,
+ * a NULL pointer has to be passed.
+ * @return StatusType E_OK: No Error E_OS_SERVICEID: No function defined for
+ * this index
+ */
+StatusType CallTrustedFunction(TrustedFunctionIndexType FunctionIndex,
+ TrustedFunctionParameterRefType FunctionParams);
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#if defined(EE_AS_USER_SPINLOCKS__) && (!defined(EE_PRIVATE_SPINLOCK__))
+StatusType GetSpinlock(SpinlockIdType SpinlockId);
+StatusType ReleaseSpinlock(SpinlockIdType SpinlockId);
+StatusType TryToGetSpinlock(SpinlockIdType SpinlockId,
+ TryToGetSpinlockType *Success);
+
+#endif /* EE_AS_USER_SPINLOCKS__ && !EE_PRIVATE_SPINLOCK__ */
+
+#if (!defined(__PRIVATE_SHUTDOWNOS__)) && defined(EE_AS_RPC__)
+void ShutdownAllCores(StatusType Error);
+#endif /* !__PRIVATE_SHUTDOWNOS__ && EE_AS_RPC__ */
+
+/* Stop ee_api_text section */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* INCLUDE_EE_KERNEL_AS_API_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_inline.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_inline.h
new file mode 100644
index 0000000..b2efd5c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_inline.h
@@ -0,0 +1,113 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_inline.h
+ * @brief Kernel API Implementation Inline For Autosar Multicore Support
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#ifndef INCLUDE_EE_KERNEL_AS_INLINE__
+#define INCLUDE_EE_KERNEL_AS_INLINE__
+
+#ifdef __MSRP__
+
+/* EG: The following should have been declared in ee_as_internal.h,
+ * but in-line services implementation force me to declare it here. */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief counter for Autosar cores started (OS_CORE_ID_MASTER is always an
+ * AUTOSAR by default) */
+extern EE_UREG volatile EE_SHARED_IDATA EE_as_core_started;
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief mask for non Autosar cores started */
+extern EE_UREG volatile EE_SHARED_UDATA EE_as_not_as_core_mask;
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifndef EE_PRIVATE_GETNUMBEROFACTIVATEDCORES__
+__INLINE__ EE_UINT32 __ALWAYS_INLINE__
+EE_as_GetNumberOfActivatedCores(void)
+{
+ /* EG: XXX Add Service Protection? (I think is just overkilling, can we
+ * just count this as features extension?) */
+ /* Both assignment to enable smart debuggers to notice the entry and
+ * exit from getactiveapplicationmode.
+ * Note that the variable is volatile, so both the writings succeeds */
+ /* [OS673]: The return value of GetNumberOfActivatedCores shall be less or
+ * equal to the configured value of "OsNumberOfCores". */
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETNUMBEROFACTIVATEDCORES);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETNUMBEROFACTIVATEDCORES);
+ return EE_as_core_started;
+}
+#endif /* EE_PRIVATE_GETNUMBEROFACTIVATEDCORES__ */
+
+#ifndef EE_PRIVATE_GETCOREID__
+__INLINE__ CoreIdType __ALWAYS_INLINE__ EE_as_GetCoreID(void)
+{
+ /* [OS675] The function GetCoreID shall return the unique logical CoreID of
+ * the core on which the function is called. The mapping of physical cores
+ * to logical CoreIDs is implementation specific. (BSW4080001) */
+ register CoreIdType core_id;
+
+ /* XXX: CoreID service trace doesn't work, because the tracing variable should
+ * be shared or dispatched beetwen cores. */
+ /* EE_ORTI_set_service_in(EE_SERVICETRACE_GETCOREID); */
+ core_id = (CoreIdType)EE_hal_get_core_id();
+ /* EE_ORTI_set_service_out(EE_SERVICETRACE_GETCOREID); */
+ return core_id;
+}
+#endif /* EE_PRIVATE_GETCOREID__ */
+
+#endif /* __MSRP__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_INLINE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_internal.h
new file mode 100644
index 0000000..a292057
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_internal.h
@@ -0,0 +1,457 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_internal.h
+ * @brief Internals for Autosar layer
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#ifndef PKG_KERNEL_AS_INC_EE_AS_INTERNAL_H
+#define PKG_KERNEL_AS_INC_EE_AS_INTERNAL_H
+
+#include "kernel/as/inc/ee_as_kernel.h"
+
+#ifdef EE_AS_USER_SPINLOCKS__
+/*******************************************************************************
+ * Spinlock Internal Clean-Up
+ ******************************************************************************/
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__
+EE_as_has_spinlocks_locked(EE_TID tid)
+{
+ SpinlockIdType const spinlock_id = EE_as_spinlocks_last[EE_CURRENTCPU];
+
+ return (spinlock_id != INVALID_SPINLOCK) &&
+ (EE_as_spinlocks_locker_task_or_isr2[spinlock_id] == tid);
+}
+
+/* Internal Clean-up function */
+SpinlockIdType EE_as_release_all_spinlocks(EE_TID tid);
+
+#else /* EE_AS_USER_SPINLOCKS__ */
+#define EE_as_release_all_spinlocks(tid) ((void)0U)
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+/*******************************************************************************
+ * Schedule Tables Utilities
+ ******************************************************************************/
+#ifdef EE_AS_SCHEDULETABLES__
+/* Utilities inline functions to check ticks and deviation values */
+__INLINE__ TickType __ALWAYS_INLINE__ EE_as_tick_min(TickType t1,
+ TickType t2)
+{
+ if (t1 <= t2) {
+ return t1;
+ } else {
+ return t2;
+ }
+}
+
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_as_abs(TickType t)
+{
+ if (t < EE_TYPETICK_HALF_VALUE) {
+ return t;
+ } else {
+ return -t;
+ }
+}
+
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#ifdef EE_AS_RPC__
+/*******************************************************************************
+ * Synchronous Remote Procedure Calls
+ ******************************************************************************/
+/** @brief Macro used to check if an id is a remote id */
+#define EE_AS_ID_REMOTE(id) ((((EE_UINT32)(id)) & \
+ (EE_UINT32)EE_REMOTE_TID) != 0U)
+/** @brief Macro used to unmark a remote id */
+#define EE_AS_UNMARK_REMOTE_ID(id) (((EE_UINT32)(id)) & (~EE_REMOTE_TID))
+
+/** @brief define that identify an invalid ServiceId */
+#define INVALID_SERVICE_ID ((OSServiceIdType)-1)
+#define INVALID_ERROR ((StatusType)-1)
+
+/** @brief RPC Handler to be called inside IIRQ handler */
+extern void EE_as_rpc_handler(void);
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following code belong to ERIKA API section ee_api_text */
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __EE_MEMORY_PROTECTION__
+/** @brief The following implement a synchronous RPC kernel primitive from
+ * "user space" (so it's a syscall). */
+extern StatusType EE_as_rpc_from_us(OSServiceIdType ServiceId,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3);
+#else /* __EE_MEMORY_PROTECTION__ */
+__INLINE__ StatusType __ALWAYS_INLINE__ EE_as_rpc_from_us(OSServiceIdType
+ ServiceId,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3)
+{
+ StatusType ev;
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+
+ ev = EE_as_rpc(ServiceId, param1, param2, param3);
+ EE_hal_end_nested_primitive(flag);
+ return ev;
+}
+#endif /* __EE_MEMORY_PROTECTION__ */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* EE_AS_RPC__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/*******************************************************************************
+ * OSApplication Utilities
+ ******************************************************************************/
+
+/** @brief Used to terminate current OS-Application. */
+void EE_as_terminate_current_app_task(void);
+
+/** @brief Used to terminate current OS-Application. */
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+__INLINE__ void __ALWAYS_INLINE__ EE_as_terminate_current_app(void)
+{
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ /* We are in a TASK */
+ EE_as_terminate_current_app_task();
+ } else {
+ /* We are in the an ISR2 */
+ (void)EE_as_TerminateISR2();
+ }
+}
+#else /* EE_MAX_ISR2 > 0 */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_terminate_current_app(void)
+{
+ /* There are no ISR2: We are in a TASK */
+ EE_as_terminate_current_app_task();
+}
+#endif /* EE_MAX_ISR2 > 0 */
+
+/**
+ * @brief Supposed to be called by EE_as_TerminateISR2 to restore trackin
+ * OSApplication global variable and eventually terminate stacked.
+ */
+void EE_as_after_IRQ_interrupted_app(ApplicationType interrupted_app);
+
+/* @brief Function determines the currently running OS-Application.
+ * (a unique identifier has to be allocated to each application).
+ */
+#if 0
+ApplicationType EE_as_GetApplicationID_internal(void);
+#endif
+
+/** @brief his service determines if the OS-Applications, given by ApplID, is
+ * allowed to use the IDs of a Task, ISR, Resource, Counter, Alarm or
+ * Schedule Table in API calls. */
+ObjectAccessType EE_as_CheckObjectAccess_internal(ApplicationType ApplID,
+ ObjectTypeType ObjectType,
+ EE_UTID ObjectID);
+
+/** @brief his service determines the OS-Applications to which the
+ * ID of a Task, ISR, Resource, Counter, Alarm or Schedule Table belong to. */
+ApplicationType EE_as_CheckObjectOwnership_internal(ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID);
+
+/** @brief Internal part of TerminateApplication service */
+void EE_as_TerminateApplication_internal(ApplicationType Application,
+ RestartType RestartOption);
+
+/* THESE HAL FUNCTIONS DECLARATION ARE PUT HERE BECAUSE SIGNATURE DEPENDS ON
+ * AS KERNEL TYPES */
+
+/** @brief Call application hook with right privileges */
+void EE_hal_call_app_hook(EE_HOOKTYPE hook,
+ ApplicationType app);
+
+/** @brief Call status application hook with right privileges */
+void EE_hal_call_app_status_hook(StatusType Error,
+ EE_STATUSHOOKTYPE
+ status_hook,
+ ApplicationType app);
+
+/** @brief Utility macro used to transform a Application ID in a bit mask */
+#define EE_APP_TO_MASK(app_id) ((EE_TYPEACCESSMASK)1U << (app_id))
+
+#ifdef EE_SERVICE_PROTECTION__
+/*******************************************************************************
+ * OSApplication Service Protection Access Data Structures
+ ******************************************************************************/
+/* [OS056] If an OS-object identifier is the parameter of an Operating System
+ * module's system service, and no sufficient access rights have been assigned
+ * to this OS-object at configuration time
+ * (Parameter Os[...]AccessingApplication) to the calling Task/Category 2 ISR,
+ * the Operating System module's system service shall return E_OS_ACCESS.
+ * (BSW11001, BSW11010, BSW11013) */
+/* [OS448]: The Operating System module shall prevent access of OS-Applications,
+ * trusted or non-trusted, to objects not belonging to this OS-Application,
+ * except access rights for such objects are explicitly granted by
+ * configuration.
+ */
+/* [OS504] The Operating System module shall deny access to Operating System
+ * objects from other OS-Applications to an OS-Application which is not in
+ * state APPLICATION_ACCESSIBLE. */
+/* [OS509] If a service call is made on an Operating System object that is owned
+ * by another OS-Application without state APPLICATION_ACCESSIBLE,
+ * then the Operating System module shall return E_OS_ACCESS. */
+
+/** @var Contains access rules for TASKs */
+extern EE_TYPEACCESSMASK const EE_as_task_access_rules[] /*EE_MAX_TASK*/;
+
+/** @var Contains access rules for ISRs */
+extern EE_TYPEACCESSMASK const EE_as_isr_access_rules[] /*EE_MAX_ISR_ID*/;
+
+#ifndef __OO_NO_RESOURCES__
+/** @var Contains access rules for RESOURCESs */
+extern EE_TYPEACCESSMASK const EE_as_resource_access_rules[] /*EE_MAX_RESOURCE*/;
+#endif /* !__OO_NO_RESOURCES__ */
+
+#if (!defined(__OO_NO_ALARMS__)) || defined(EE_AS_SCHEDULETABLES__)
+/** @var Contains access rules for COUNTERs */
+extern EE_TYPEACCESSMASK const EE_as_counter_access_rules[] /*EE_MAX_COUNTER*/;
+#endif /* !__OO_NO_ALARMS__ || !EE_AS_SCHEDULETABLES__ */
+
+#ifndef __OO_NO_ALARMS__
+/** @var Contains access rules for ALARMs */
+extern EE_TYPEACCESSMASK const EE_as_alarm_access_rules[] /*EE_MAX_ALARM*/;
+#endif /* !__OO_NO_ALARMS__ */
+
+#ifdef EE_AS_SCHEDULETABLES__
+/** @var Contains access rules for SCHEDULE TABLEs */
+extern EE_TYPEACCESSMASK const
+EE_as_scheduletable_access_rules[] /*EE_MAX_SCHEDULETABLE*/;
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#ifdef EE_AS_USER_SPINLOCKS__
+/** @var Contains access rules for SCHEDULE TABLEs */
+extern EE_TYPEACCESSMASK const
+EE_as_spinlock_access_rules[] /*EE_MAX_SPINLOCK_USER*/;
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+
+/* OSApplication Objects belog to active Macros */
+#define EE_OSAPP_TASK_ACCESS(TaskID) (EE_as_Application_RAM[\
+ EE_th_app[(TaskID + 1U)]].ApplState == APPLICATION_ACCESSIBLE)
+
+#define EE_OSAPP_ISR_ACCESS(ISRID) (EE_as_Application_RAM[\
+ EE_as_ISR_ROM[ISRID].ApplID].ApplState == APPLICATION_ACCESSIBLE)
+
+#define EE_OSAPP_COUNTER_ACCESS(CounterID) (EE_as_Application_RAM[\
+ EE_counter_ROM[CounterID].ApplID].ApplState == APPLICATION_ACCESSIBLE)
+
+#define EE_OSAPP_ALARM_ACCESS(AlarmID) (EE_as_Application_RAM[\
+ EE_alarm_ROM[AlarmID].ApplID].ApplState == APPLICATION_ACCESSIBLE)
+
+#define EE_OSAPP_SCHED_TABLE_ACCESS(SchedTableID) (EE_as_Application_RAM[\
+ EE_as_Schedule_Table_ROM[SchedTableID].ApplID].ApplState == \
+ APPLICATION_ACCESSIBLE)
+
+/* Access Macros */
+#define EE_TASK_ACCESS(TaskID, ApplID) (((EE_as_task_access_rules[TaskID] & \
+ EE_APP_TO_MASK(ApplID)) && EE_OSAPP_TASK_ACCESS(TaskID)))
+
+#define EE_ISR_ACCESS(ISRID, ApplID) (((EE_as_isr_access_rules[ISRID] & \
+ EE_APP_TO_MASK(ApplID)) && EE_OSAPP_ISR_ACCESS(ISRID)))
+
+#define EE_COUNTER_ACCESS(CounterID, ApplID) \
+ (((EE_as_counter_access_rules[CounterID] & EE_APP_TO_MASK(ApplID)) && \
+ EE_OSAPP_COUNTER_ACCESS(CounterID)))
+
+#define EE_ALARM_ACCESS(AlarmID, ApplID) (((EE_as_alarm_access_rules[\
+ AlarmID] & EE_APP_TO_MASK(ApplID)) && EE_OSAPP_ALARM_ACCESS(AlarmID)))
+
+#define EE_SCHED_TABLE_ACCESS(SchedTableID, ApplID) \
+ (((EE_as_scheduletable_access_rules[SchedTableID] & EE_APP_TO_MASK(ApplID)) \
+ && EE_OSAPP_SCHED_TABLE_ACCESS(SchedTableID)))
+
+#define EE_RESOURCE_ACCESS(ResourceID, ApplID) \
+ ((EE_as_resource_access_rules[ResourceID] & EE_APP_TO_MASK(ApplID)))
+
+#define EE_SPINLOCK_ACCESS(SpinlockID, ApplID) \
+ ((EE_as_spinlock_access_rules[SpinlockID] & EE_APP_TO_MASK(ApplID)))
+
+/* Error Macros */
+#define EE_TASK_ACCESS_ERR(TaskID, ApplID) (!EE_TASK_ACCESS(TaskID, ApplID))
+
+#define EE_ISR_ACCESS_ERR(ISRID, ApplID) (!EE_ISR_ACCESS(ISRID, ApplID))
+
+#define EE_COUNTER_ACCESS_ERR(CounterID, ApplID) (!EE_COUNTER_ACCESS(CounterID, \
+ ApplID))
+
+#define EE_ALARM_ACCESS_ERR(AlarmID, ApplID) (!EE_ALARM_ACCESS(AlarmID, \
+ ApplID))
+
+#define EE_SCHED_TABLE_ACCESS_ERR(SchedTableID, ApplID) \
+ (!EE_SCHED_TABLE_ACCESS(SchedTableID, ApplID))
+
+#define EE_RESOURCE_ACCESS_ERR(ResourceID, ApplID) \
+ (!EE_RESOURCE_ACCESS(ResourceID, ApplID))
+
+#define EE_SPINLOCK_ACCESS_ERR(SpinlockID, ApplID) \
+ (!EE_SPINLOCK_ACCESS(SpinlockID, ApplID))
+
+#endif /* EE_SERVICE_PROTECTION__ */
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#ifdef EE_AS_HAS_PROTECTIONHOOK__
+/*******************************************************************************
+ * ProtectionHook Internal Support
+ ******************************************************************************/
+#ifdef EE_AS_OSAPPLICATIONS__
+/**
+ * @brief This function wraps the call to the protection hook.
+ * Also, it does what is required to do according to what the ProtectionHook
+ * returns.
+ * @param error_app the OS-Application that caused the error
+ * @param error the error to send to the ProtectionHook function
+ */
+void EE_as_handle_protection_error(ApplicationType error_app,
+ StatusType error);
+#else /* EE_AS_OSAPPLICATIONS__ */
+/**
+ * @brief This function wraps the call to the protection hook.
+ * Also, it does what is required to do according to what the ProtectionHook
+ * returns.
+ * @param error the error to send to the ProtectionHook function
+ */
+void EE_as_handle_protection_error(StatusType error);
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#endif /* EE_AS_HAS_PROTECTIONHOOK__ */
+
+#ifdef __EE_MEMORY_PROTECTION__
+/*******************************************************************************
+ * Memory Protection Internal Support
+ ******************************************************************************/
+/** Syscall table */
+extern EE_FADDR const EE_syscall_table[] /*EE_SYSCALL_NR*/;
+
+/** @typedef for TRUSTED Function pointers */
+typedef StatusType (*EE_TRUSTEDFUNCTYPE)(TrustedFunctionIndexType,
+ TrustedFunctionParameterRefType);
+
+/* THIS HAL FUNCTIONS DECLARATION ARE PUT HERE BECAUSE SIGNATURE DEPENDS ON
+ * AS KERNEL TYPES */
+
+/**
+ * Return the access permission for the given memory area. Defined in the CPU
+ * layer. */
+AccessType EE_hal_get_app_mem_access(ApplicationType app,
+ MemoryStartAddressType beg,
+ MemorySizeType size);
+
+#if defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__
+EE_as_active_app_is_inside_trusted_function_call(void)
+{
+ return EE_as_Application_RAM[EE_as_active_app].
+ TrustedFunctionCallsCounter != 0U;
+}
+#else /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#define EE_as_active_app_is_inside_trusted_function_call() EE_FALSE
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#else /* __EE_MEMORY_PROTECTION__ */
+#define EE_as_active_app_is_inside_trusted_function_call() EE_FALSE
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+/*******************************************************************************
+ * Stack Monitoring Internal Support
+ ******************************************************************************/
+#ifdef EE_STACK_MONITORING__
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/* Functions used to check and handle Stack Overflow, with short cut to
+ * pass current application */
+void EE_as_check_and_handle_stack_overflow(ApplicationType appid,
+ EE_UREG stktop);
+#else /* EE_AS_OSAPPLICATIONS__ */
+/* Functions used to check and handle Stack Overflow. Have to be to be
+ * implemented in each porting that support stack monitoring */
+void EE_as_check_and_handle_stack_overflow(EE_UREG stktop);
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/* Used Internally in Kernel primitives */
+void EE_as_monitoring_the_stack(void);
+
+#else /* EE_STACK_MONITORING__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_check_and_handle_stack_overflow(ApplicationType appid,
+ EE_UREG stktop)
+{
+}
+#else /* EE_AS_OSAPPLICATIONS__ */
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_check_and_handle_stack_overflow(EE_UREG stktop)
+{
+}
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_as_monitoring_the_stack(void)
+{
+}
+#endif /* EE_STACK_MONITORING__ */
+
+/* Used to select witch system ERROR handling function call */
+#ifdef EE_AS_HAS_PROTECTIONHOOK__
+#ifdef EE_AS_OSAPPLICATIONS__
+#define EE_as_call_protection_error(app, error) \
+ EE_as_handle_protection_error(app, error)
+#else /* EE_AS_OSAPPLICATIONS__ */
+#define EE_as_call_protection_error(app, error) \
+ EE_as_handle_protection_error(error)
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#else /* EE_AS_HAS_PROTECTIONHOOK__ */
+#define EE_as_call_protection_error(app, error) \
+ EE_oo_ShutdownOS_internal(error)
+#endif /* EE_AS_HAS_PROTECTIONHOOK__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_INTERNAL__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_ioc.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_ioc.h
new file mode 100644
index 0000000..35cca69
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_ioc.h
@@ -0,0 +1,286 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_ioc.h
+ * @brief APIs declarations for Autosar IOC module
+ * @author Francesco Esposito
+ * @date 2012
+ */
+
+#ifndef INCLUDE_EE_IOC_AS_KERNEL__
+#define INCLUDE_EE_IOC_AS_KERNEL__
+
+#ifndef EE_AS_RPC__
+#error IOC internally depends on AS RPC mechanism!
+#endif /* EE_AS_RPC__ */
+
+#ifdef EE_AS_INCLUDE_AUTOSAR_HEADERS
+#include "rte.h" /* To include RTE macros (e.g.: RTE_E_OK */
+#else
+/* TODO: Dummy values introduced to prevent user to add his personal header RTE
+ * file */
+/* Since RTE does not (yet) exist, they are (temporary) defined as follow */
+#define RTE_E_OK 0U /* No error occurred */
+#define RTE_E_NOK 1U /* Error occurred */
+#define RTE_E_NO_DATA 131U /* No data available for reception */
+#define RTE_E_LIMIT 130U /* Buffer dimension */
+#define RTE_E_LOST_DATA 64U /* Buffer dimension */
+#endif
+
+#define IOC_PRIMITIVE_TYPE 0U /**< Denotes a primitive type
+ * (e.g. uint32) **/
+#define IOC_NON_PRIMITIVE_TYPE 1U /**< Denotes other type
+ * (e.g. *TASKParams3) **/
+
+#define IOC_UNQUEUED 0U /**< It denotes "unqueued" data
+ * (Last-Is-Best) **/
+#define IOC_QUEUED 1U /**< It denotes "queued" data
+ * (First-In-First-Out) **/
+
+#define IOC_CALLBACK_YES 0U /**< Callback configured **/
+#define IOC_CALLBACK_NOT 1U /**< Callback not configured **/
+
+/* Return values remapping (from RTE codes to IOC codes) */
+#define IOC_E_OK RTE_E_OK
+#define IOC_E_NOK RTE_E_NOK
+#define IOC_E_NO_DATA RTE_E_NO_DATA
+#define IOC_E_LIMIT RTE_E_LIMIT
+#define IOC_E_LOST_DATA RTE_E_LOST_DATA
+
+typedef void *EE_IOC_DATA_PTR;
+typedef const void *EE_IOC_DATA_PTR_CONST;
+
+/* Uncomment the following line to allow buffer overrun. But notice that
+ * it is not allowed for Autosar */
+/*#define BUFFER_OVERRUN_ALLOWED */
+
+/**
+ * @brief Cicular Buffers Type
+ *
+ * The implementation of the circular queue make use of the
+ * <it>fill counter</it> mechanism to solve the Full/Empty condition and
+ * particulary the case with one index and a fill counter
+ * (no additional variable required).
+ **/
+typedef struct EE_IOC_Buffer {
+ EE_UINT8 id; /**< message id **/
+ EE_UINT16 head; /**< head: points to first byte to be
+ * extracted **/
+ EE_UINT16 counter; /**< counter: number of byte filled in
+ * buffer **/
+ EE_UINT16 buffer_length; /* IOC uses OsIocBufferLength */
+ EE_UINT8 *memory; /**< memory: points to the buffer memory
+ * (supposed allocated byte dimension:
+ * buffer_length) **/
+ EE_INT8 data_rejected; /**< mark as buffer with "rejected data".
+ * Field used by IocReceive_XXX **/
+ EE_UINT8 lenght; /**< Single data length (in bytes) **/
+ EE_UINT8 callback; /**< Ioc receive callback **/
+} EE_IOC_Buffer;
+
+typedef EE_UINT8 EE_IOC_BufferError;
+
+/*=================================================
+ * Symbols and macros definition
+ * ==================================================*/
+/**
+ * @brief error codes
+ * @{
+ **/
+#define EE_CBUFF_OK (0x00)
+#define EE_CBUFF_ERR_NULL (-1)
+#define EE_CBUFF_ERR_TOO_MANY (-2)
+#define EE_CBUFF_ERR_TOO_FEW (-3)
+#define EE_CBUFF_ERR_OOB (-4) /** Out of Bounds **/
+
+#define EE_CBUFF_DATA_REJECTED (-5) /** to mark a buffer as buffer
+ * with rejected data **/
+#define EE_CBUFF_DATA_ACCEPTED (-6) /** to mark a buffer as working in
+ * normal condition **/
+/** @} **/
+
+/** @brief CBuffer NULL pointer **/
+#define EE_NULL_CBUFF ((EE_IOC_Buffer *)0)
+
+/**
+ * @brief Performs an "explicit" sender-receiver transmission of data
+ * elements with "event" semantic for a unidirectional 1:1 or N:1
+ * communication between OS-Applications located on the same or
+ * on different cores. IocSend API call is generated for "events"
+ * (queued First-In-First-Out, event semantics) semantics.
+ * Autosar reference: [OS718].
+ *
+ * @param id: is a unique identifier that references a unidirectional
+ * 1:1 or N:1 communication.
+ * @param data: Data value to be sent over a communication identified
+ *
+ * @return IOC_E_OK: The data has been passed successfully to the
+ * communication service;
+ * IOC_E_LIMIT: IOC internal communication buffer is full (Case:
+ * Receiver is slower than sender)
+ **/
+EE_INT8 IocSend(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data);
+
+/**
+ * @brief Performs an "explicit" sender-receiver transmission of data
+ * elements with "data" semantic for a unidirectional 1:1 or N:1
+ * communication between OS-Applications located on the same or
+ * on different cores. IocWrite API call is generated for "data"
+ * (unqueued (Last-is-Best, data semantics)) semantics.
+ * Autosar reference: [OS718].
+ *
+ * @param id: is a unique identifier that references a unidirectional
+ * 1:1 or N:1 communication.
+ * @param data: Data value to be sent over a communication identified
+ *
+ * @return IOC_E_OK: The data has been passed successfully to the
+ * communication service;
+ **/
+EE_INT8 IocWrite(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data);
+
+/**
+ * @brief Performs an "explicit" sender-receiver reception of data
+ * elements with "event" semantic for a unidirectional communication
+ * between OS-Applications located on the same or on different cores.
+ * Autosar reference: [OS718].
+ *
+ * @param id: is a unique identifier that references a unidirectional
+ * 1:1 or N:1 communication.
+ * @param data: Data reference to be filled with the received data element.
+ *
+ * @return IOC_E_OK: Data was received successfully
+ * IOC_E_NO_DATA: No data is available for reception
+ * IOC_E_LOST_DATA: This Overlayed Error indicates that the IOC
+ * communication service refused an IOCSend request from sender
+ * due to an internal buffer overflow. There is no error in the data
+ * returned in parameter.
+ **/
+EE_INT8 IocReceive(EE_UINT8 id,
+ EE_IOC_DATA_PTR data);
+
+/**
+ * @brief Performs an "explicit" sender-receiver reception of data
+ * elements with "data" semantic for a unidirectional communication
+ * between OS-Applications located on the same or on different cores.
+ * Autosar reference: [OS718].
+ *
+ * @param id: is a unique identifier that references a unidirectional
+ * 1:1 or N:1 communication.
+ * @param data: Data reference to be filled with the received data element.
+ *
+ * @return IOC_E_OK: Data was received successfully
+ **/
+EE_INT8 IocRead(EE_UINT8 id,
+ EE_IOC_DATA_PTR data);
+
+/**
+ * @brief In case of queued communication identified by the <IocId> in
+ * the function name, the content of the IOC internal communication
+ * queue shall be deleted.
+ * Autosar reference: [OS754].
+ *
+ * @param id: none
+ *
+ * @return IOC_E_OK: Data was received successfully
+ **/
+EE_INT8 IocEmptyQueue(EE_UINT8 id);
+
+/**
+ * @brief Performs an "explicit" sender-receiver transmission of data
+ * elements with "data" semantic for a unidirectional 1:1
+ * communication between OS-Applications located on the same
+ * or on different cores.
+ *
+ * @param id: List of parameters with data values to be sent over a
+ * communication identified by the <IocId>. The parameters will be
+ * passed by value for simple data elements and by reference for all
+ * other types.
+ *
+ * @return IOC_E_OK: The data has been passed successfully to the
+ * communication service.
+ **/
+void IocWriteSingleElement(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data,
+ EE_UINT8 size,
+ EE_UINT8 parameter_number);
+
+/**
+ * @brief Performs an "explicit" sender-receiver transmission of data
+ * elements with a "data" semantic for a unidirectional 1:1
+ * communication between OS-Applications located on the same or
+ * on different cores.
+ *
+ *
+ * @param id: List of data references to be filled with the received data
+ * elements. The specified order of the parameter shall match to
+ * the specified order in the corresponding send function.
+ *
+ *
+ * @return IOC_E_OK: Data was received successfully
+ **/
+void IocReadSingleElement(EE_UINT8 id,
+ EE_IOC_DATA_PTR data,
+ EE_UINT8 size,
+ EE_UINT8 parameter_number);
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief List that tie IOC buffer IDs to his receiving core. It SHALL be
+ * generated by RT-Druid IOC Generator. If Erika IOC implementation is used
+ * without a generator this structure MUST provided in a project
+ * module (e.g. ioc_common.c) */
+extern EE_TYPECOREID const EE_SHARED_CDATA EE_as_rpc_IOC_channels[];
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief Signal asynchronously the right core to start callback Sequence. */
+void EE_as_IOC_signal_callbacks(EE_UINT8 id);
+
+/** @brief Standard function that SHALL be generated by IOC generator that
+ * implement the IOC callbacks sequece for current core */
+void EE_as_IOC_callback_sequence(void);
+
+#endif /* INCLUDE_EE_IOC_AS_KERNEL__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_kernel.h
new file mode 100644
index 0000000..4e91ccf
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_kernel.h
@@ -0,0 +1,945 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_kernel.h
+ * @brief Types and macros for Autosar layer
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#ifndef PKG_KERNEL_AS_INC_EE_AS_KERNEL_H
+#define PKG_KERNEL_AS_INC_EE_AS_KERNEL_H
+
+#define OSId_AS_Sevices_Begin OSId_OO_Services_End
+
+#define OSServiceId_GetNumberOfActivatedCores OSId_AS_Sevices_Begin
+#define OSServiceId_GetCoreID (OSId_AS_Sevices_Begin + 1U)
+#define OSServiceId_StartCore (OSId_AS_Sevices_Begin + 2U)
+#define OSServiceId_StartNonAutosarCore (OSId_AS_Sevices_Begin + 3U)
+#define OSServiceId_GetSpinlock (OSId_AS_Sevices_Begin + 4U)
+#define OSServiceId_ReleaseSpinlock (OSId_AS_Sevices_Begin + 5U)
+#define OSServiceId_TryToGetSpinlock (OSId_AS_Sevices_Begin + 6U)
+#define OSServiceId_ShutdownAllCores (OSId_AS_Sevices_Begin + 7U)
+/* Inter OSApplication Communication (IOC) */
+#define OSServiceId_IOCService (OSId_AS_Sevices_Begin + 8U)
+/* OS-Applications Services */
+#define OSServiceId_GetApplicationState (OSId_AS_Sevices_Begin + 9U)
+#define OSServiceId_TerminateApplication (OSId_AS_Sevices_Begin + 10U)
+#define OSServiceId_AllowAccess (OSId_AS_Sevices_Begin + 11U)
+/* Trusted Function */
+#define OSServiceId_CallTrustedFunction (OSId_AS_Sevices_Begin + 12U)
+/* Schedule Table */
+#define OSServiceId_StartScheduleTableRel (OSId_AS_Sevices_Begin + 13U)
+#define OSServiceId_StartScheduleTableAbs (OSId_AS_Sevices_Begin + 14U)
+#define OSServiceId_StopScheduleTable (OSId_AS_Sevices_Begin + 15U)
+#define OSServiceId_NextScheduleTable (OSId_AS_Sevices_Begin + 16U)
+#define OSServiceId_GetScheduleTableStatus (OSId_AS_Sevices_Begin + 17U)
+#define OSServiceId_SyncScheduleTable (OSId_AS_Sevices_Begin + 18U)
+/* Service Protection Check API */
+#define OSServiceId_CheckObjectOwnership (OSId_AS_Sevices_Begin + 19U)
+#define OSServiceId_CheckObjectAccess (OSId_AS_Sevices_Begin + 20U)
+/* Memory Protection Check API */
+#define OSServiceId_CheckTaskMemoryAccess (OSId_AS_Sevices_Begin + 21U)
+#define OSServiceId_CheckISRMemoryAccess (OSId_AS_Sevices_Begin + 22U)
+/* GetApplicationID & GetISRID
+ * (put here because forgotten and RT-Druid support already ORTI) */
+#define OSServiceId_GetApplicationID (OSId_AS_Sevices_Begin + 22U)
+#define OSServiceId_GetISRID (OSId_AS_Sevices_Begin + 23U)
+
+/*******************************************************************************
+ * Standard Defines
+ ******************************************************************************/
+
+/* 8.1 Constants */
+/* Application Mode do not Care */
+#define DONOTCARE ((AppModeType) - 1)
+
+/*******************************************************************************
+ * ORTI support
+ ******************************************************************************/
+
+/* The last OO service called by the application. SERVICETRACE IDs
+ * are even numbers. The LSBit is used as a flag and it is set to 1
+ * when the servce is entered, to 0 at exit.
+ * (Needed here, not in intenal, for services inline implementation). */
+#define EE_SERVICETRACE_AS_BEGIN EE_SERVICETRACE_OO_LAST
+
+#define EE_SERVICETRACE_GETNUMBEROFACTIVATEDCORES EE_SERVICETRACE_AS_BEGIN
+#define EE_SERVICETRACE_GETCOREID (EE_SERVICETRACE_AS_BEGIN + 2U)
+#define EE_SERVICETRACE_STARTCORE (EE_SERVICETRACE_AS_BEGIN + 4U)
+#define EE_SERVICETRACE_STARTNONAUTOSARCORE (EE_SERVICETRACE_AS_BEGIN + 6U)
+#define EE_SERVICETRACE_GETSPINLOCK (EE_SERVICETRACE_AS_BEGIN + 8U)
+#define EE_SERVICETRACE_RELEASESPINLOCK (EE_SERVICETRACE_AS_BEGIN + 10U)
+#define EE_SERVICETRACE_TRYTOGETSPINLOCK (EE_SERVICETRACE_AS_BEGIN + 12U)
+#define EE_SERVICETRACE_SHUTDOWNALLCORES (EE_SERVICETRACE_AS_BEGIN + 14U)
+#define EE_SERVICETRACE_CHECKTASKMEMORYACCESS (EE_SERVICETRACE_AS_BEGIN + 16U)
+#define EE_SERVICETRACE_CHECKISRMEMORYACCESS (EE_SERVICETRACE_AS_BEGIN + 18U)
+#define EE_SERVICETRACE_GETAPPLICATIONID (EE_SERVICETRACE_AS_BEGIN + 20U)
+#define EE_SERVICETRACE_GETISRID (EE_SERVICETRACE_AS_BEGIN + 22U)
+#define EE_SERVICETRACE_GETAPPLICATIONSTATE (EE_SERVICETRACE_AS_BEGIN + 24U)
+#define EE_SERVICETRACE_TERMINATEAPPLICATION (EE_SERVICETRACE_AS_BEGIN + 26U)
+#define EE_SERVICETRACE_ALLOWACCESS (EE_SERVICETRACE_AS_BEGIN + 28U)
+#define EE_SERVICETRACE_CHECKOBJECTACCESS (EE_SERVICETRACE_AS_BEGIN + 30U)
+#define EE_SERVICETRACE_CHECKOBJECTOWNERSHIP (EE_SERVICETRACE_AS_BEGIN + 32U)
+#define EE_SERVICETRACE_CALLTRUSTEDFUNCTION (EE_SERVICETRACE_AS_BEGIN + 34U)
+#define EE_SERVICETRACE_STARTSCHEDULETABLEREL (EE_SERVICETRACE_AS_BEGIN + 36U)
+#define EE_SERVICETRACE_STARTSCHEDTABABS (EE_SERVICETRACE_AS_BEGIN + 38U)
+#define EE_SERVICETRACE_STOPSCHEDULETABLE (EE_SERVICETRACE_AS_BEGIN + 40U)
+#define EE_SERVICETRACE_NEXTSCHEDULETABLE (EE_SERVICETRACE_AS_BEGIN + 42U)
+#define EE_SERVICETRACE_GETSCHEDULETABLESTATUS \
+ (EE_SERVICETRACE_AS_BEGIN + 44U)
+#define EE_SERVICETRACE_SYNCSCHEDULETABLE (EE_SERVICETRACE_AS_BEGIN + 46U)
+
+/*******************************************************************************
+ * System services
+ ******************************************************************************/
+/* This inclusion is put here instead of inter layer because eecfg.c need to see
+ * declarations inside to configure the feature */
+#include "kernel/as/inc/ee_as_timing_prot.h"
+
+#ifdef __MSRP__
+/*******************************************************************************
+ * System Services Implemented Inline inclusion
+ ******************************************************************************/
+#include "kernel/as/inc/ee_as_inline.h"
+
+/* Following types and services declaration have reason only in multicore
+ * environment */
+#ifndef __PRIVATE_STARTOS__
+void EE_as_StartCore(CoreIdType CoreID,
+ StatusType *Status);
+void EE_as_StartNonAutosarCore(CoreIdType CoreID,
+ StatusType *Status);
+#endif /* !__PRIVATE_STARTOS__ */
+
+
+#if defined(EE_AS_USER_SPINLOCKS__) && (!defined(EE_PRIVATE_SPINLOCK__))
+StatusType EE_as_GetSpinlock(SpinlockIdType SpinlockId);
+StatusType EE_as_ReleaseSpinlock(SpinlockIdType SpinlockId);
+StatusType EE_as_TryToGetSpinlock(SpinlockIdType SpinlockId,
+ TryToGetSpinlockType *Success);
+
+#endif /* EE_AS_USER_SPINLOCKS__ && !EE_PRIVATE_SPINLOCK__ */
+
+#if (!defined(__PRIVATE_SHUTDOWNOS__)) && defined(EE_AS_RPC__)
+void EE_as_ShutdownAllCores(StatusType Error);
+#endif /* !__PRIVATE_SHUTDOWNOS__ && EE_AS_RPC__ */
+
+#endif /* __MSRP__ */
+
+/*******************************************************************************
+ * Errors Handling API
+ ******************************************************************************/
+
+/* [OS439]: The Operating System module shall provide the OSEK error macros
+ * (OSError...()) to all configured error hooks AND there shall be two
+ * (like in OIL) global configuration parameters to switch these macros on
+ * or off. */
+#if (defined(__OO_HAS_ERRORHOOK__)) && (!defined(__OO_ERRORHOOK_NOMACROS__))
+#ifdef EE_AS_USER_SPINLOCKS__
+__INLINE__ SpinlockIdType __ALWAYS_INLINE__
+OSError_GetSpinlock_SpinlockId(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ SpinlockIdType __ALWAYS_INLINE__
+OSError_ReleaseSpinlock_SpinlockId(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ SpinlockIdType __ALWAYS_INLINE__
+OSError_TryToGetSpinlock_SpinlockId(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TryToGetSpinlockType *__ALWAYS_INLINE__
+OSError_TryToGetSpinlock_Success(void)
+{
+ return EE_oo_get_errorhook_data()->param2.try_to_get_spinlock_ref;
+}
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_GetScheduleTableStatus_ScheduleTableID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ScheduleTableStatusRefType __ALWAYS_INLINE__
+OSError_GetScheduleTableStatus_ScheduleStatus(void)
+{
+ return EE_oo_get_errorhook_data()->param2.schedule_table_status_ref;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_StartScheduleTableRel_ScheduleTableID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TickType __ALWAYS_INLINE__
+OSError_StartScheduleTableRel_Offset(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_StartScheduleTableAbs_ScheduleTableID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TickType __ALWAYS_INLINE__
+OSError_StartScheduleTableAbs_Start(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_StopScheduleTable_ScheduleTableID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_NextScheduleTable_ScheduleTableID_From(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_NextScheduleTable_ScheduleTableID_To(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ ScheduleTableType __ALWAYS_INLINE__
+OSError_SyncScheduleTable_ScheduleTableID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TickType __ALWAYS_INLINE__
+OSError_SyncScheduleTable_Value(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+/* TODO: Add Macro to read error informations of last Scheduletable API */
+
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+
+__INLINE__ ApplicationType __ALWAYS_INLINE__
+OSError_TerminateApplication_Application(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ RestartType __ALWAYS_INLINE__
+OSError_TerminateApplication_RestartOption(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ ApplicationType __ALWAYS_INLINE__
+OSError_GetApplicationState_Application(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ApplicationStateRefType __ALWAYS_INLINE__
+OSError_GetApplicationState_Value(void)
+{
+ return EE_oo_get_errorhook_data()->param2.application_state_ref;
+}
+
+__INLINE__ ApplicationType __ALWAYS_INLINE__
+OSError_CheckObjectAccess_ApplID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ObjectTypeType __ALWAYS_INLINE__
+OSError_CheckObjectAccess_ObjectType(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ EE_os_param_id __ALWAYS_INLINE__
+OSError_CheckObjectAccess_ObjectID(void)
+{
+ return EE_oo_get_errorhook_data()->param3.value_param;
+}
+
+#ifdef EE_SERVICE_PROTECTION__
+
+__INLINE__ ObjectTypeType __ALWAYS_INLINE__
+OSError_CheckObjectOwnership_ObjectType(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ EE_os_param_id __ALWAYS_INLINE__
+OSError_CheckObjectOwnership_ObjectID(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef __EE_MEMORY_PROTECTION__
+__INLINE__ TaskType __ALWAYS_INLINE__
+OSError_CheckTaskMemoryAccess_TaskID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ MemoryStartAddressType __ALWAYS_INLINE__
+OSError_CheckTaskMemoryAccess_Address(void)
+{
+ return EE_oo_get_errorhook_data()->param2.memory_address;
+}
+
+__INLINE__ MemorySizeType __ALWAYS_INLINE__
+OSError_CheckTaskMemoryAccess_Size(void)
+{
+ return EE_oo_get_errorhook_data()->param3.value_param;
+}
+
+__INLINE__ ISRType __ALWAYS_INLINE__
+OSError_CheckISRMemoryAccess_ISRID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ MemoryStartAddressType __ALWAYS_INLINE__
+OSError_CheckISRMemoryAccess_Address(void)
+{
+ return EE_oo_get_errorhook_data()->param2.memory_address;
+}
+
+__INLINE__ MemorySizeType __ALWAYS_INLINE__
+OSError_CheckISRMemoryAccess_Size(void)
+{
+ return EE_oo_get_errorhook_data()->param3.value_param;
+}
+
+#if defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+
+__INLINE__ TrustedFunctionIndexType __ALWAYS_INLINE__
+OSError_CallTrustedFunction_FunctionIndex(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TrustedFunctionParameterRefType __ALWAYS_INLINE__
+OSError_CallTrustedFunction_FunctionParams(void)
+{
+ return EE_oo_get_errorhook_data()->param2.trusted_function_parameter_ref;
+}
+
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#endif /* __EE_MEMORY_PROTECTION__ */
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#endif /* __OO_HAS_ERRORHOOK__ && !__OO_ERRORHOOK_NOMACROS__ */
+
+#ifdef EE_AS_RPC__
+/*******************************************************************************
+ * Synchronous Remote Procedure Calls
+ ******************************************************************************/
+
+/** @brief type that hold params and return value for a RPC */
+typedef struct {
+ CoreIdType serving_core;
+ OSServiceIdType remote_procedure;
+ EE_os_param param1;
+ EE_os_param param2;
+ EE_os_param param3;
+ StatusType error;
+} EE_TYPEASRPC;
+
+typedef struct {
+ CoreIdType core_id;
+ EE_os_param_id param_id;
+#ifdef EE_SERVICE_PROTECTION__
+ EE_UREG core0_index;
+#endif /* EE_SERVICE_PROTECTION__ */
+} EE_TYPEASREMOTEID;
+
+typedef EE_TYPEASREMOTEID const *EE_TYPEASREMOTEIDCONSTREF;
+
+/* The following are moved in interface because used by inline generated code
+ * for IOC */
+
+/** @brief Map the core id with his corresponding spinlock */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief Map the core id with his corresponding spinlock */
+extern EE_TYPESPIN const EE_SHARED_CDATA EE_as_core_spinlocks[EE_MAX_CPU];
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief Flag that a core is serving a RPCs */
+extern EE_BIT volatile EE_SHARED_IDATA EE_as_rpc_serving[EE_MAX_CPU];
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __EE_MEMORY_PROTECTION__
+/** @typedef Autosar RPC with memory protection temporary return parameters */
+typedef union EE_as_rpc_outparam_type {
+ TaskStateType task_state;
+#ifndef __OO_NO_ALARMS__
+ AlarmBaseType alarm_base;
+ TickType tick;
+#endif /* !__OO_NO_ALARMS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ ScheduleTableStatusType schedule_table_status;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ ApplicationStateType application_state;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+} EE_as_rpc_outparam;
+
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+/** @brief The following implement a synchronous RPC kernel primitive. */
+/* This is put here because have to be seen in eecfg.c in case of
+ * __EE_MEMORY_PROTECTION__ */
+extern StatusType EE_as_rpc(OSServiceIdType ServiceId,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3);
+
+#endif /* EE_AS_RPC__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/*******************************************************************************
+ * OSApplication API
+ * (Types & Hooks are declared in ee_oo_common.h)
+ ******************************************************************************/
+
+/* Autosar Kernel Functions Declarations
+ * 8.4 Function definitions
+ */
+
+/** @brief This service determines the currently running OS-Application.
+ * (a unique identifier has to be allocated to each application).
+ */
+ApplicationType EE_as_GetApplicationID(void);
+
+/** @brief This service returns the identifier of the currently executing ISR.
+ */
+ISRType EE_as_GetISRID(void);
+
+/**
+ * @brief This service terminates the OS-Application to which the calling
+ * Task/Category 2 ISR/application specific error hook belongs.
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ * @param Application The identifier of the OS-Application to be terminated.
+ * If the caller belongs to <Application> the call results in a self
+ * termination.
+ * @param RestartOption Either RESTART for doing a restart of the
+ * OS-Application or NO_RESTART if OS-Application shall not be restarted.
+ * @return E_OK: No errors
+ * E_OS_ID: <Application> was not valid (only in EXTENDED status)
+ * E_OS_VALUE: <RestartOption> was neither RESTART nor NO_RESTART
+ * (only in EXTENDED status)
+ * E_OS_ACCESS: The caller does not have the right to terminate
+ * <Application> (only in EXTENDED status)
+ * E_OS_STATE: The state of <Application> does not allow
+ * terminating <Application>
+ */
+StatusType EE_as_TerminateApplication(ApplicationType Application,
+ RestartType RestartOption);
+
+/**
+ * @brief This service sets the own state of an OS-Application from
+ * APPLICATION_RESTARTING to APPLICATION_ACCESSIBLE. (Supposed to be called
+ * by OS-Application restarting TASK).
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ * @return E_OK: No errors
+ * E_OS_STATE: The OS-Application of the caller is in the wrong state
+ */
+StatusType EE_as_AllowAccess(void);
+
+/**
+ * @brief This service returns the current state of an OS-Application.
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ * @param Application: The OS-Application from which the state is requested.
+ * @param Value: The current state of the application.
+ * @return E_OK: No errors
+ * E_OS_ID: <Application> is not valid (only in EXTENDED status)
+ */
+StatusType EE_as_GetApplicationState(ApplicationType Application,
+ ApplicationStateRefType Value);
+
+/**
+ * @brief This service determines if the OS-Applications, given by ApplID, is
+ * allowed to use the IDs of a Task, ISR, Resource, Counter, Alarm or
+ * Schedule Table in API calls.
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ * @param ApplID: OS-Application identifier
+ * @param ObjectType: Type of the following parameter
+ * @param ObjectID: The object to be examined
+ * @return ObjectAccessType ACCESS if the ApplID has access to the object
+ * NO_ACCESS otherwise
+ */
+ObjectAccessType EE_as_CheckObjectAccess(ApplicationType ApplID,
+ ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID);
+
+#ifdef EE_SERVICE_PROTECTION__
+/**
+ * @brief This service determines to which OS-Application a given Task, ISR,
+ * Counter, Alarm or Schedule Table belongs.
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ * @param ObjectType: Type of the following parameter
+ * @param ObjectID: The object to be examined
+ * @return ApplicationType: <OS-Application> the OS-Application to which the
+ * object ObjectType belongs or INVALID_OSAPPLICATION if the object does not
+ * exists
+ */
+ApplicationType EE_as_CheckObjectOwnership(ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID);
+#endif /* EE_SERVICE_PROTECTION__ */
+
+/** @brief Called at the end of an ISR2 for termination */
+StatusType EE_as_TerminateISR2(void);
+
+/* The following functions are always called directly, never by syscall */
+#define GetApplicationID EE_as_GetApplicationID
+#define GetISRID EE_as_GetISRID
+#define GetApplicationState EE_as_GetApplicationState
+#define CheckObjectOwnership EE_as_CheckObjectOwnership
+#define CheckObjectAccess EE_as_CheckObjectAccess
+
+#ifdef __EE_MEMORY_PROTECTION__
+/*******************************************************************************
+ * Memory Protection Support
+ ******************************************************************************/
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* Autosar Kernel Functions Declarations
+ * 8.4 Function definitions
+ */
+
+/**
+ * @brief This service checks if a memory region is write/read/execute
+ * accessible for a TASK and also returns information if the memory
+ * region is part of the stack space.
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ *
+ * @param ISRID Index: ISR reference.
+ * @param Address: Start of memory area
+ * @param Size: Size of memory area
+ * @return AccessType: Value which contains the access rights to the memory
+ * area
+ */
+AccessType EE_as_CheckTaskMemoryAccess(TaskType TaskID,
+ MemoryStartAddressType Address,
+ MemorySizeType Size);
+
+/**
+ * @brief This service checks if a memory region is write/read/execute
+ * accessible for an ISR and also returns information if the memory
+ * region is part of the stack space.
+ * Sync/Async: Synchronous.
+ * Reentrancy: Reentrant.
+ *
+ * @param ISRID Index: ISR reference.
+ * @param Address: Start of memory area
+ * @param Size: Size of memory area
+ * @return AccessType: Value which contains the access rights to the memory
+ * area
+ */
+AccessType EE_as_CheckISRMemoryAccess(ISRType ISRID,
+ MemoryStartAddressType
+ Address,
+ MemorySizeType Size);
+
+/* The following functions are always called directly never by a syscall */
+#define CheckTaskMemoryAccess EE_as_CheckTaskMemoryAccess
+#define CheckISRMemoryAccess EE_as_CheckISRMemoryAccess
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+/**
+ * @brief A (trusted or non-trusted) OS-Application uses this service to call
+ * a trusted function
+ * Sync/Async: Depends on called function. If called function is synchronous
+ * then service is synchronous. May cause rescheduling.
+ * Reentrancy: Reentrant.
+ * @param FunctionIndex Index of the function to be called.
+ * @param FunctionParams Pointer to the parameters for the function - specified
+ * by the FunctionIndex - to be called. If no parameters are provided,
+ * a NULL pointer has to be passed.
+ * @return StatusType E_OK: No Error E_OS_SERVICEID: No function defined for
+ * this index
+ */
+StatusType EE_as_CallTrustedFunction(TrustedFunctionIndexType FunctionIndex,
+ TrustedFunctionParameterRefType FunctionParams);
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+
+/**
+ * The APIs below should modify the state of interrupts, but they cannot
+ * manipulate the state register directly when a syscall is used. So they take
+ * the value of the state register before the syscall and return the value to be
+ * set after the syscall. The syscall handler code takes care of updating the
+ * state register. */
+
+/* DisableAllInterrupts() body */
+EE_FREG EE_as_DisableAllInterrupts(EE_FREG prev);
+/* EnableAllInterrupts() body */
+EE_FREG EE_as_EnableAllInterrupts(EE_FREG prev);
+/* SuspendAllInterrupts() body */
+EE_FREG EE_as_SuspendAllInterrupts(EE_FREG prev);
+/* ResumeAllInterrupts() body */
+EE_FREG EE_as_ResumeAllInterrupts(EE_FREG prev);
+/* SuspendOSInterrupts() body */
+EE_FREG EE_as_SuspendOSInterrupts(EE_FREG prev);
+/* ResumeOSInterrupts() body */
+EE_FREG EE_as_ResumeOSInterrupts(EE_FREG prev);
+
+#else /* __EE_MEMORY_PROTECTION__ */
+/* TerminateApplication & AllowAccess services remapping on body functions
+ * (is an part API in the ERIKA's meaning of that) */
+#define TerminateApplication EE_as_TerminateApplication
+#define AllowAccess EE_as_AllowAccess
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#ifdef EE_AS_HAS_PROTECTIONHOOK__
+/*******************************************************************************
+ * Protection Hook Support
+ ******************************************************************************/
+/**
+ * @typedef ProtectionReturnType
+ *
+ * Defines what to do after returning from ProtectionHook.
+ *
+ * See paragraph 8.3.16 of AUTOSAR OS SWS 5.0.0
+ */
+typedef enum {
+ PRO_IGNORE, /**< do nothing */
+ PRO_TERMINATETASKISR, /**< terminate the faulty task or ISR2 */
+ PRO_TERMINATEAPPL, /**< terminate the faulty application */
+ PRO_TERMINATEAPPL_RESTART, /**< restart the faulty application */
+ PRO_SHUTDOWN /**< shutdown the OS */
+} ProtectionReturnType;
+
+/**
+ * User protection hook callback function.
+ *
+ * @param FatalError the kind of error
+ *
+ * @return what to do after this error
+ *
+ * see paragraph 8.7.1 of AUTOSAR OS SWS 5.0.0
+ */
+extern ProtectionReturnType ProtectionHook(StatusType FatalError);
+#endif /* EE_AS_HAS_PROTECTIONHOOK__ */
+
+/*******************************************************************************
+ * Multicore Startup synchronization data structures
+ ******************************************************************************/
+#ifdef __MSRP__
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/* The following contains cores application modes */
+extern AppModeType volatile EE_SHARED_UDATA
+ EE_as_os_application_mode[EE_MAX_CPU];
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/* Mask for Autosar cores started */
+extern EE_UREG EE_SHARED_IDATA volatile EE_as_core_mask;
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __MSRP__ */
+
+#ifdef EE_AS_USER_SPINLOCKS__
+/*******************************************************************************
+ * Spinlocks data Structures
+ ******************************************************************************/
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if (defined(EE_MAX_SPINLOCK_USER)) && (EE_MAX_SPINLOCK_USER > 0)
+/** @brief Hold which core is locking the spinlock */
+extern CoreIdType volatile EE_SHARED_IDATA EE_as_spinlocks_locker_core[EE_MAX_SPINLOCK_USER];
+
+/** @brief Spinlock Stack */
+extern SpinlockIdType volatile EE_SHARED_IDATA EE_as_spinlocks_stack[EE_MAX_SPINLOCK_USER];
+
+/** @brief Hold which task is locking the spinlock */
+extern TaskType volatile EE_SHARED_IDATA EE_as_spinlocks_locker_task_or_isr2[EE_MAX_SPINLOCK_USER];
+#endif /* EE_MAX_SPINLOCK_USER && EE_MAX_SPINLOCK_USER */
+
+#if (defined(EE_MAX_CPU)) && (EE_MAX_CPU > 0)
+/** @brief Spinlock Stack head */
+extern SpinlockIdType volatile EE_SHARED_IDATA EE_as_spinlocks_last[EE_MAX_CPU];
+#endif /* EE_MAX_CPU && EE_MAX_CPU */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+#ifdef EE_AS_RPC__
+/*******************************************************************************
+ * Synchronous Remote Procedure Calls Data Structures
+ ******************************************************************************/
+
+#if defined(EE_AS_RPC_SERVICES_TABLE_SIZE) && \
+ (EE_AS_RPC_SERVICES_TABLE_SIZE > 0)
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief used to map global ids on local ids */
+extern EE_TYPEASREMOTEIDCONSTREF const EE_SHARED_CDATA
+ EE_as_rpc_services_table[EE_AS_RPC_SERVICES_TABLE_SIZE];
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* EE_AS_RPC_SERVICES_TABLE_SIZE > 0 */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief Mask used in shutdown all cores procedure for synchronization */
+extern EE_UREG volatile EE_SHARED_IDATA EE_as_shutdown_mask;
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if defined(EE_AS_RPC_TASKS_SIZE) && (EE_AS_RPC_TASKS_SIZE > 0)
+extern EE_TYPEASREMOTEID const EE_SHARED_CDATA
+ EE_as_rpc_tasks[EE_AS_RPC_TASKS_SIZE];
+#endif /* EE_AS_RPC_TASKS_SIZE > 0 */
+
+#if defined(EE_AS_RPC_ALARMS_SIZE) && (EE_AS_RPC_ALARMS_SIZE > 0)
+extern EE_TYPEASREMOTEID const EE_SHARED_CDATA
+ EE_as_rpc_alarms[EE_AS_RPC_ALARMS_SIZE];
+#endif /* EE_AS_RPC_ALARMS_SIZE > 0 */
+
+#if defined(EE_AS_RPC_COUNTERS_SIZE) && (EE_AS_RPC_COUNTERS_SIZE > 0)
+extern EE_TYPEASREMOTEID const EE_SHARED_CDATA
+ EE_as_rpc_counters[EE_AS_RPC_COUNTERS_SIZE];
+#endif /* EE_AS_RPC_COUNTERS_SIZE > 0 */
+
+#if defined(EE_AS_RPC_SCHEDTABS_SIZE) && (EE_AS_RPC_SCHEDTABS_SIZE > 0)
+extern EE_TYPEASREMOTEID const EE_SHARED_CDATA
+ EE_as_rpc_schedTabs[EE_AS_RPC_SCHEDTABS_SIZE];
+#endif /* EE_AS_RPC_SCHEDTABS_SIZE > 0 */
+
+#if defined(EE_AS_RPC_OSAPPLS_SIZE) && (EE_AS_RPC_OSAPPLS_SIZE > 0)
+extern EE_TYPEASREMOTEID const EE_SHARED_CDATA
+ EE_as_rpc_osAppls[EE_AS_RPC_OSAPPLS_SIZE];
+#endif /* EE_AS_RPC_OSAPPLS_SIZE > 0 */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __EE_MEMORY_PROTECTION__
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief array used to crossing memory protection between cores when call a
+ * service with param2 as some kind of reference */
+extern EE_as_rpc_outparam EE_SHARED_UDATA EE_as_rpc_out_param2[EE_MAX_CPU];
+/** @brief array used to crossing memory protection between cores when call a
+ * service with param3 as some kind of reference */
+extern EE_as_rpc_outparam EE_SHARED_UDATA EE_as_rpc_out_param3[EE_MAX_CPU];
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#if defined(EE_MAX_CPU) && (EE_MAX_CPU > 0)
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+/** @brief Data structures to pass RPC parameters */
+extern EE_TYPEASRPC volatile EE_SHARED_IDATA EE_as_rpc_RAM[EE_MAX_CPU];
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+#endif /* EE_MAX_CPU > 0 */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief Flag used to signal that ShutdownAllCores have been called */
+extern EE_BIT volatile EE_SHARED_UDATA EE_as_shutdown_all_cores_flag;
+
+/** @brief Used to pass ShutdownAllCores error parameter to other cores */
+extern StatusType volatile EE_SHARED_UDATA EE_as_shutdown_all_cores_error;
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* EE_AS_RPC__ */
+
+#ifdef EE_AS_IOC__
+/*******************************************************************************
+ * Inter OSApplication Communication (IOC) Data Structures
+ ******************************************************************************/
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @brief Flag used to signal a IOC request */
+extern EE_BIT EE_SHARED_UDATA EE_as_rpc_IOC[EE_MAX_CPU];
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* EE_AS_IOC__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(EE_AS_RPC__))
+/*******************************************************************************
+ * OSApplication Service Protection Access Shared Data Structures
+ ******************************************************************************/
+/* Extra info used to implement service protection in Multi-core environment */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+extern EE_TYPEACCESSMASK const EE_SHARED_CDATA EE_as_rpc_remote_access_rules[
+ EE_AS_RPC_REMOTE_ACCESS_RULES_SIZE];
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_CONST_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+#endif /* EE_AS_OSAPPLICATIONS__ && EE_SERVICE_PROTECTION__ && EE_AS_RPC__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_KERNEL__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_multicore_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_multicore_api.h
new file mode 100644
index 0000000..42aa62f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_multicore_api.h
@@ -0,0 +1,92 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_multicore_api.h
+ * @brief Kernel API For Autosar Multicore Support
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+
+#ifndef INCLUDE_EE_KERNEL_AS_API__
+#define INCLUDE_EE_KERNEL_AS_API__
+
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || \
+ defined(__OO_ECC2__)
+/* These API are always called directly, never by a syscall */
+#ifndef GetNumberOfActivatedCores
+#define GetNumberOfActivatedCores EE_as_GetNumberOfActivatedCores
+#endif /* GetNumberOfActivatedCores */
+
+#ifndef GetCoreID
+#define GetCoreID EE_as_GetCoreID
+#endif /* GetCoreID */
+
+#ifndef StartCore
+#define StartCore EE_as_StartCore
+#endif /* StartCore */
+
+#ifndef StartNonAutosarCore
+#define StartNonAutosarCore EE_as_StartNonAutosarCore
+#endif /* StartNonAutosarCore */
+
+/* API Called by syscall when memory protection is enabled */
+#ifndef __EE_MEMORY_PROTECTION__
+#ifndef GetSpinlock
+#define GetSpinlock EE_as_GetSpinlock
+#endif /* GetSpinlock */
+
+#ifndef ReleaseSpinlock
+#define ReleaseSpinlock EE_as_ReleaseSpinlock
+#endif /* ReleaseSpinlock */
+
+#ifndef TryToGetSpinlock
+#define TryToGetSpinlock EE_as_TryToGetSpinlock
+#endif /* TryToGetSpinlock */
+
+#ifndef ShutdownAllCores
+#define ShutdownAllCores EE_as_ShutdownAllCores
+#endif /* ShutdownAllCores */
+
+#endif /* !__EE_MEMORY_PROTECTION__ */
+
+#endif /* __OO_BCC1__ || __OO_BCC2__ || __OO_ECC1__ || __OO_ECC2__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_API__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_schedule_tables.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_schedule_tables.h
new file mode 100644
index 0000000..2245675
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_schedule_tables.h
@@ -0,0 +1,222 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_schedule_tables.h
+ * @brief AUTOSAR Schedule Table Types and Functions declaration
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#ifndef INCLUDE_EE_KERNEL_AS_SCHEDULE_TABLES__
+#define INCLUDE_EE_KERNEL_AS_SCHEDULE_TABLES__
+
+/** 8.4.8 StartScheduleTableRel [OS347]
+ *
+ * @brief This service starts the processing of a schedule table at "Offset"
+ * relative to the "Now" value on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID Schedule table to be started.
+ *
+ * @param Offset Number of ticks on the counter before the the schedule table
+ * processing is started
+ *
+ * @return StatusType -
+ * E_OK: No Error
+ * E_OS_ID: (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE: (only in EXTENDED status): Offset is greater than
+ * (OsCounterMaxAllowedValue - InitialOffset) or is equal to 0.
+ * E_OS_STATE: Schedule table was already started.
+ */
+StatusType EE_as_StartScheduleTableRel(ScheduleTableType ScheduleTableID,
+ TickType Offset);
+
+/** 8.4.9 StartScheduleTableAbs [SWS_Os_00358]
+ *
+ * @brief This service starts the processing of a schedule table at an absolute
+ * value "Start" on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID: Schedule table to be started
+ * @param Start: Absolute counter tick value at which the schedule table is
+ * started
+ *
+ * @return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE (only in EXTENDED status): "Start" is greater than
+ * OsCounterMaxAllowedValue
+ * E_OS_STATE: Schedule table was already started Description:
+ */
+
+StatusType EE_as_StartScheduleTableAbs(ScheduleTableType ScheduleTableID,
+ TickType Start);
+
+/** 8.4.10 StopScheduleTable [SWS_Os_00006]
+ *
+ * @brief This service cancels the processing of a schedule table immediately
+ * at any point while the schedule table is running.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID: Schedule table to be stopped
+ *
+ * @return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_NOFUNC: Schedule table was already stopped.
+ */
+StatusType EE_as_StopScheduleTable(ScheduleTableType ScheduleTableID);
+
+/** 8.4.15 GetScheduleTableStatus [SWS_Os_00227]
+ *
+ * @brief This service queries the state of a schedule table (also with respect
+ * to synchronization).
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID (in): Schedule table for which status is requested.
+ * @param ScheduleStatus (out): Reference to ScheduleTableStatusType.
+ *
+ * @return StatusType:
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): Invalid ScheduleTableID
+ *
+ * (SRS_Os_11002)
+ */
+StatusType EE_as_GetScheduleTableStatus(ScheduleTableType ScheduleTableID,
+ ScheduleTableStatusRefType ScheduleStatus);
+
+/* The following primitives are available only on local objects */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+/** 8.4.11 NextScheduleTable [SWS_Os_00191]
+ *
+ * @brief This service switches the processing from one schedule table to
+ * another schedule table.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID_From: Currently processed schedule table
+ * @param ScheduleTableID_To: Schedule table that provides its series of
+ * expiry points
+ *
+ * @return StatusType
+ * E_OK: No error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID_From or
+ * ScheduleTableID_To not valid.
+ * E_OS_NOFUNC: ScheduleTableID_From not started
+ * E_OS_STATE: ScheduleTableID_To is started or next
+ *
+ * (SRS_Os_00099)
+ */
+
+StatusType EE_as_NextScheduleTable(ScheduleTableType ScheduleTableID_From,
+ ScheduleTableType ScheduleTableID_To);
+
+/** 8.4.13 SyncScheduleTable [SWS_Os_00199]
+ *
+ * @brief This service provides the schedule table with a synchronization
+ * count and start synchronization.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID (in): Schedule table to be synchronized
+ * @param Value (in): The current value of the synchronization counter
+ *
+ * @return StatusType:
+ * E_OK: No errors
+ * E_OS_ID (only in EXTENDED status): The ScheduleTableID was not valid or
+ * schedule table can not be synchronized (OsScheduleTblSyncStrategy not
+ * set or OsScheduleTblSyncStrategy = IMPLICIT)
+ * E_OS_VALUE (only in EXETENDED status): The <Value> is out of range.
+ * E_OS_STATE: The state of schedule table <ScheduleTableID> is equal to
+ * SCHEDULETABLE_STOPPED
+ * (SRS_Os_11002)
+ */
+
+StatusType EE_as_SyncScheduleTable(ScheduleTableType ScheduleTableID,
+ TickType Value);
+
+/* The following primitives are available only on local objects */
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+
+/*******************************************************************************
+* Schedule Table Kernel API names remapping
+*******************************************************************************/
+
+#ifndef GetScheduleTableStatus
+#define GetScheduleTableStatus EE_as_GetScheduleTableStatus
+#endif /* !GetScheduleTableStatus */
+
+/* Direct mapping only without memory proetction */
+#ifndef __EE_MEMORY_PROTECTION__
+
+#ifndef StartScheduleTableRel
+#define StartScheduleTableRel EE_as_StartScheduleTableRel
+#endif /* !StartScheduleTableRel */
+
+#ifndef StartScheduleTableAbs
+#define StartScheduleTableAbs EE_as_StartScheduleTableAbs
+#endif /* !StartScheduleTableAbs */
+
+#ifndef StopScheduleTable
+#define StopScheduleTable EE_as_StopScheduleTable
+#endif /* !StopScheduleTable */
+
+#ifndef NextScheduleTable
+#define NextScheduleTable EE_as_NextScheduleTable
+#endif /* !NextScheduleTable */
+
+#ifndef SyncScheduleTable
+#define SyncScheduleTable EE_as_SyncScheduleTable
+#endif /* !SyncScheduleTable */
+
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_SCHEDULE_TABLES__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_timing_prot.h b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_timing_prot.h
new file mode 100644
index 0000000..299e1f0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/inc/ee_as_timing_prot.h
@@ -0,0 +1,483 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_timing_prot.h
+ * @brief Types, macros and function declaration for AUTOSAR
+ * timing protection
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#ifndef PKG_KERNEL_AS_INC_EE_AS_TIMING_PROT_H
+#define PKG_KERNEL_AS_INC_EE_AS_TIMING_PROT_H
+
+/* Declare something only if the timing protection feature is enabled */
+#ifdef EE_TIMING_PROTECTION__
+
+#ifndef EE_CPU_CLOCK
+#error To handle Timing Protection is CPU clock frequency have to be configured!
+#endif /* !EE_CPU_CLOCK */
+
+/** @brief Macro that represent the MAX time allowed for TP */
+#define EE_AS_TP_MAX_TIME EE_HAL_SWFRT_TIMER_DURATION
+
+/** @brief Macro that represent no time (time equal to zero */
+#define EE_OS_NO_TIME ((TickType)0U)
+
+/** @brief Macro used to convert microseconds to SWFRT ticks */
+#define EE_MICRO_TO_SWFRT_TICKS(X_US) EE_MICRO_TO_TICKS(X_US, EE_SWFRT_CLOCK)
+
+/** @brief Macro used to populate TP data structures, with saturation
+ * handling. */
+#define EE_AS_TP_MICRO_TO_TICKS_SATURATED(X_US, SAT) \
+ ((EE_MICRO_TO_SWFRT_TICKS(X_US) > (SAT)) ? (SAT) : \
+ EE_MICRO_TO_SWFRT_TICKS(X_US))
+
+/** @typedef Used as index to access timing protection informations */
+typedef EE_UTID TimingProtectionType;
+#define INVALID_TIMING_PROTECTION ((TimingProtectionType) - 1)
+#define EE_MAX_TP ((EE_UTID)(EE_MAX_TASK + EE_MAX_ISR_ID))
+
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+/** Macro that represent the Time Frames Reclamation Budget */
+#define EE_RECLAMATION_TIME_FRAMES_BUDGET_ID (EE_MAX_TIMING_BUDGET - 1U)
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+
+/** @typedef Used as index to access time budget information */
+typedef EE_UTID BudgetType;
+#define INVALID_BUDGET ((BudgetType) - 1)
+
+/** @typedef This ENUM hold timing budget identifiers used to access data
+ * structures */
+typedef enum {
+ EE_EXECUTION_BUDGET,
+ EE_RESOURCE_LOCK_BUDGET,
+ EE_OS_INTERRUPT_LOCK_BUDGET,
+ EE_ALL_INTERRUPT_LOCK_BUDGET,
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ /** Special Budget to reclaim expired time frames */
+ EE_RECLAMATION_TIME_FRAMES_BUDGET
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+} EE_as_tp_budget_type;
+
+/** @typedef This struct hold a time budget dynamic data */
+typedef struct EE_as_tp_budget_data_type_ {
+ TickType remaining_budget;
+ EE_TYPEBOOL active;
+} EE_as_tp_budget_data_type;
+
+/** @typedef This struct hold a time budget configuration data */
+typedef struct EE_as_tp_budget_conf_type_ {
+ EE_as_tp_budget_type budget_type;
+ TickType budget_value;
+} EE_as_tp_budget_conf_type;
+
+/** @typedef This struct hold time frame data */
+typedef struct EE_as_tp_time_frame_type {
+ TickType frame_start;
+ EE_TYPEBOOL active;
+} EE_as_tp_time_frame;
+
+/** @typedef Pointer to an array that hold resource lock budgets.
+ * If configured for a TP is accessed with the ResourceID */
+#ifndef __OO_NO_RESOURCES__
+typedef BudgetType const (*ResourceLockBudgetsTypeRef)[EE_MAX_RESOURCE];
+#endif /* !__OO_NO_RESOURCES__ */
+
+/** @typedef This struct hold static timing protection configuration for a TASK
+ * or an ISR2 */
+typedef struct EE_as_tp_ROM_type_ {
+ /** Index of the first budget tied to this TP */
+ BudgetType budgets_begin_index;
+ /** Index of the end budget tied to this TP */
+ BudgetType budgets_end_index;
+ /** Index of the execution budget if configured */
+ BudgetType execution_budget_index;
+ /** Index of the OS ISR lock budget if configured */
+ BudgetType os_isr_lock_budget_index;
+ /** Index of the ALL ISR lock budget if configured */
+ BudgetType all_isr_lock_budget_index;
+#ifndef __OO_NO_RESOURCES__
+ /** Reference to the array that hold the resource lock budgets */
+ ResourceLockBudgetsTypeRef resources_lock_budgets_ref;
+#endif /* !__OO_NO_RESOURCES__ */
+ /** Inter-arrival frame duration, a value of EE_OS_NO_TIME means
+ * no protection */
+ TickType frame_duration;
+} EE_as_tp_ROM_type;
+
+/** @typedef This struct hold timing protection actual data for a TASK or an
+ * ISR2 */
+typedef struct EE_as_tp_RAM_type_ {
+ /** Inter-arrival frame protection data */
+ EE_as_tp_time_frame interarrival_frame;
+ /** Time of the last budgets update */
+ TickType last_update;
+ /** Index of the first expiring budget */
+ BudgetType first_expiring;
+} EE_as_tp_RAM_type;
+
+/** @typedef TP ROM reference types */
+typedef EE_as_tp_ROM_type const *EE_as_tp_ROM_const_ref;
+/** @typedef TP RAM reference types */
+typedef EE_as_tp_RAM_type *EE_as_tp_RAM_ref;
+
+/** @typedef This struct hold the information related to the first expiring
+ * budget active. Active TP have to be initialized to
+ * INVALID_TIMING_PROTECTION, the other fields could be left
+ * uninitialized. */
+typedef struct EE_as_tp_active_type_ {
+ /** Index of the active timing protection. Used as shortcut index.
+ * Otherwise I should always discriminate between current TASK or ISR2 */
+ TimingProtectionType active_tp;
+ /** Active timing protection RAM reference */
+ EE_as_tp_RAM_ref active_tp_RAM_ref;
+ /** Active timing protection ROM reference */
+ EE_as_tp_ROM_const_ref active_tp_ROM_ref;
+} EE_as_tp_active_type;
+
+/** @var Array of timing protection configuration structures indexed with
+ * TASK_IDs and EE_MAX_TASK + EE_ISR2_IDs */
+extern const EE_as_tp_ROM_const_ref
+ EE_as_tp_ROM_refs[] /*EE_MAX_TASK + EE_MAX_ISR2*/;
+
+/** @var Array of timing protection data structures indexed with TASK_IDs and
+ * EE_MAX_TASK + EE_ISR2_IDs */
+extern const EE_as_tp_RAM_ref EE_as_tp_RAM_refs[] /*EE_MAX_TASK + EE_MAX_ISR2*/;
+
+/** @var Array with all the expiring budgets protection data */
+extern const EE_as_tp_budget_conf_type
+ EE_as_tp_budget_confs[] /*EE_MAX_TIMING_BUDGET*/;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @var Active Timing Protection Information set */
+extern EE_as_tp_active_type EE_as_tp_active;
+/** @var Array with all the expiring budgets protection data */
+extern EE_as_tp_budget_data_type EE_as_tp_budget_data[] /*EE_MAX_TIMING_BUDGET*/;
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** Utilities Macros to convert TASK/ISR2 ID's in TP ID's */
+#define EE_AS_TP_ID_FROM_TASK(task_id) ((TimingProtectionType)task_id)
+#define EE_AS_TP_ID_FROM_ISR2(isr2_id) (EE_AS_TP_ID_FROM_TASK(EE_MAX_TASK) + \
+ isr2_id)
+
+/** Set active timing protection data structures informations */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_active_set(TimingProtectionType
+ tp_id)
+{
+ /* If EE_as_tp_RAM_refs[tp_id] is NULL it MUST be NULL
+ * EE_as_tp_ROM_refs[tp_id] too!!! */
+ if ((tp_id != INVALID_TIMING_PROTECTION) &&
+ (EE_as_tp_RAM_refs[tp_id] != NULL)) {
+ EE_as_tp_active.active_tp = tp_id;
+ EE_as_tp_active.active_tp_RAM_ref = EE_as_tp_RAM_refs[tp_id];
+ EE_as_tp_active.active_tp_ROM_ref = EE_as_tp_ROM_refs[tp_id];
+ } else {
+ EE_as_tp_active.active_tp = INVALID_TIMING_PROTECTION;
+ }
+}
+
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_tp_active_minimum_against_reclamation(BudgetType minimum_budget_index,
+ TickType actual_min)
+{
+ if (actual_min <=
+ EE_as_tp_budget_data[EE_RECLAMATION_TIME_FRAMES_BUDGET_ID].
+ remaining_budget) {
+ EE_as_tp_active.active_tp_RAM_ref->first_expiring = minimum_budget_index;
+ } else {
+ EE_as_tp_active.active_tp_RAM_ref->first_expiring =
+ EE_RECLAMATION_TIME_FRAMES_BUDGET_ID;
+ }
+}
+#else /* !EE_NO_RECLAMATION_TIME_FRAMES */
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_tp_active_minimum_against_reclamation(BudgetType minimum_budget_index,
+ TickType actual_min)
+{
+ EE_as_tp_active.active_tp_RAM_ref->first_expiring = minimum_budget_index;
+}
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+
+/* Search and set as first expiring, the minimum between active budgets of the
+ * active TP */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_active_eval_first_expiring(void)
+{
+ BudgetType b_index;
+ BudgetType minimum_budget_index = INVALID_BUDGET;
+ TickType actual_min = ((TickType)-1);
+
+ for (b_index = EE_as_tp_active.active_tp_ROM_ref->budgets_begin_index;
+ b_index <= EE_as_tp_active.active_tp_ROM_ref->budgets_end_index;
+ ++b_index) {
+ /* Get the budget data reference indexed */
+ EE_as_tp_budget_data_type *b_data_ref = &EE_as_tp_budget_data[b_index];
+ /* If the indexed budget is active... */
+ if (b_data_ref->active != EE_FALSE) {
+ /* Check if it is NOT the first budget that we found active... */
+ if (minimum_budget_index != INVALID_BUDGET) {
+ /* Check if it is smaller than the actual minimum */
+ if (actual_min > b_data_ref->remaining_budget) {
+ minimum_budget_index = b_index;
+ actual_min = b_data_ref->remaining_budget;
+ }
+ } else {
+ /* If this is the first budget found active it is the actual
+ * minimum too. */
+ minimum_budget_index = b_index;
+ actual_min = b_data_ref->remaining_budget;
+ }
+ }
+ }
+
+ if (minimum_budget_index != INVALID_BUDGET) {
+ EE_as_tp_active_minimum_against_reclamation(minimum_budget_index,
+ actual_min);
+ }
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ else {
+ EE_as_tp_active.active_tp_RAM_ref->first_expiring =
+ EE_RECLAMATION_TIME_FRAMES_BUDGET_ID;
+ }
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+}
+
+/** This function deactivate an active budget and reset it */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_stop_budget(
+ EE_as_tp_RAM_ref const tp_ram_ref,
+ BudgetType budget_id)
+{
+ EE_as_tp_budget_data_type *const time_budget_ref =
+ &EE_as_tp_budget_data[budget_id];
+
+ time_budget_ref->remaining_budget = EE_as_tp_budget_confs[budget_id].
+ budget_value;
+
+ time_budget_ref->active = EE_FALSE;
+}
+
+/** Reset timing protection budgets */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_reset_budgets(TimingProtectionType
+ tp_id)
+{
+ BudgetType b_index;
+
+ for (b_index = EE_as_tp_ROM_refs[tp_id]->budgets_begin_index;
+ b_index <= EE_as_tp_ROM_refs[tp_id]->budgets_end_index;
+ ++b_index) {
+ EE_as_tp_stop_budget(EE_as_tp_RAM_refs[tp_id], b_index);
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_stop_interarrival_frame(
+ TimingProtectionType tp_id)
+{
+ const EE_as_tp_RAM_ref tp_ram_ref = EE_as_tp_RAM_refs[tp_id];
+
+ /* If the TASK/ISR2 has TP... */
+ if (tp_ram_ref != NULL) {
+ /*... Stop inter-arrival frame for it. */
+ tp_ram_ref->interarrival_frame.active = EE_FALSE;
+ }
+}
+
+/** Check inter-arrival error in case of Activation/Release from Wait Event.
+ * If not error happens restart the frame. return EE_TRUE if the
+ * Activation/Release have to be performed */
+EE_TYPEBOOL EE_as_tp_handle_interarrival(TimingProtectionType tp_id);
+
+/** Reset active timing protection budgets. (If a TP is really active) */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_active_reset_budgets(void)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ BudgetType b_index;
+ for (b_index = EE_as_tp_active.active_tp_ROM_ref->budgets_begin_index;
+ b_index <= EE_as_tp_active.active_tp_ROM_ref->budgets_end_index;
+ ++b_index) {
+ EE_as_tp_stop_budget(EE_as_tp_active.active_tp_RAM_ref, b_index);
+ }
+ }
+}
+
+/** Set active timing protection from TASK Id, saving "now" in "last update".
+ * Used when the TASK is restored from a preemption */
+void EE_as_tp_active_set_from_TASK(TaskType task_id);
+
+/** Set active timing protection and restart it, saving "now" in
+ * "last update". Used when the ISR2 is restored from a preemption */
+void EE_as_tp_active_set_from_id_with_restart(TimingProtectionType tp_id);
+
+/** Start timing protection for the TASK that is going to be started or
+ * released from a wait */
+void EE_as_tp_active_start_on_TASK_stacking(TaskType task_id);
+
+/** Start timing protection for a new ISR2 */
+void EE_as_tp_active_start_for_ISR2(ISRType isr2_id);
+
+/** Stop the active timing protection without updates. Used where we are
+ * sure that current TP won't be restarted. Instead the Time Frame Reclamation
+ * Budget is enabled if needed */
+void EE_as_tp_active_stop(void);
+
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+/** Active the Time Frames Reclamation Budget when the application goes in
+ * IDLE */
+void EE_as_tp_active_start_idle(void);
+#else /* !EE_NO_RECLAMATION_TIME_FRAMES */
+#define EE_as_tp_active_start_idle() ((void)0)
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+
+/* Implementation functions. Those TP functions are broken in two part to safe
+ * a function call, that can be not cheap in some architectures, if it's not
+ * really needed */
+void EE_as_tp_active_pause_and_update_budgets_impl(void);
+
+void EE_as_tp_active_update_budgets_and_restart_impl(void);
+
+void EE_as_tp_active_activate_budget_impl(EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL start_first);
+
+void EE_as_tp_active_stop_budget_impl(EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL start_first);
+
+/** Called inside OS services primitives to update budget and "pause" the
+ * protection. We need to do this because some timing protection implementation
+ * could rely in hardware that can "interrupt" kernel and as we have to call
+ * the ProtectionHook, in case of budget expiration, that "terminate stuff"
+ * (TASKs/ISRs or Applications) we have to assure kernel consistency.
+ *
+ * N.B: another budget update is done at the end of the primitive so no ticks
+ * are given for free to a TASK/ISR2 budget */
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_tp_active_pause_and_update_budgets(void)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ EE_as_tp_active_pause_and_update_budgets_impl();
+ }
+}
+
+/** Update the budgets plus restart the protection. Handle budget expiration too
+ * if it happens */
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_tp_active_update_budgets_and_restart(void)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ EE_as_tp_active_update_budgets_and_restart_impl();
+ }
+}
+
+/** This function update actual active budgets, active a new budget for
+ * the active TP, after that reassess the first expiring budget */
+__INLINE__ void __ALWAYS_INLINE__
+EE_as_tp_active_activate_budget(EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL start_first)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ EE_as_tp_active_activate_budget_impl(budget_type, ref_object_id,
+ start_first);
+ }
+}
+
+/** Stop an active budget and if the budget stopped is the actual first
+ * expiring budget reassess the new first expiring */
+__INLINE__ void __ALWAYS_INLINE__ EE_as_tp_active_stop_budget(
+ EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL
+ start_first)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ EE_as_tp_active_stop_budget_impl(budget_type, ref_object_id, start_first);
+ }
+}
+
+/* [OS064]: If a task's OsTaskExecutionBudget is reached then the Operating
+ * System module shall call the ProtectionHook() with E_OS_PROTECTION_TIME. */
+/* [OS210]: If a Category 2 ISRs OsIsrExecutionBudget is reached then the
+ * Operating System module shall call the ProtectionHook() with
+ * E_OS_PROTECTION_TIME. */
+/* [OS033]: If a Task/Category 2 ISR holds an OSEK Resource and exceeds the
+ * Os[Task|Isr]ResourceLockBudget, the Operating System module shall call the
+ * ProtectionHook() with E_OS_PROTECTION_LOCKED.
+ * (BSW11008, BSW11013, BSW11014) */
+/* [OS037]:If a Task/Category 2 ISR disables interrupts
+ * (via Suspend/Disable|All/OS|Interrupts()) and exceeds the configured
+ * Os[Task|Isr][All|OS]InterruptLockBudget, the Operating System module shall
+ * call the ProtectionHook() with E_OS_PROTECTION_LOCKED.
+ * (BSW11008, BSW11013, BSW11014) */
+void EE_as_tp_active_budget_expired(void);
+
+#else /* EE_TIMING_PROTECTION__ */
+/* void placeholders */
+#define EE_as_tp_active_set(tp_id) ((void)0)
+#define EE_as_tp_active_set_from_TASK(task_id) ((void)0)
+#define EE_as_tp_active_set_from_id_with_restart(tp_id) ((void)0)
+#define EE_as_tp_active_start_on_TASK_stacking(task_id) ((void)0)
+#define EE_as_tp_active_start_for_ISR2(isr2_id) ((void)0)
+#define EE_as_tp_active_stop() ((void)0)
+#define EE_as_tp_active_start_idle() ((void)0)
+#define EE_as_tp_active_reset_budgets() ((void)0)
+#define EE_as_tp_active_pause_and_update_budgets() ((void)0)
+#define EE_as_tp_active_update_budgets_and_restart() ((void)0)
+#define EE_as_tp_active_activate_budget(b_type, obj_id, start_first) ((void)0)
+#define EE_as_tp_active_stop_budget(b_type, obj_id, start_first) ((void)0)
+#define EE_as_tp_active_budget_expired() ((void)0)
+#define EE_as_tp_stop_budget(tp_ram_ref, budget_id) ((void)0)
+#define EE_as_tp_reset_budgets(tp_id) ((void)0)
+#define EE_as_tp_stop_interarrival_frame(tp_id) ((void)0)
+#define EE_as_tp_handle_interarrival(tp_id) EE_TRUE
+#define EE_hal_tp_stop() ((void)0)
+#endif /* EE_TIMING_PROTECTION__ */
+
+#endif /* INCLUDE_EE_KERNEL_AS_TIMING_PROT__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_base.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_base.c
new file mode 100644
index 0000000..c8a049c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_base.c
@@ -0,0 +1,165 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Basic Autosar API, common to all SCs
+ * Author: 2011, Bernardo Dal Seno
+ */
+
+#include "ee_internal.h"
+
+#ifdef EE_SERVICE_PROTECTION__
+/* Used by the kernel to flag in witch context is executing */
+/* Initialized to Idle so no API other than StartOS and Start(NonAutosar)Core
+ * can be called i main function */
+EE_TYPECONTEXT EE_as_execution_context = Idle_Context;
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+
+/* Store the actual active OS-Application */
+ApplicationType EE_as_active_app;
+
+ISRType EE_as_GetISRID(void)
+{
+ /* Error Value Flag */
+ register StatusType ev;
+ register ISRType irq;
+
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+ register EE_UREG irqnest = EE_hal_get_IRQ_nesting_level();
+#endif /* EE_MAX_ISR2 > 0 */
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETISRID);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * invalid value of the service. (BSW11009, BSW11013) */
+ /* GetISRID is callable by Task, ISR2, ErrorHook and ProtectionHook */
+ if (EE_as_execution_context > ProtectionHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+ if (irqnest > 0U) {
+ /* Inside an IRQ handler */
+ irq = EE_as_ISR_stack[irqnest - 1U].ISR_ID;
+ ev = E_OK;
+ } else {
+ irq = INVALID_ISR;
+ ev = E_OK;
+ }
+#else /* EE_MAX_ISR2 > 0 */
+ {
+ irq = INVALID_ISR;
+ ev = E_OK;
+ }
+#endif /* EE_MAX_ISR2 > 0 */
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS_INIT(EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM,
+ EE_OS_INVALID_PARAM);
+ EE_os_notify_error_from_us(OSServiceId_GetISRID, &error_parameters,
+ ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETISRID);
+ irq = INVALID_ISR;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETISRID);
+ }
+
+ return irq;
+}
+
+/* Supposed to be called by EE_as_TerminateISR2 to restore EE_as_active_app and
+ * terminate stacked task, eventually. */
+void EE_as_after_IRQ_interrupted_app(ApplicationType interrupted_app)
+{
+ EE_as_active_app = interrupted_app;
+ /* Check the OSApplication that is going to be reactivated if it is not
+ * restarting terminate the current TASK */
+ if ((EE_as_Application_RAM[interrupted_app].ApplState !=
+ APPLICATION_ACCESSIBLE) &&
+ (EE_stk_queryfirst() !=
+ EE_as_Application_ROM[interrupted_app].restart_task)) {
+ EE_as_terminate_current_app_task();
+ }
+}
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/*******************************************************************************
+ * Stack Monitoring Internal Support
+ ******************************************************************************/
+#ifdef EE_STACK_MONITORING__
+/* Used Internally in Kernel primitives */
+void EE_as_monitoring_the_stack(void)
+{
+#ifdef EE_AS_OSAPPLICATIONS__
+ if (EE_IRQ_nesting_level > 0U) {
+ EE_as_check_and_handle_stack_overflow(EE_as_active_app,
+ EE_as_Application_ROM[EE_as_active_app].ISRTOS);
+ } else {
+ EE_as_check_and_handle_stack_overflow(EE_as_active_app,
+ EE_std_thread_tos[EE_stk_queryfirst() + 1]);
+ }
+#else /* EE_AS_OSAPPLICATIONS__ */
+#ifdef __IRQ_STACK_NEEDED__
+ /* I cannot monitor ISR2 Stack In this Case */
+ /* TODO EG: Make RT-Druid Handle this configuration */
+#warning Stack Monitoring Enabled without OSApplication: In this State ISR2 \
+ Stack is not monitorable
+ if (EE_IRQ_nesting_level > 0U) {
+ return;
+ }
+#endif /* __IRQ_STACK_NEEDED__ */
+ EE_as_check_and_handle_stack_overflow(
+ EE_std_thread_tos[EE_stk_queryfirst() + 1]);
+#endif /* EE_AS_OSAPPLICATIONS__ */
+}
+#endif /* EE_STACK_MONITORING__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_ioc.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_ioc.c
new file mode 100644
index 0000000..c0dce64
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_ioc.c
@@ -0,0 +1,423 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_ioc.c
+ * @brief Autosar API and data structures for IOC module
+ * @author Francesco Esposito
+ * @date 2012
+ */
+
+#include "ee_internal.h"
+#include <string.h>
+
+/*===========================================================
+ * Static Functions (Private Implementation)
+ * ===========================================================*/
+static EE_UINT8 *EE_IOC_Buffer_push_and_get_write_addr(EE_IOC_Buffer *cbuffer,
+ EE_UINT16 data_length)
+{
+ /* Circular arithmetic to evaluate "push index" */
+ EE_UINT16 write_index;
+ EE_UINT8 *result = NULL;
+
+ if (cbuffer != NULL) {
+ write_index = (cbuffer->head + cbuffer->counter) %
+ cbuffer->buffer_length;
+ /* Increment Count (new element added)*/
+ cbuffer->counter += data_length;
+
+ result = (EE_UINT8 *)cbuffer->memory + write_index;
+ }
+
+ /* evaluate the addres where write to */
+ return result;
+}
+
+static EE_UINT8 *EE_IOC_Buffer_pop_and_get_read_addr(EE_IOC_Buffer *cbuffer,
+ EE_UINT16 data_length)
+{
+ /* evaluate the address where read to */
+ EE_UINT8 *read_addr = NULL;
+
+ if (cbuffer != NULL) {
+ read_addr = (EE_UINT8 *)cbuffer->memory + cbuffer->head;
+ /* Circular arithmetic to evaluate new head */
+ cbuffer->head = (cbuffer->head + data_length) % cbuffer->buffer_length;
+ /* Decrement count (element removed) */
+ cbuffer->counter -= data_length;
+ }
+
+ return read_addr;
+}
+
+/**
+ * @brief Check if the buffer is empty.
+ *
+ * Checks the counter of the buffer is equal to zero.
+ *
+ * @param cbuffer: c-buffer struct pointer
+ * @param num_bytes: number of bytes that buffer should contains at least
+ *
+ * @return 1 if buffer contains more or equal bytes of num_bytes
+ * 0 otherwise
+ **/
+static EE_UINT8 EE_IOC_Buffer_contains(const EE_IOC_Buffer *cbuffer,
+ EE_UINT16 num_bytes)
+{
+ EE_UINT8 result = 0U;
+
+ if (cbuffer != NULL) {
+ if (cbuffer->counter >= num_bytes) {
+ result = 1U; /* True */
+ } else {
+ result = 0U; /* False */
+ }
+ }
+
+ return result;
+}
+
+/**
+ * @brief Check if the buffer is full.
+ *
+ * Compare the counter of the buffer with the max size.
+ *
+ * @param cbuffer: c-buffer struct pointer
+ * @return 1 if in buffer are available more or equal bytes of num_bytes
+ * 0 otherwise
+ **/
+static EE_UINT8 EE_IOC_Buffer_available(const EE_IOC_Buffer *cbuffer,
+ EE_UINT16 num_bytes)
+{
+ EE_UINT8 result = 0U;
+
+ if (cbuffer != NULL) {
+ if ((cbuffer->buffer_length - cbuffer->counter) >= num_bytes) {
+ result = 1U; /* True */
+ } else {
+ result = 0U; /* False */
+ }
+ }
+
+ return result;
+}
+
+/*static EE_IOC_BufferError EE_IOC_Buffer_init(EE_IOC_Buffer * cbuffer,
+ * EE_UINT16 buffer_length, EE_UINT8 * memory)
+ * {
+ * EE_IOC_BufferError error = EE_CBUFF_OK;
+ *
+ * if(cbuffer == EE_NULL_CBUFF) {
+ * error = EE_CBUFF_ERR_NULL;
+ * }
+ *
+ * if(error == EE_CBUFF_OK){
+ * cbuffer->head = 0;
+ * cbuffer->counter = 0;
+ * cbuffer->buffer_length = buffer_length;
+ * cbuffer->memory = memory;
+ * }
+ *
+ * return error;
+ * }*/
+
+/* This functions puts a message in the buffer (push in queue) */
+static EE_IOC_BufferError EE_IOC_Buffer_push(EE_IOC_Buffer *cbuffer,
+ const EE_UINT8 *ele,
+ EE_UINT16 data_length)
+{
+ EE_UINT8 *write_addr;
+ EE_IOC_BufferError error = (EE_IOC_BufferError)EE_CBUFF_OK;
+
+ if ((cbuffer == EE_NULL_CBUFF) || (ele == NULL) || (data_length == 0U)) {
+ return (EE_IOC_BufferError)EE_CBUFF_ERR_NULL;
+ }
+
+ if (EE_IOC_Buffer_available(cbuffer, data_length) ==
+ (EE_UINT8)EE_CBUFF_OK) {
+ /* Mark current buffer as buffer having rejected data */
+ cbuffer->data_rejected = EE_CBUFF_DATA_REJECTED;
+
+ /* Set return value to warn about a full buffer */
+ error = (EE_IOC_BufferError)EE_CBUFF_ERR_TOO_MANY;
+#if !defined(BUFFER_OVERRUN_ALLOWED)
+ return error;
+#endif
+ }
+
+ write_addr = EE_IOC_Buffer_push_and_get_write_addr(cbuffer, data_length);
+
+ if (write_addr != NULL) {
+ if (data_length > 1U) {
+ EE_INT32 offset = (EE_INT8 *)write_addr -
+ (EE_INT8 *)cbuffer->memory;
+
+ /* write in array boundaries */
+ if ((offset + (EE_INT32)data_length) <=
+ (EE_INT32)cbuffer->buffer_length) {
+ (void)memcpy(write_addr, ele, (size_t)data_length);
+ } else {
+ /* write outside array boundaries */
+ EE_INT32 bytes_before_the_end =
+ (EE_INT32)cbuffer->buffer_length - offset;
+
+ EE_INT32 remaining_bytes = (EE_INT32)data_length -
+ bytes_before_the_end;
+
+ (void)memcpy(write_addr, ele, (size_t)bytes_before_the_end);
+ (void)memcpy(cbuffer->memory,
+ (const EE_INT8 *)ele + bytes_before_the_end,
+ (size_t)remaining_bytes);
+ }
+ } else {
+ ((EE_INT8 *)write_addr)[0] = ((const EE_INT8 *)ele)[0];
+ }
+ }
+
+ return error;
+}
+
+static EE_IOC_BufferError EE_IOC_Buffer_pop(EE_IOC_Buffer *cbuffer,
+ EE_UINT8 *ele,
+ EE_UINT16 data_length)
+{
+ EE_IOC_BufferError error = (EE_IOC_BufferError)EE_CBUFF_OK;
+
+ if ((cbuffer == EE_NULL_CBUFF) || (ele == NULL) || (data_length == 0U)) {
+ error = (EE_IOC_BufferError)EE_CBUFF_ERR_NULL;
+ }
+
+ if (error == (EE_IOC_BufferError)EE_CBUFF_OK) {
+ if (EE_IOC_Buffer_contains(cbuffer, data_length) ==
+ (EE_UINT8)EE_CBUFF_OK) {
+ error = (EE_IOC_BufferError)EE_CBUFF_ERR_TOO_FEW;
+ } else {
+ EE_UINT8 *read_addr = EE_IOC_Buffer_pop_and_get_read_addr(cbuffer,
+ data_length);
+
+ if ((read_addr != NULL) && (ele != NULL)) {
+ if (data_length > 1U) {
+ if (cbuffer != NULL) {
+ EE_INT32 offset = (EE_INT8 *)read_addr -
+ (EE_INT8 *)cbuffer->memory;
+
+ /* read in array boundaries */
+ if (((EE_UINT16)offset + data_length) <=
+ cbuffer->buffer_length) {
+ (void)memcpy(ele, read_addr, (size_t)data_length);
+ } else {
+ /* read outside array boundaries */
+ EE_INT32 bytes_before_the_end =
+ (EE_INT32)cbuffer->buffer_length - offset;
+
+ EE_INT32 remaining_bytes = (EE_INT32)data_length -
+ bytes_before_the_end;
+
+ (void)memcpy(ele, read_addr,
+ (size_t)bytes_before_the_end);
+ (void)memcpy((EE_INT8 *)ele + bytes_before_the_end,
+ cbuffer->memory, (size_t)remaining_bytes);
+ }
+ }
+ } else {
+ ((EE_INT8 *)ele)[0] = ((EE_INT8 *)read_addr)[0];
+ }
+ }
+ }
+ }
+
+ return error;
+}
+
+/*===========================================================
+ * Global Functions (Public Autosar Interface)
+ * ===========================================================*/
+EE_INT8 IocSend(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data)
+{
+ /* Initialise return value of the following internal library call */
+ EE_INT8 result;
+
+ /*
+ * Use id to access auto-generated data
+ */
+ result = (EE_INT8)EE_IOC_Buffer_push(&EE_ioc_enqueued_buffer[id],
+ (const EE_UINT8 *)data, (EE_UINT16)EE_ioc_enqueued_buffer[id].lenght);
+
+ /* Buffer is full */
+ if (EE_CBUFF_ERR_TOO_MANY == result) {
+ return (EE_INT8)IOC_E_LIMIT;
+ }
+
+ return (EE_INT8)IOC_E_OK;
+}
+
+EE_INT8 IocWrite(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data)
+{
+ /*
+ * Use id to access auto-generated data
+ */
+ if (data != NULL) {
+ (void)memcpy(EE_ioc_enqueued_buffer[id].memory, data,
+ (size_t)(EE_ioc_enqueued_buffer[id].lenght));
+ }
+
+ /* Always return IOC_E_OK */
+ return (EE_INT8)IOC_E_OK;
+}
+
+EE_INT8 IocReceive(EE_UINT8 id,
+ EE_IOC_DATA_PTR data)
+{
+ /* Initialise return value of the following internal library call */
+ EE_INT8 result;
+
+ /*
+ * Use id to access auto-generated data
+ */
+ result = (EE_INT8)EE_IOC_Buffer_pop(&EE_ioc_enqueued_buffer[id],
+ (EE_UINT8 *)data, (EE_UINT16)EE_ioc_enqueued_buffer[id].lenght);
+
+ /* Check if IOC refused a previous IocSend_XXX */
+ if ((EE_CBUFF_DATA_REJECTED == EE_ioc_enqueued_buffer[id].data_rejected)
+ && (result == EE_CBUFF_OK)) {
+ /* a data has been extracted from the queue, now current buffer
+ * can get back to normal if its previous status was "rejected" */
+ EE_ioc_enqueued_buffer[id].data_rejected = EE_CBUFF_DATA_ACCEPTED;
+
+ return (EE_INT8)IOC_E_LOST_DATA;
+ }
+
+ /* Buffer is empty */
+ if (EE_CBUFF_ERR_TOO_FEW == result) {
+ return (EE_INT8)IOC_E_NO_DATA;
+ }
+
+ /* result is or-ed with result (since a lost data might be occurred) */
+ return (EE_INT8)IOC_E_OK;
+}
+
+EE_INT8 IocRead(EE_UINT8 id,
+ EE_IOC_DATA_PTR data)
+{
+ /*
+ * Use id to access auto-generated data
+ */
+ if (data != NULL) {
+ (void)memcpy(data, EE_ioc_enqueued_buffer[id].memory,
+ (size_t)(EE_ioc_enqueued_buffer[id].lenght));
+ }
+
+ /* Always return IOC_E_OK */
+ return (EE_INT8)IOC_E_OK;
+}
+
+EE_INT8 IocEmptyQueue(EE_UINT8 id)
+{
+ /* Empty buffer identified by id */
+ EE_ioc_enqueued_buffer[id].head = 0U;
+ EE_ioc_enqueued_buffer[id].counter = 0U;
+
+ /* Mark this buffer as available (since it has been emptied) */
+ EE_ioc_enqueued_buffer[id].data_rejected = EE_CBUFF_DATA_ACCEPTED;
+
+ /* Always return IOC_E_OK */
+ return (EE_INT8)IOC_E_OK;
+}
+
+void IocWriteSingleElement(EE_UINT8 id,
+ EE_IOC_DATA_PTR_CONST data,
+ EE_UINT8 size,
+ EE_UINT8 parameter_number)
+{
+ if (data != NULL) {
+ (void)memcpy(EE_ioc_enqueued_buffer[id].memory +
+ (parameter_number * size), data, (size_t)size);
+ }
+}
+
+void IocReadSingleElement(EE_UINT8 id,
+ EE_IOC_DATA_PTR data,
+ EE_UINT8 size,
+ EE_UINT8 parameter_number)
+{
+ if (data != NULL) {
+ (void)memcpy(data, EE_ioc_enqueued_buffer[id].memory +
+ (parameter_number * size), (size_t)size);
+ }
+}
+
+#ifdef EE_MASTER_CPU
+/** @brief Flag used to signal a IOC request */
+EE_BIT EE_SHARED_UDATA EE_as_rpc_IOC[EE_MAX_CPU];
+#endif /* EE_MASTER_CPU */
+
+void EE_as_IOC_signal_callbacks(EE_UINT8 id)
+{
+ /* Unitializated locals */
+ register CoreIdType ioc_cpu;
+ register EE_TYPESPIN spinlock_id;
+ /* Initialized locals */
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+
+ /* Get the core that shall receive the notification */
+ ioc_cpu = EE_as_rpc_IOC_channels[id];
+
+ /* Select the Right Spinlock Where Synchronize on */
+ spinlock_id = EE_as_core_spinlocks[ioc_cpu];
+
+ /* Enter RPC Critical Section */
+ EE_hal_spin_in(spinlock_id);
+
+ /* Signal the IOC Request */
+ EE_as_rpc_IOC[ioc_cpu] = 1U;
+
+ if (EE_as_rpc_serving[ioc_cpu] == 0U) {
+ /* In any case we shall assure that EE_hal_IRQ_interprocessor can
+ * handle multiple sequential calls */
+ EE_hal_IRQ_interprocessor((EE_UINT8)ioc_cpu);
+ }
+
+ /* Exit RPC Critical Section */
+ EE_hal_spin_out(spinlock_id);
+
+ EE_hal_end_nested_primitive(flag);
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_mem_prot.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_mem_prot.c
new file mode 100644
index 0000000..45873d7
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_mem_prot.c
@@ -0,0 +1,405 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * APIs and functions used for memory protection
+ * Author: 2011 Bernardo Dal Seno
+ */
+
+#include <ee_internal.h>
+
+/*
+ * Functions to enable and disable interrupts used when memory protection is
+ * active. Interrupts must be enabled/disabled when returning from the syscall
+ * made from user space.
+ */
+
+/* The variables below have the "EE_oo" prefix because they could be used also
+ * for the OO kernel. */
+
+/* IRQ state at the time DisableAllInterrupts() is called. This is global,
+ * because it's used by other APIs to check if they are called inside a
+ * Disable/Enable section. */
+EE_FREG EE_oo_all_irq_prev_state = EE_HAL_IRQSTATE_INVALID;
+
+/* IRQ state at the time the first SuspendAllInterrupts() is called */
+static EE_FREG EE_oo_res_all_irq_prev_state;
+
+EE_FREG EE_as_DisableAllInterrupts(EE_FREG prev)
+{
+ EE_FREG next;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+ EE_oo_all_irq_prev_state = EE_hal_set_irq_valid_flag(prev);
+ next = EE_hal_clear_irq_flag(prev);
+ ++EE_oo_IRQ_disable_count;
+
+ /* Enable DisableAllInterrupts TP budget, if needed */
+ if (EE_oo_IRQ_disable_count == 1U) {
+ EE_as_tp_active_activate_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+ return next;
+}
+
+EE_FREG EE_as_EnableAllInterrupts(EE_FREG prev)
+{
+ EE_FREG next;
+ EE_FREG prev_state;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+ next = prev;
+ prev_state = EE_oo_all_irq_prev_state;
+ if (prev_state == EE_HAL_IRQSTATE_INVALID) {
+ /* No previous DisableAllInterrupts(): do nothing */
+ } else {
+ EE_oo_all_irq_prev_state = EE_HAL_IRQSTATE_INVALID;
+ next = EE_hal_copy_irq_flag(prev_state, next);
+ --EE_oo_IRQ_disable_count;
+ }
+
+ /* Stop DisableAllInterrupts TP budget, if needed */
+ if (EE_oo_IRQ_disable_count == 0U) {
+ EE_as_tp_active_stop_budget(EE_ALL_INTERRUPT_LOCK_BUDGET, INVALID_OBJECTID,
+ EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+ return next;
+}
+
+EE_FREG EE_as_SuspendAllInterrupts(EE_FREG prev)
+{
+ EE_FREG next;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+ next = prev;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ next = EE_hal_clear_irq_flag(next);
+ EE_oo_res_all_irq_prev_state = prev;
+ }
+ ++EE_oo_IRQ_disable_count;
+
+ /* Enable DisableAllInterrupts TP budget, if needed */
+ if (EE_oo_IRQ_disable_count == 1U) {
+ EE_as_tp_active_activate_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+ return next;
+}
+
+EE_FREG EE_as_ResumeAllInterrupts(EE_FREG prev)
+{
+ EE_FREG next;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+ next = prev;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ /* No previous SuspendAllInterrupts(): do nothing */
+ } else {
+ --EE_oo_IRQ_disable_count;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ next = EE_hal_copy_irq_flag(
+ EE_oo_res_all_irq_prev_state, next);
+ /* Stop DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_stop_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+ }
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+ return next;
+}
+
+/* FIXME: Currently ERIKA has not defined any HAL primitives to selectively
+ * disable ISR2s. Therefore, SuspendOSInterrupts() suspends all interrupts. */
+EE_FREG EE_as_SuspendOSInterrupts(EE_FREG prev)
+{
+ return EE_as_SuspendAllInterrupts(prev);
+}
+
+EE_FREG EE_as_ResumeOSInterrupts(EE_FREG prev)
+{
+ return EE_as_ResumeAllInterrupts(prev);
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+AccessType EE_as_CheckTaskMemoryAccess(TaskType TaskID,
+ MemoryStartAddressType Address,
+ MemorySizeType Size)
+{
+ /* This function will be called only by a syscall, interrupts will
+ * be handled by the syscall handler */
+ register AccessType ret;
+ /* Error Value Flag */
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CHECKTASKMEMORYACCESS);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CheckTaskMemoryAccess is callable by Task, ISR2, ErrorHook and
+ * ProtectionHook */
+ if (EE_as_execution_context > ProtectionHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ /* Invalid TaskID: no permission */
+ ret = NO_ACCESS;
+ ev = E_OK;
+ } else {
+ ApplicationType app;
+ app = EE_th_app[TaskID + 1];
+ ret = EE_hal_get_app_mem_access(app, Address, Size);
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(TaskID);
+ EE_OS_ERROR_PARAMETERS_PARAM2_REF(memory_address, Address);
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(Size);
+
+ EE_os_notify_error_from_us(OSServiceId_CheckTaskMemoryAccess,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKTASKMEMORYACCESS);
+ ret = NO_ACCESS;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKTASKMEMORYACCESS);
+ }
+
+ return ret;
+}
+
+AccessType EE_as_CheckISRMemoryAccess(ISRType ISRID,
+ MemoryStartAddressType Address,
+ MemorySizeType Size)
+{
+ /* This function will be called only by a syscall, interrupts will
+ * be handled by the syscall handler */
+ /* Invalid ISRID: no permission */
+ register AccessType ret;
+ /* Error Value Flag */
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CHECKISRMEMORYACCESS);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CheckISRMemoryAccess is callable by Task, ISR2, ErrorHook and
+ * ProtectionHook */
+ if (EE_as_execution_context > ProtectionHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if defined(EE_MAX_ISR_ID) && (EE_MAX_ISR_ID > 0)
+ if (ISRID < (ISRType)EE_MAX_ISR_ID) {
+ ApplicationType app;
+ app = EE_as_ISR_ROM[ISRID].ApplID;
+ ret = EE_hal_get_app_mem_access(app, Address, Size);
+ ev = E_OK;
+ } else
+#endif /* EE_MAX_ISR_ID > 0 */
+ {
+ ret = NO_ACCESS;
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(ISRID);
+ EE_OS_ERROR_PARAMETERS_PARAM2_REF(memory_address, Address);
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(Size);
+
+ EE_os_notify_error_from_us(OSServiceId_CheckISRMemoryAccess,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKISRMEMORYACCESS);
+ ret = NO_ACCESS;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKISRMEMORYACCESS);
+ }
+ return ret;
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+StatusType EE_as_CallTrustedFunction(TrustedFunctionIndexType FunctionIndex,
+ TrustedFunctionParameterRefType FunctionParams)
+{
+ register StatusType ev;
+ /* This function will be called only by a syscall, interrupts will
+ * be handled by the syscall handler, but TP have to be handled here... */
+ register EE_as_Application_RAM_type *const app_RAM_ptr =
+ &EE_as_Application_RAM[EE_as_active_app];
+
+ /* Reaction to timing protection can be defined to terminate the
+ * OSApplication. If a task is inside CallTrustedFunction() and task
+ * rescheduling takes place within the same OSApplication, the newly running
+ * higher priority task may cause timing protection and terminate the
+ * OSApplication, thus indirectly aborting the trusted function.
+ * To avoid this, the scheduling of other Tasks which belong to the same
+ * OS-Application as the caller needs to be restricted, as well as the
+ * availability of interrupts of the same OS-Application. */
+ /* [SWS_Os_00565]: When CallTrustedFunction() is called and the caller of
+ * CallTrustedFunction() is supervised with timing protection, the Operating
+ * System shall delay any timing protection errors until the return of
+ * CallTrustedFunction(). */
+ /* [SWS_Os_00564]: If such a violation is detected inside a nested call
+ * sequence of CallTrustedFunction() of a task, the delay shall last until
+ * the return of the last CallTrustedFunction(). */
+ /* The following handle enventual TP errors. The check if we are inside a
+ * Trusted Function Call inside, because the following function is called at
+ * the end of all ERIKA Services, and the check have to be done at every
+ * service's call */
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CALLTRUSTEDFUNCTION);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CallTrustedFunction is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+ /* [OS623]: The OS API function CallTrustedFunction shall return E_OS_ACCESS
+ * in extended status if the target trusted function is part of an
+ * OS-Application on another core. (BSW4080013)
+ * XXX: This cannot never happens in our implementation */
+
+ /* [SWS_Os_00100] If CallTrustedFunction() is called and the called trusted
+ * function is not configured the Operating System module shall call the
+ * ErrorHook with E_OS_SERVICEID. */
+ if ((FunctionIndex < EE_MAX_SYS_SERVICEID) &&
+ (FunctionIndex >= EE_SYSCALL_NR)) {
+ ev = E_OS_SERVICEID;
+ } else {
+ ++app_RAM_ptr->TrustedFunctionCallsCounter;
+ /* Re-enable interrupts before call the TRUSTED Function */
+ EE_hal_enableIRQ();
+ ev = ((EE_TRUSTEDFUNCTYPE)EE_syscall_table[FunctionIndex])(FunctionIndex,
+ FunctionParams);
+ /* Disable them again */
+ EE_hal_disableIRQ();
+ /* Decrement TRUSTED function call counter */
+ --app_RAM_ptr->TrustedFunctionCallsCounter;
+
+ /* Monitor the stack here: after the function call & before scheduling */
+ EE_as_monitoring_the_stack();
+ /* A Task Activation could have been delayed */
+ if (ev == E_OK) {
+ /* Check for preemption:
+ * this test has to be done only if we are inside a TASK. The check
+ * that we are not in a nested Trusted Functions Call, is done inside the
+ * preemption point */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ /* we are inside a task */
+ EE_oo_preemption_point();
+ }
+ }
+ }
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_function_index);
+ EE_OS_PARAM(os_function_params);
+ EE_OS_PARAM_VALUE(os_function_index, FunctionIndex);
+ EE_OS_PARAM_REF(os_function_params, trusted_function_parameter_ref,
+ FunctionParams);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_CallTrustedFunction, os_function_index,
+ os_function_params, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CALLTRUSTEDFUNCTION);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_multicore.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_multicore.c
new file mode 100644
index 0000000..5a4a056
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_multicore.c
@@ -0,0 +1,212 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_multicore.c
+ * @brief Basic Autosar API and data structures for multicore management
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_STARTOS__
+/* Flag set by StartOs to signal that the OS is started */
+extern EE_UREG volatile EE_oo_started;
+
+#if defined(EE_MAX_CPU) && (EE_MAX_CPU > 1)
+/** @brief The following contains cores start addresses */
+extern EE_ADDR const EE_SHARED_CDATA EE_as_core_start_addresses[EE_MAX_CPU - 1];
+#endif /* EE_MAX_CPU */
+
+#ifdef EE_MASTER_CPU
+/** @brief The following contains cores application modes: N.B it is used inside
+ * StartOS */
+AppModeType volatile EE_SHARED_UDATA EE_as_os_application_mode[EE_MAX_CPU];
+
+/** @brief mask for Autosar cores started */
+EE_UREG volatile EE_SHARED_IDATA
+ EE_as_core_mask = ((EE_UREG)1U << OS_CORE_ID_MASTER);
+
+/** @brief counter for Autosar cores started (OS_CORE_ID_MASTER is always an
+ * AUTOSAR by default) */
+EE_UREG volatile EE_SHARED_IDATA EE_as_core_started = 1U;
+
+/** @brief mask for non Autosar cores started */
+EE_UREG volatile EE_SHARED_UDATA EE_as_not_as_core_mask;
+
+#endif /* EE_MASTER_CPU */
+
+void EE_as_StartCore(CoreIdType CoreID,
+ StatusType *Status)
+{
+ /* Error Value */
+ register StatusType ev;
+ /* Primitive Lock Procedure */
+ register const EE_FREG flag = EE_hal_begin_nested_primitive();
+ /* Variable introduced to meet MISRA 12.1 in the next else if statement */
+ register EE_UREG EE_as_core_mask_local = EE_as_core_mask;
+
+ /* Get CPU0 Spinlocks to serialize core starting procedure. As
+ * implementation choice we serialize core activation on core0 spinlock
+ * that is the one with max priority */
+ EE_hal_spin_in(EE_SPINLOCK_CORE0);
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STARTCORE);
+
+ if (CoreID >= EE_MAX_CPU) {
+ /* [OS677] The function StartCore shall start one core that shall run under
+ * the control of the AUTOSAR OS. (BSW4080006, BSW4080026, BSW4080027)
+ */
+ /* [OS681] There is no call to the ErrorHook() if an error occurs during
+ * StartCore(); (BSW4080006, BSW4080026, BSW4080027) */
+ /* XXX: AS IMPLEMENTATION CHOICE THE CONFIGURATOR ASSIGN CORES IN ASCENDING
+ * ORDER OF ID AUTOMATICALLY. THERE IS NO WAY FOR USER TO SELECT
+ * EXPLICITLY WICH CORE ASSIGN TO AN SPECIFIC SLAVE CONFIGURATION.
+ * So if an ID is lower than EE_MAX_CPU is valid to call StartCore on.
+ * FIXME: Probably this behavior could be not perfectly compliant so it
+ * should be checked */
+ ev = E_OS_ID;
+ } else if (EE_oo_started != 0U) {
+ /* [OS606] The AUTOSAR specification does not support the activation of
+ * AUTOSAR cores after calling StartOS on that core. If StartCore is called
+ * after StartOS it shall return with E_OS_ACCESS in extended status.
+ * (BSW4080001) */
+ /* [OS678] Calls to the StartCore function after StartOS() shall return with
+ * E_OS_ACCESS and the core shall not be started.
+ * (BSW4080006, BSW4080026, BSW4080027) */
+ ev = E_OS_ACCESS;
+ } else if (((EE_as_core_mask_local | EE_as_not_as_core_mask) &
+ ((EE_UREG)1U << CoreID)) != 0U) {
+ /* [OS679] If the parameter CoreIDs refers to a core that was already
+ * started by the function StartCore the related core is ignored and
+ * E_OS_STATE shall be returned. (BSW4080006, BSW4080026, BSW4080027) */
+ /* [OS680] If the parameter CoreID refers to a core that was already
+ * started by the function StartNonAutosarCore the related core is
+ * ignored and E_OS_STATE shall be returned.
+ * (BSW4080006, BSW4080026, BSW4080027) */
+ ev = E_OS_STATE;
+ } else {
+ /* Really start the core if we are not in MASTER core */
+ if (CoreID != OS_CORE_ID_MASTER) {
+ /* Flag that core is started as Autosar core */
+ EE_as_core_mask |= ((EE_UREG)1U << CoreID);
+ /* Increment the Autosar Cores counter */
+ ++EE_as_core_started;
+
+ EE_hal_start_core(CoreID, EE_as_core_start_addresses[CoreID - 1]);
+ }
+
+ ev = E_OK;
+ }
+
+ /* Restore the initial conditions */
+ EE_hal_spin_out(EE_SPINLOCK_CORE0);
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTCORE);
+
+ EE_hal_end_nested_primitive(flag);
+
+ if (Status != NULL) {
+ *Status = ev;
+ }
+
+ return;
+}
+
+void EE_as_StartNonAutosarCore(CoreIdType CoreID,
+ StatusType *Status)
+{
+ /* Error Value */
+ register StatusType ev;
+ /* Primitive Lock Procedure */
+ register const EE_FREG flag = EE_hal_begin_nested_primitive();
+ /* Variable introduced to meet MISRA 12.1 in the next else if statement */
+ register EE_UREG EE_as_core_mask_local = EE_as_core_mask;
+
+ /* Get CPU0 Spinlocks to serialize core starting procedure */
+ EE_hal_spin_in(EE_SPINLOCK_CORE0);
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STARTNONAUTOSARCORE);
+ /* [OS683] The function StartNonAutosarCore shall start a core that is not
+ * controlled by the AUTOSAR OS. (BSW4080006, BSW4080026, BSW4080027) */
+
+ /* EE_NUMBER_OF_CORES SHALL be defined in MCU layer (ideally in multicore
+ * support header */
+ if (CoreID >= EE_NUMBER_OF_CORES) {
+ /* [OS685] If the parameter CoreID refers to an unknown core the function
+ * StartNonAutosarCore has effect and sets "Status" to E_OS_ID.
+ * (BSW4080006, BSW4080026, BSW4080027) */
+
+ ev = E_OS_ID;
+ } else if (((EE_as_core_mask_local | EE_as_not_as_core_mask) &
+ ((EE_UREG)1U << CoreID)) != 0U) {
+ /* [OS684] If the parameter CoreID refers to a core that was already
+ * started by the function StartNonAutosarCore has no effect and sets
+ * "Status" to E_OS_STATE. (BSW4080006, BSW4080026, BSW4080027) */
+ /* XXX: Specification do not states for StartNonAutosarCore what to do if
+ * core has been start by StartCore, I choose to handle it has error */
+ ev = E_OS_STATE;
+ } else {
+ /* Really start the core if we are not in MASTER core */
+ if (CoreID != OS_CORE_ID_MASTER) {
+ /* Flag that core is started as non Autosar core */
+ EE_as_not_as_core_mask |= ((EE_UREG)1U << CoreID);
+
+ EE_hal_start_core(CoreID, EE_as_core_start_addresses[CoreID - 1]);
+ }
+
+ ev = E_OK;
+ }
+
+ /* Restore the initial conditions */
+ EE_hal_spin_out(EE_SPINLOCK_CORE0);
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTNONAUTOSARCORE);
+
+ EE_hal_end_nested_primitive(flag);
+
+ if (Status != NULL) {
+ *Status = ev;
+ }
+
+ return;
+}
+
+#endif /* __PRIVATE_STARTOS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_osapp.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_osapp.c
new file mode 100644
index 0000000..77f0d3a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_osapp.c
@@ -0,0 +1,993 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_osapp.c
+ * @brief API related to OS-applications
+ * @author Bernardo Dal Seno
+ * @date 2012
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#include "ee_internal.h"
+
+#if 0 /* Begin Comment */
+ApplicationType EE_as_GetApplicationID_internal(void)
+{
+ ApplicationType app;
+
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+ EE_UREG irqnest;
+ irqnest = EE_hal_get_IRQ_nesting_level();
+ if (irqnest > 0U) {
+ /* Inside an IRQ handler */
+ ISRType irq;
+ irq = EE_as_ISR_stack[irqnest - 1U].ISR_ID;
+ app = EE_as_ISR_ROM[irq].ApplID;
+ } else
+#endif /* defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0) */
+ {
+ EE_TID t = EE_stk_queryfirst();
+ /* if t == INVALID_TASK the result is still correct */
+ app = EE_th_app[t + 1];
+ }
+ return app;
+}
+#endif /* End Comment */
+
+ApplicationType EE_as_GetApplicationID(void)
+{
+ register StatusType ev;
+ register ApplicationType app;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETAPPLICATIONID);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetApplicationID is callable by Task, ISR2, ErrorHook, ProtectionHook,
+ * Pre/Post Task Hook, Startup Hook & ShutdownHook */
+ if (EE_as_execution_context > ShutdownHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+ {
+ app = EE_as_active_app;
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS_INIT(EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM,
+ EE_OS_INVALID_PARAM);
+ EE_os_notify_error_from_us(OSServiceId_GetApplicationID,
+ &error_parameters, ev);
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETAPPLICATIONID);
+ app = INVALID_OSAPPLICATION;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETAPPLICATIONID);
+ }
+ return app;
+}
+
+ObjectAccessType EE_as_CheckObjectAccess_internal(ApplicationType ApplID,
+ ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID)
+{
+ /* [OS504] The Operating System module shall deny access to Operating System
+ * objects from other OS-Applications to an OS-Application which is not in
+ * state APPLICATION_ACCESSIBLE. */
+ ObjectAccessType access = NO_ACCESS;
+
+ if ((ApplID < EE_MAX_APP) &&
+ (EE_as_Application_RAM[ApplID].ApplState == APPLICATION_ACCESSIBLE)) {
+#ifdef EE_SERVICE_PROTECTION__
+ switch (ObjectType) {
+ case OBJECT_TASK:
+ if ((EE_TID)ObjectID < EE_MAX_TASK) {
+ access = (EE_TASK_ACCESS(ObjectID, ApplID)) ? ACCESS : NO_ACCESS;
+ }
+ break;
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+ case OBJECT_ISR:
+ if (ObjectID < EE_MAX_ISR_ID) {
+ access = (EE_ISR_ACCESS(ObjectID, ApplID)) ? ACCESS : NO_ACCESS;
+ }
+ break;
+#endif /* EE_MAX_ISR2 > 0 */
+#ifndef __OO_NO_RESOURCES__
+ case OBJECT_RESOURCE:
+ if (ObjectID < EE_MAX_RESOURCE) {
+ access = (EE_RESOURCE_ACCESS(ObjectID, ApplID)) ? ACCESS :
+ NO_ACCESS;
+ }
+ break;
+#endif /* !__OO_NO_RESOURCES__ */
+#if defined(EE_MAX_ALARM) && (EE_MAX_ALARM > 0)
+ case OBJECT_ALARM:
+ if (ObjectID < EE_MAX_ALARM) {
+ access = (EE_ALARM_ACCESS(ObjectID, ApplID)) ? ACCESS : NO_ACCESS;
+ }
+ break;
+
+ case OBJECT_COUNTER:
+ if (ObjectID < EE_MAX_COUNTER) {
+ access = (EE_COUNTER_ACCESS(ObjectID, ApplID)) ? ACCESS : NO_ACCESS;
+ }
+#endif /* EE_MAX_ALARM > 0 */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ case OBJECT_SCHEDULETABLE:
+ if (ObjectID < EE_MAX_SCHEDULETABLE) {
+ access = (EE_SCHED_TABLE_ACCESS(ObjectID, ApplID)) ? ACCESS :
+ NO_ACCESS;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+ default:
+ access = NO_ACCESS;
+ break;
+ }
+#else /* EE_SERVICE_PROTECTION__ */
+ access = ACCESS;
+#endif /* EE_SERVICE_PROTECTION__ */
+ }
+
+ return access;
+}
+
+ObjectAccessType EE_as_CheckObjectAccess(ApplicationType ApplID,
+ ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID)
+{
+ register StatusType ev;
+ register ObjectAccessType access;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CHECKOBJECTACCESS);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CheckObjectAccess is callable by Task, ISR2, ErrorHook and ProtectionHook */
+ if (EE_as_execution_context > ProtectionHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+ {
+ access = EE_as_CheckObjectAccess_internal(ApplID, ObjectType, ObjectID);
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS_INIT({ ApplID }, { ObjectType }, { ObjectID });
+ EE_os_notify_error_from_us(OSServiceId_CheckObjectAccess,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKOBJECTACCESS);
+ access = NO_ACCESS;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKOBJECTACCESS);
+ }
+
+ return access;
+}
+
+#ifdef EE_SERVICE_PROTECTION__
+ApplicationType EE_as_CheckObjectOwnership_internal(ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID)
+{
+ ApplicationType app = INVALID_OSAPPLICATION;
+
+ switch (ObjectType) {
+ case OBJECT_TASK:
+ if ((EE_TID)ObjectID < EE_MAX_TASK) {
+ app = EE_th_app[(ObjectID + 1U)];
+ }
+ break;
+
+#if defined(EE_MAX_ISR_ID) && (EE_MAX_ISR_ID > 0)
+ case OBJECT_ISR:
+ if (ObjectID < EE_MAX_ISR_ID) {
+ app = EE_as_ISR_ROM[ObjectID].ApplID;
+ }
+ break;
+#endif /* EE_MAX_ISR_ID > 0 */
+
+#if defined(EE_MAX_ALARM) && (EE_MAX_ALARM > 0)
+ case OBJECT_ALARM:
+ if (ObjectID < EE_MAX_ALARM) {
+ app = EE_alarm_ROM[ObjectID].ApplID;
+ }
+ break;
+
+ case OBJECT_COUNTER:
+ if (ObjectID < EE_MAX_COUNTER) {
+ app = EE_counter_ROM[ObjectID].ApplID;
+ }
+#endif /* EE_MAX_ALARM > 0 */
+
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ case OBJECT_SCHEDULETABLE:
+ if (ObjectID < EE_MAX_SCHEDULETABLE) {
+ app = EE_as_Schedule_Table_ROM[ObjectID].ApplID;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+ default:
+ break;
+ }
+
+ return app;
+}
+
+ApplicationType EE_as_CheckObjectOwnership(ObjectTypeType ObjectType,
+ EE_os_param_id ObjectID)
+{
+ register StatusType ev;
+ register ApplicationType app;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CHECKOBJECTOWNERSHIP);
+
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CheckObjectOwnership is callable by Task, ISR2, ErrorHook and
+ * ProtectionHook */
+ if (EE_as_execution_context > ProtectionHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else {
+ app = EE_as_CheckObjectOwnership_internal(ObjectType, ObjectID);
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS_INIT({ ObjectType }, { ObjectID }, EE_OS_INVALID_PARAM);
+
+ EE_os_notify_error_from_us(OSServiceId_CheckObjectOwnership,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKOBJECTOWNERSHIP);
+ app = INVALID_OSAPPLICATION;
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHECKOBJECTOWNERSHIP);
+ }
+
+ return app;
+}
+#endif /* EE_SERVICE_PROTECTION__ */
+
+StatusType EE_as_GetApplicationState(ApplicationType Application,
+ ApplicationStateRefType Value)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETAPPLICATIONSTATE);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetApplicationState is callable by Task, ISR2, ErrorHook, ProtectionHook,
+ * Pre- and Post- TaskHook, StartupHook and ShutdownHook */
+ if (EE_as_execution_context > ShutdownHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+ /* [OS566]: The Operating System API shall check in extended mode all
+ * pointer argument for NULL pointer and return OS_E_PARAM_POINTER
+ * if such argument is NULL. +
+ * MISRA dictate NULL check for pointers always. */
+ if (Value == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if defined(EE_SERVICE_PROTECTION__) && defined(__EE_MEMORY_PROTECTION__)
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app, Value,
+ sizeof(*Value)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ && __EE_MEMORY_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(Application)) {
+ EE_os_param as_app_state_ref;
+ EE_os_param const unmarked_app_id = {
+ EE_AS_UNMARK_REMOTE_ID(Application)
+ };
+ as_app_state_ref.application_state_ref = Value;
+ /* Forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc_from_us(OSServiceId_GetApplicationState, unmarked_app_id,
+ as_app_state_ref, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [OS495]: If the <Application> in a call of GetApplicationState() is not
+ * valid GetApplicationState() shall return E_OS_ID. */
+ if (Application >= EE_MAX_APP) {
+ ev = E_OS_ID;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* XXX: ApplicationStateType is an enum so an integer, so a
+ * read it SHOULD Atomic (Check this in Architectures other than TriCore) */
+ (*Value) = EE_as_Application_RAM[Application].ApplState;
+ ev = E_OK;
+ }
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(Application);
+ EE_OS_ERROR_PARAMETERS_PARAM2_REF(application_state_ref, Value);
+
+ /* Begin the critical section here */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+ EE_os_notify_error_from_us(OSServiceId_GetApplicationState,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETAPPLICATIONSTATE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETAPPLICATIONSTATE);
+ }
+
+ return ev;
+}
+
+/* ==========================================================================
+ * OSApplication Termination
+ * ========================================================================== */
+void EE_as_terminate_current_app_task(void)
+{
+ register EE_TID current_task = EE_stk_queryfirst();
+
+ /* If current task still holds OSEK Resources, release them. */
+ (void)EE_oo_release_all_resources(current_task);
+
+ /* Force the spinlock release for current task */
+ (void)EE_as_release_all_spinlocks(current_task);
+
+#ifndef __OO_NO_CHAINTASK__
+ EE_th_terminate_nextask[current_task] = EE_NIL;
+#endif /* __OO_NO_CHAINTASK__ */
+
+#if defined(__OO_BCC2__) || defined(__OO_ECC2__)
+ /* This Trick will fix the problem of MAX activation that grows if the
+ * TASK is RUNNING and another instance of the same TASK is READY in the
+ * moment of termination of its OSApplication */
+ if (EE_th_rnact[current_task] == EE_th_rnact_max[current_task]) {
+ --EE_th_rnact[current_task];
+ }
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+ EE_hal_terminate_task(current_task);
+}
+
+static void EE_as_task_other_cleanup(EE_TID tid)
+{
+ /* Reset remaining activations...*/
+#if defined(__OO_BCC1__) || defined(__OO_ECC1__)
+ EE_th_rnact[tid] = 1;
+#else /* __OO_BCC1__ || __OO_ECC1__ */
+ EE_th_rnact[tid] = EE_th_rnact_max[tid];
+#endif /* __OO_BCC1__ || __OO_ECC1__ */
+
+ /* Reset ORTI priority if needed */
+ EE_ORTI_set_th_priority(tid, 0U);
+
+ /* Put TASK status as Suspended */
+ EE_th_status[tid] = SUSPENDED;
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ /* Remove events eventually set (I could check but if it is an extended
+ * TASK with EE_th_is_extended[] array, but it would be only cycles time). */
+ EE_th_event_active[tid] = 0U;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+ /* [SWS_Os_00473]: The Operating System module shall reset a task’s
+ * OsTaskExecutionBudget on a transition to the SUSPENDED or WAITING states.
+ * (SRS_Os_11008) */
+ /* The TASK shall be as it was when the OS Started: Reset Everything */
+ EE_as_tp_reset_budgets(EE_AS_TP_ID_FROM_TASK(tid));
+ EE_as_tp_stop_interarrival_frame(EE_AS_TP_ID_FROM_TASK(tid));
+}
+
+static void EE_as_terminate_preempted_task(EE_TID tid)
+{
+ /* If task still holds OSEK Resources, release them. */
+ (void)EE_oo_release_all_resources(tid);
+
+ /* Force the spinlock release for task */
+ (void)EE_as_release_all_spinlocks(tid);
+
+ /* Reset the thread priority bit in the system_ceiling. */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[tid];
+
+ /* Make the clean-up of other data structures related to scheduler */
+ EE_as_task_other_cleanup(tid);
+ /* TASK stack rewind */
+ EE_hal_terminate_other_task(tid);
+}
+
+/* Terminate stacked TASKs belonging to app */
+static void EE_as_app_terminate_stacked_tasks(ApplicationType app)
+{
+ /* Indexes used to traverse the stacked queue */
+ EE_TID current, previous, next;
+
+ /* Remove TASKs from the stacked queue starting from the first preempted
+ * task. (Current stacked TASK eventually will be terminated at the end of
+ * primitive) */
+ previous = EE_stk_queryfirst();
+ current = EE_th_next[previous];
+ while (current != EE_NIL) {
+ /* Get the next */
+ next = EE_th_next[current];
+ /* Check if the stacked task have to be terminated */
+ if (EE_th_app[current + 1] == app) {
+ /* Terminate the TASK */
+ EE_as_terminate_preempted_task(current);
+ /* Removing the task from the queue */
+ EE_th_next[previous] = next;
+ } else {
+ /* Otherwise current will be next previous */
+ previous = current;
+ }
+ current = next;
+ }
+}
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+static void EE_as_app_terminate_waiting_tasks(ApplicationType app)
+{
+ /* Index used to cycle over TASKs' status */
+ EE_TID tid;
+
+ for (tid = 0; tid < EE_MAX_TASK; ++tid) {
+ /* If the TASK and belong to the given app... */
+ if (EE_th_app[tid + 1] == app) {
+ /* and it is waiting... */
+ if (EE_th_status[tid] == WAITING) {
+ /* It have to be terminated. ( Do not check for resources and spinlocks
+ * release, a TASK MUST NOT hold any resource/spinlock before wait ) */
+
+ /* Remove the wait flag, mask and active events */
+ EE_th_waswaiting[tid] = 0U;
+ EE_th_event_waitmask[tid] = 0U;
+ EE_th_event_active[tid] = 0U;
+
+ /* Reset remaining activations...*/
+#ifdef __OO_ECC1__
+ EE_th_rnact[tid] = 1;
+#else
+ EE_th_rnact[tid] = EE_th_rnact_max[tid];
+#endif /* __OO_ECC1__ */
+
+ /* Reset ORTI priority if needed */
+ EE_ORTI_set_th_priority(tid, 0U);
+ /* Put TASK status as Suspended */
+ EE_th_status[tid] = SUSPENDED;
+
+ /* Make the clean-up of other data structures related to scheduler */
+ EE_as_task_other_cleanup(tid);
+ /* TASK stack rewind */
+ EE_hal_terminate_other_task(tid);
+ }
+ }
+ }
+}
+#else /* __OO_ECC1__ || __OO_ECC2__ */
+/* No waiting TASKs */
+#define EE_as_app_terminate_waiting_tasks(app) ((void)0U)
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+/**
+ * This function remove tasks belonging to an application from the ready queue
+ */
+#if defined(__OO_BCC1__) || defined(__OO_ECC1__)
+static void EE_as_terminate_app_tasks(ApplicationType app)
+{
+ /* Indexes used to traverse the ready queue */
+ EE_TID current, previous;
+
+ /* Terminate stacked tasks belonging to app */
+ EE_as_app_terminate_stacked_tasks(app);
+ /* If needed I have to cycle to search eventual TASK in waiting status to be
+ * Terminated */
+ EE_as_app_terminate_waiting_tasks(app);
+
+ /* Move the head of the the ready queue until the queue is not EMPTY and the
+ * first element doesn't belong to app */
+ while ((EE_rq_first != EE_NIL) && (EE_th_app[EE_rq_first + 1] == app)) {
+ /* Terminate the task */
+ EE_as_task_other_cleanup(EE_rq_first);
+ EE_rq_first = EE_th_next[EE_rq_first];
+ }
+
+ /* Remove elements inside ready queue, if the queue is still NOT EMPTY */
+ current = EE_rq_first;
+ previous = current;
+
+ while (current != EE_NIL) {
+ /* Get the next */
+ EE_TID next = EE_th_next[current];
+ /* If the current have to be removed */
+ if (EE_th_app[current + 1] == app) {
+ /* Make the clean-up of other data structures related to ready queue */
+ EE_as_task_other_cleanup(current);
+ /* Assign previous-next to next */
+ EE_th_next[previous] = next;
+ } else {
+ /* Otherwise current will be next previous */
+ previous = current;
+ }
+ /* Move the current to next at the end */
+ current = next;
+ }
+}
+#elif defined(__OO_BCC2__) || defined(__OO_ECC2__)
+
+static void EE_as_terminate_app_tasks(ApplicationType app)
+{
+ /* First non-empty queue */
+ EE_INT8 x;
+ /* Indexes used to traverse the priority-ready queue */
+ EE_TYPEPAIR current, previous, next;
+ /* Hold "current" tid */
+ EE_TID tid;
+
+ /* Terminate stacked tasks belonging to app */
+ EE_as_app_terminate_stacked_tasks(app);
+ /* If needed I have to cycle to search eventual TASK in waiting status to be
+ * Terminated */
+ EE_as_app_terminate_waiting_tasks(app);
+
+ x = EE_rq_get_first_not_empty_queue();
+ while (x != (EE_INT8)-1) {
+ /* Move the head of the the priority ready queue until the queue is not
+ * EMPTY and the first element doesn't belong to app */
+ current = EE_rq_queues_head[x];
+ while (current != (EE_TYPEPAIR)-1) {
+ /* Get the next */
+ next = EE_rq_pairs_next[current];
+ /* Hold "current" tid */
+ tid = EE_rq_pairs_tid[current];
+
+ if (EE_th_app[tid + 1] == app) {
+ /* Free the descriptor */
+ EE_rq_pairs_next[current] = EE_rq_free;
+ EE_rq_free = current;
+
+ /* Move the head of ready priority queue */
+ EE_rq_queues_head[x] = next;
+
+ /* Make the clean-up of other data structures related to ready queue */
+ EE_as_task_other_cleanup(tid);
+ } else {
+ /* current != -1 is checked in the cycle below */
+ break;
+ }
+ /* Move the current to next at the end */
+ current = next;
+ }
+
+ /* Remove elements inside priority ready queue, if the queue is still
+ * NOT EMPTY */
+ previous = current;
+ while (current != (EE_TYPEPAIR)-1) {
+ /* Get the next */
+ next = EE_rq_pairs_next[current];
+ /* Hold "current" tid */
+ tid = EE_rq_pairs_tid[current];
+
+ if (EE_th_app[tid + 1] == app) {
+ /* Free the descriptor */
+ EE_rq_pairs_next[current] = EE_rq_free;
+ EE_rq_free = current;
+
+ /* Assign previous-next to next */
+ EE_rq_pairs_next[previous] = next;
+
+ /* Make the clean-up of other data structures related to ready queue */
+ EE_as_task_other_cleanup(tid);
+ } else {
+ /* Otherwise current will be next previous */
+ previous = current;
+ }
+ /* Move the current to next at the end */
+ current = next;
+ }
+
+ /* If the actual priority ready queue is empty, clean it (even though it
+ * could be already clean) */
+ if (EE_rq_queues_head[x] == (EE_TYPEPAIR)-1) {
+ /* Adjust priority ready queue tail */
+ EE_rq_queues_tail[x] = -1;
+ /* Reset the (x)th bit in the bitfield (casts are for MISRA Compliance) */
+ EE_rq_bitmask &= ((EE_TYPE_RQ_MASK) ~((EE_TYPE_RQ_MASK)1U << x));
+ }
+ /* Decrement priority ready queue index until -1 */
+ --x;
+ }
+}
+#endif /* OO Kernels */
+
+void EE_as_TerminateApplication_internal(ApplicationType Application,
+ RestartType RestartOption)
+{
+ /* Pointer to OS-Application to be terminated data structure */
+ register EE_as_Application_RAM_type *const app_RAM_ptr =
+ &EE_as_Application_RAM[Application];
+
+ /* Terminate application TASKs */
+ EE_as_terminate_app_tasks(Application);
+
+#ifdef EE_SERVICE_PROTECTION__
+#if defined(EE_MAX_ALARM) && (EE_MAX_ALARM > 0)
+ {
+ /* Handle alarms cancellation and counters reset */
+ AlarmType alarm;
+ for (alarm = 0; alarm < EE_MAX_ALARM; ++alarm) {
+ EE_oo_alarm_ROM_type const *const pAlarmROM = &EE_alarm_ROM[alarm];
+
+ if (pAlarmROM->ApplID == Application) {
+ CounterType const counter = EE_oo_counter_object_ROM[alarm].c;
+
+ EE_oo_counter_object_RAM_type *const pCounterObjectRAM =
+ &EE_oo_counter_object_RAM[alarm];
+
+ /* RESET COUNTER OBJECT */
+ pCounterObjectRAM->used = 0U;
+ pCounterObjectRAM->cycle = 0U;
+ pCounterObjectRAM->delta = 0U;
+ pCounterObjectRAM->next = INVALID_COUNTER_OBJECT;
+
+ if (EE_counter_ROM[counter].ApplID == Application) {
+ /* RESET THE COUNTER TOO */
+ EE_oo_counter_RAM_type *const pCounterRAM =
+ &EE_counter_RAM[counter];
+
+ pCounterRAM->value = 0U;
+ pCounterRAM->first = INVALID_COUNTER_OBJECT;
+ }
+ }
+ }
+ }
+#endif /* EE_MAX_ALARM > 0 */
+
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ {
+ /* Handle alarms cancellation and counters reset */
+ ScheduleTableType sched_id;
+ for (sched_id = 0; sched_id < EE_MAX_SCHEDULETABLE; ++sched_id) {
+ EE_as_Schedule_Table_ROM_type const *const p_schedule_table_ROM =
+ &EE_as_Schedule_Table_ROM[sched_id];
+
+ if (p_schedule_table_ROM->ApplID == Application) {
+ CounterObjectType const obj_id = EE_MAX_ALARM + sched_id;
+ CounterType const counter = EE_oo_counter_object_ROM[obj_id].c;
+
+ EE_oo_counter_object_RAM_type *const pCounterObjectRAM =
+ &EE_oo_counter_object_RAM[obj_id];
+ EE_as_Schedule_Table_RAM_type *const p_schedule_table_RAM =
+ &EE_as_Schedule_Table_RAM[sched_id];
+
+ /* RESET COUNTER OBJECT */
+ pCounterObjectRAM->used = 0U;
+ pCounterObjectRAM->cycle = 0U;
+ pCounterObjectRAM->delta = 0U;
+ pCounterObjectRAM->next = INVALID_COUNTER_OBJECT;
+
+ /* RESET SCHEDULE TABLE RAM TOO */
+ p_schedule_table_RAM->status = SCHEDULETABLE_STOPPED;
+ p_schedule_table_RAM->position = INVALID_SCHEDULETABLE_POSITION;
+ p_schedule_table_RAM->deviation = 0;
+ p_schedule_table_RAM->next_table = INVALID_SCHEDULETABLE;
+
+ if (EE_counter_ROM[counter].ApplID == Application) {
+ /* RESET THE COUNTER TOO */
+ EE_oo_counter_RAM_type *const pCounterRAM =
+ &EE_counter_RAM[counter];
+
+ pCounterRAM->value = 0U;
+ pCounterRAM->first = INVALID_COUNTER_OBJECT;
+ }
+ }
+ }
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* Set Application in requested Status */
+ if (RestartOption == RESTART) {
+ TaskType restart_task = EE_as_Application_ROM[Application].restart_task;
+ app_RAM_ptr->ApplState = APPLICATION_RESTARTING;
+ if (restart_task != EE_NIL) {
+ /* Decrement the residual number activation */
+ --EE_th_rnact[restart_task];
+ /* Put the task in the ready state */
+ EE_oo_set_th_status_ready(restart_task);
+ /* Insert the restart task in the ready queue */
+ EE_rq_insert(restart_task);
+ }
+ } else {
+ app_RAM_ptr->ApplState = APPLICATION_TERMINATED;
+ }
+}
+
+StatusType EE_as_TerminateApplication(ApplicationType Application,
+ RestartType RestartOption)
+{
+ /* Pointer to OS-Application to be terminated data structure */
+ register EE_as_Application_RAM_type *app_RAM_ptr;
+ /* Calling OS-Application ID */
+ register ApplicationType current_app;
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_TERMINATEAPPLICATION);
+
+ EE_as_monitoring_the_stack();
+
+ /* Calling OS-Application ID */
+ current_app = EE_as_active_app;
+ /* Get the OS-Application to be terminated data structure */
+ app_RAM_ptr = &EE_as_Application_RAM[Application];
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* TerminateApplication is callable by Task, ISR2, ErrorHook
+ * (only self termination) */
+ if ((EE_as_execution_context > ErrorHook_Context) ||
+ ((EE_as_execution_context == ErrorHook_Context) &&
+ (current_app != Application))) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(Application)) {
+ EE_os_param const unmarked_app_id = {
+ EE_AS_UNMARK_REMOTE_ID(Application)
+ };
+ EE_os_param const as_restart_option = {
+ RestartOption
+ };
+
+ /* Forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_TerminateApplication, unmarked_app_id,
+ as_restart_option, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [OS495] If the <Application> in a call of GetApplicationState() is not
+ * valid GetApplicationState() shall return E_OS_ID. */
+ /* [OS493] If the input parameter <Application> in a call of
+ * TerminateApplication() is not valid. TerminateApplication() shall
+ * return E_OS_ID. */
+ /* [OS459] If the <RestartOption> in a call of TerminateApplication() is
+ * invalid, TerminateApplication() shall return E_OS_VALUE. */
+ /* [OS494] If the input parameter <Application> in a call of
+ * TerminateApplication() is valid AND the caller belongs to a
+ * non-trusted OS-Application AND the caller does not belong
+ * to <Application> TerminateApplication() shall return E_OS_ACCESS. */
+ if (Application >= EE_MAX_APP) {
+ ev = E_OS_ID;
+ } else if (Application >= EE_MAX_APP) {
+ ev = E_OS_ID;
+ } else if ((RestartOption != NO_RESTART) && (RestartOption != RESTART)) {
+ ev = E_OS_VALUE;
+ } else if ((current_app != Application) &&
+ (EE_as_Application_ROM[current_app].Mode != EE_MEMPROT_TRUST_MODE)) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ /* [OS507] If the state of <Application> in a call of TerminateApplication()
+ * is APPLICATION_TERMINATED TerminateApplication() shall return E_OS_STATE.
+ */
+ /* [OS508] If the state of <Application> in a call of TerminateApplication()
+ * is APPLICATION_RESTARTING and the caller does not belong to the
+ * <Application> then TerminateApplication() shall return E_OS_STATE. */
+ /* [OS548] If the state of <Application> in a call of TerminateApplication()
+ * is APPLICATION_RESTARTING AND the caller does belong to the <Application>
+ * AND the <RestartOption> is equal RESTART then TerminateApplication()
+ * shall return E_OS_STATE. ( ) */
+ if ((app_RAM_ptr->ApplState == APPLICATION_TERMINATED) ||
+ ((app_RAM_ptr->ApplState == APPLICATION_RESTARTING) &&
+ ((current_app != Application) || (RestartOption == RESTART)))) {
+ ev = E_OS_STATE;
+ } else {
+ /* [OS287] If the parameters in a call of TerminateApplication() are valid
+ * and the above criteria are met TerminateApplication() shall terminate
+ * <Application> (i.e. to kill all tasks, disable the interrupt sources of
+ * those ISRs which belong to the OS-Application and free all other
+ * OS resources associated with the application) AND shall activate
+ * the configured OsRestartTask of <Application> if <RestartOption>
+ * equals RESTART. If the <Application> is restarted, its state is set
+ * to APPLICATION_RESTARTING otherwise to APPLICATION_TERMINATED.
+ * If the caller belongs to <Application> TerminateApplication()shall not
+ * return, otherwise it shall return E_OK. */
+ EE_as_TerminateApplication_internal(Application, RestartOption);
+
+ /* If the caller belong to the OS-Application to be terminated,
+ * terminate it. */
+ if (current_app == Application) {
+ EE_as_terminate_current_app();
+ }
+ ev = E_OK;
+ }
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_application);
+ EE_OS_PARAM(os_restart_option);
+ EE_OS_PARAM_VALUE(os_application, Application);
+ EE_OS_PARAM_VALUE(os_restart_option, RestartOption);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_TerminateApplication, os_application,
+ os_restart_option, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_TERMINATEAPPLICATION);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+StatusType EE_as_AllowAccess(void)
+{
+ /* Current OS-Application the one to be restarted */
+ register ApplicationType current_app;
+ /* Pointer to OS-Application to be restarted data structure */
+ register EE_as_Application_RAM_type *app_RAM_ptr;
+ /* Error Value */
+ register StatusType ev;
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* Current Task */
+ register EE_TID current;
+#endif /* EE_SERVICE_PROTECTION__ */
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_ALLOWACCESS);
+
+ EE_as_monitoring_the_stack();
+
+ /* Current Application */
+ current_app = EE_as_active_app;
+
+ /* Get the OS-Application to be restarted data structure */
+ app_RAM_ptr = &EE_as_Application_RAM[current_app];
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* Current Task */
+ current = EE_stk_queryfirst();
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* AllowAccess is callable only by Restarting Task Task, ISR2, ErrorHook
+ * (only self termination) */
+ if ((EE_as_execution_context > TASK_Context) ||
+ (current != EE_as_Application_ROM[current_app].restart_task)) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [OS497] If the state of the OS-Application of the caller of AllowAccess()
+ * is not APPLICATION_RESTARTING AllowAccess() shall return E_OS_STATE. */
+ if (app_RAM_ptr->ApplState != APPLICATION_RESTARTING) {
+ ev = E_OS_STATE;
+ } else {
+ /* [OS498] If the state of the OS-Application of the caller of AllowAccess()
+ * is APPLICATION_RESTARTING, AllowAccess() shall set the state to
+ * APPLICATION_ACCESSIBLE and allow other OS-Applications to access the
+ * configured objects of the callers OS-Application. */
+ app_RAM_ptr->ApplState = APPLICATION_ACCESSIBLE;
+
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_os_notify_error(OSServiceId_AllowAccess, EE_OS_INVALID_PARAM,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_ALLOWACCESS);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_prot_error.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_prot_error.c
new file mode 100644
index 0000000..6624a65
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_prot_error.c
@@ -0,0 +1,283 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_prot_error.c
+ * @brief Protection Error Handling and calls to ProtectionHook
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#include "ee_internal.h"
+
+#ifdef EE_AS_OSAPPLICATIONS__
+void EE_as_handle_protection_error(ApplicationType error_app,
+ StatusType error)
+{
+ /* Call the ProtectionHook and get the policy */
+ ProtectionReturnType policy;
+ /* ISR Nesting level */
+ EE_UREG current_nesting;
+ /* Stacked TASK ID */
+ EE_TID current_task;
+ /* Handle Protection Hook execution context */
+ EE_TYPECONTEXT prev_context;
+
+ /* Saving the execution context make sense only in case of
+ * E_OS_PROTECTION_ARRIVAL, otherwise there will some kind of Termination
+ * (TASK,ISR2,Application,OS) that will handle that */
+ if (E_OS_PROTECTION_ARRIVAL == error) {
+ prev_context = EE_as_get_execution_context();
+ }
+
+ /* Set the context on ProtectionHook */
+ EE_as_set_execution_context(ProtectionHook_Context);
+ policy = ProtectionHook(error);
+
+ /* [OS506]: If the ProtectionHook() is called with E_OS_PROTECTION_ARRIVAL
+ * the only valid return values are PRO_IGNORE or PRO_SHUTDOWN.
+ * Returning other values will result in a call to ShutdownOS(). */
+ if (E_OS_PROTECTION_ARRIVAL == error) {
+ if (policy == PRO_IGNORE) {
+ /* Restore the previous execution context */
+ EE_as_set_execution_context(prev_context);
+ } else {
+ EE_oo_ShutdownOS_internal(error);
+ }
+ } else {
+#ifdef EE_TIMING_PROTECTION__
+ if (error == E_OS_PROTECTION_LOCKED) {
+ /* Reset ISR counter here to not call ErrorHook too in addition of
+ * ProtectionHook in case of ISR2 Termination (the ErrorHook would be call
+ * by EE_IRQ_end_post_stub()) */
+ EE_oo_IRQ_disable_count = 0U;
+ }
+#endif /* EE_TIMING_PROTECTION__ */
+
+ switch (policy) {
+ case PRO_IGNORE:
+ /* [OS475]: If the ProtectionHook() returns PRO_IGNORE and the
+ * ProtectionHook() was not called with E_OS_PROTECTION_ARRIVAL then the
+ * Operating System module shall call ShutdownOS(). */
+ EE_oo_ShutdownOS_internal(error);
+ break;
+
+ case PRO_TERMINATETASKISR:
+ /* [OS243]: If the reaction is to forcibly terminate the Task/Category 2
+ * OsIsr and no Task or OsIsr can be associated with the error,
+ * the running OS-Application is forcibly terminated by the Operating
+ * System. */
+ current_nesting = EE_hal_get_IRQ_nesting_level();
+ current_task = EE_stk_queryfirst();
+ if (current_nesting > 0U) {
+#if defined(EE_MAX_ISR2) && (EE_MAX_ISR2 > 0)
+ ISRType irq = EE_as_ISR_stack[current_nesting - 1U].ISR_ID;
+ if (EE_as_ISR_ROM[irq].ApplID == error_app) {
+ /* I can terminate the ISR2 because it belong to the application
+ * that generate the error */
+ EE_as_TerminateISR2();
+ } else
+#endif /* EE_MAX_ISR2 > 0 */
+ if ((error_app != INVALID_OSAPPLICATION) &&
+ (error_app != KERNEL_OSAPPLICATION)) {
+ EE_as_TerminateApplication_internal(error_app, NO_RESTART);
+ } else {
+ /* In any other case here I have to shutdown the OS */
+ EE_oo_ShutdownOS_internal(error);
+ }
+ } else if (current_task != EE_NIL) {
+ if (EE_th_app[current_task + 1] == error_app) {
+ /* I can terminate the TASK because it belong to the application
+ * that generate the error */
+ /* [OS108]: If the Operating System module forcibly terminates a
+ * task, it terminates the task, releases all allocated OSEK
+ * resources and calls EnableAllInterrupts() /
+ * ResumeOSInterrupts() / ResumeAllInterrupts() if the Task called
+ * DisableAllInterrupts() / SuspendOSInterrupts() /
+ * SuspendAllInterrupts() before without the corresponding
+ * EnableAllInterrupts() / ResumeOSInterrupts() /
+ * ResumeAllInterrupts() call. */
+ (void)EE_oo_release_all_resources(current_task);
+ (void)EE_as_release_all_spinlocks(current_task);
+#ifndef __OO_NO_CHAINTASK__
+ EE_th_terminate_nextask[current_task] = EE_NIL;
+#endif /* __OO_NO_CHAINTASK__ */
+ EE_hal_terminate_task(current_task);
+ } else if ((error_app != INVALID_OSAPPLICATION) &&
+ (error_app != KERNEL_OSAPPLICATION)) {
+ EE_as_TerminateApplication_internal(error_app, NO_RESTART);
+ } else {
+ /* In any other case here I have to shutdown the OS */
+ EE_oo_ShutdownOS_internal(error);
+ }
+ } else if ((error_app != INVALID_OSAPPLICATION) &&
+ (error_app != KERNEL_OSAPPLICATION)) {
+ EE_as_TerminateApplication_internal(error_app, NO_RESTART);
+ } else {
+ /* In any other case here I have to shutdown the OS */
+ EE_oo_ShutdownOS_internal(error);
+ }
+ break;
+
+ case PRO_TERMINATEAPPL:
+ if (EE_as_active_app == error_app) {
+ EE_as_TerminateApplication_internal(EE_as_active_app, NO_RESTART);
+ EE_as_terminate_current_app();
+ } else if ((error_app != INVALID_OSAPPLICATION) &&
+ (error_app != KERNEL_OSAPPLICATION)) {
+ EE_as_TerminateApplication_internal(error_app, NO_RESTART);
+ } else {
+ /* [OS244] If the ProtectionHook() returns PRO_TERMINATEAPPL or
+ * PRO_TERMINATEAPPL_RESTART and no OS-Application can be assigned,
+ * ShutdownOS() is called. (BSW11014) */
+ EE_oo_ShutdownOS_internal(error);
+ }
+ break;
+
+ case PRO_TERMINATEAPPL_RESTART:
+ if (EE_as_active_app == error_app) {
+ EE_as_TerminateApplication_internal(EE_as_active_app, RESTART);
+ EE_as_terminate_current_app();
+ } else if ((error_app != INVALID_OSAPPLICATION) &&
+ (error_app != KERNEL_OSAPPLICATION)) {
+ EE_as_TerminateApplication_internal(error_app, NO_RESTART);
+ } else {
+ /* [OS244] If the ProtectionHook() returns PRO_TERMINATEAPPL or
+ * PRO_TERMINATEAPPL_RESTART and no OS-Application can be assigned,
+ * ShutdownOS() is called. (BSW11014) */
+ EE_oo_ShutdownOS_internal(error);
+ }
+ break;
+
+ case PRO_SHUTDOWN:
+ EE_oo_ShutdownOS_internal(error);
+ break;
+
+ default:
+ /* ProtectionHook returned a wrong policy: shutdown the OS */
+ EE_oo_ShutdownOS_internal(error);
+ break;
+ }
+ }
+}
+#else /* EE_AS_OSAPPLICATIONS__ */
+void EE_as_handle_protection_error(StatusType error)
+{
+ /* Call the ProtectionHook and get the policy */
+ ProtectionReturnType policy;
+ /* ISR Nesting level */
+ EE_UREG current_nesting;
+ /* Stacked TASK ID */
+ EE_TID current_task;
+ /* Handle Protection Hook execution context */
+ EE_TYPECONTEXT prev_context;
+
+ /* Saving the execution context make sense only in case of
+ * E_OS_PROTECTION_ARRIVAL, otherwise there will some kind of Termination
+ * (TASK,ISR2,Application,OS) that will handle that */
+ if (E_OS_PROTECTION_ARRIVAL == error) {
+ prev_context = EE_as_get_execution_context();
+ }
+
+ /* Set the context on ProtectionHook */
+ EE_as_set_execution_context(ProtectionHook_Context);
+ policy = ProtectionHook(error);
+
+ /* [OS506]: If the ProtectionHook() is called with E_OS_PROTECTION_ARRIVAL
+ * the only valid return values are PRO_IGNORE or PRO_SHUTDOWN.
+ * Returning other values will result in a call to ShutdownOS(). */
+ if (E_OS_PROTECTION_ARRIVAL == error) {
+ if (policy == PRO_IGNORE) {
+ /* Restore the previous execution context */
+ EE_as_set_execution_context(prev_context);
+ } else {
+ EE_oo_ShutdownOS_internal(error);
+ }
+ } else {
+#ifdef EE_TIMING_PROTECTION__
+ if (error == E_OS_PROTECTION_LOCKED) {
+ /* Reset ISR counter here to not call ErrorHook too in addition of
+ * ProtectionHook in case of ISR2 Termination (the ErrorHook would be call
+ * by EE_IRQ_end_post_stub()) */
+ EE_oo_IRQ_disable_count = 0U;
+ }
+#endif /* EE_TIMING_PROTECTION__ */
+
+ switch (policy) {
+ case PRO_TERMINATETASKISR:
+ /* [OS243]: If the reaction is to forcibly terminate the Task/Category 2
+ * OsIsr and no Task or OsIsr can be associated with the error,
+ * the running OS-Application is forcibly terminated by the Operating
+ * System. */
+ current_nesting = EE_hal_get_IRQ_nesting_level();
+ current_task = EE_stk_queryfirst();
+ if (current_nesting == 0U) {
+ /* [OS108]: If the Operating System module forcibly terminates a task,
+ * it terminates the task, releases all allocated OSEK resources and
+ * calls EnableAllInterrupts()/ ResumeOSInterrupts() /
+ * ResumeAllInterrupts() if the Task called DisableAllInterrupts() /
+ * SuspendOSInterrupts() / SuspendAllInterrupts() before without the
+ * corresponding EnableAllInterrupts() / ResumeOSInterrupts() /
+ * ResumeAllInterrupts() call. */
+ (void)EE_oo_release_all_resources(current_task);
+ (void)EE_as_release_all_spinlocks(current_task);
+#ifndef __OO_NO_CHAINTASK__
+ EE_th_terminate_nextask[current_task] = EE_NIL;
+#endif /* __OO_NO_CHAINTASK__ */
+ EE_hal_terminate_task(current_task);
+ } else {
+ EE_oo_ShutdownOS_internal(error);
+ }
+ break;
+
+ /* [OS475]: If the ProtectionHook() returns PRO_IGNORE and the
+ * ProtectionHook() was not called with E_OS_PROTECTION_ARRIVAL then the
+ * Operating System module shall call ShutdownOS(). */
+ case PRO_IGNORE:
+ case PRO_TERMINATEAPPL:
+ case PRO_TERMINATEAPPL_RESTART:
+ case PRO_SHUTDOWN:
+ default:
+ /* ProtectionHook returned a wrong policy: shutdown the OS */
+ EE_oo_ShutdownOS_internal(error);
+ break;
+ }
+ }
+}
+#endif /* EE_AS_OSAPPLICATIONS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_rpc.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_rpc.c
new file mode 100644
index 0000000..3dda8ea
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_rpc.c
@@ -0,0 +1,728 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_rpc.c
+ * @brief Implementation of Synchronous Remote Procedure Call (RPC) to
+ * execute kernel primitives in other cores. This shares some
+ * requirements with RN (Remote Notification) Kernel Extension, but
+ * unlike that, take advantage of the fact that Autosar
+ * Specification explicitly states synchronous behavior.
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#include "ee_internal.h"
+#include "ee_api.h"
+
+#ifdef EE_MASTER_CPU
+
+/** @brief Flag that a core is serving a RPCs */
+EE_BIT volatile EE_SHARED_UDATA EE_as_rpc_serving[EE_MAX_CPU];
+
+/** @brief Flag used to signal that ShutdownAllCores have been called */
+EE_BIT volatile EE_SHARED_UDATA EE_as_shutdown_all_cores_flag;
+
+/** @brief Used to pass ShutdownAllCores error parameter to other cores */
+StatusType volatile EE_SHARED_UDATA EE_as_shutdown_all_cores_error;
+
+/** @brief Mask used in shutdown all cores procedure for synchronization */
+EE_UREG volatile EE_SHARED_IDATA
+ EE_as_shutdown_mask = ((EE_UREG)1U << EE_MAX_CPU) - 1U;
+
+#ifdef __EE_MEMORY_PROTECTION__
+/** @brief array used to crossing memory protection between cores when call a
+ * service with param2 as some kind of reference */
+EE_as_rpc_outparam EE_SHARED_UDATA EE_as_rpc_out_param2[EE_MAX_CPU];
+/** @brief array used to crossing memory protection between cores when call a
+ * service with param3 as some kind of reference */
+EE_as_rpc_outparam EE_SHARED_UDATA EE_as_rpc_out_param3[EE_MAX_CPU];
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#endif /* EE_MASTER_CPU */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+static EE_UREG EE_as_get_service_index_and_limit(
+ OSServiceIdType ServiceId,
+ EE_os_param_id *limit_id_ref)
+{
+ EE_UREG service_index;
+
+ switch (ServiceId) {
+ case OSServiceId_ActivateTask:
+ case OSServiceId_ChainTask:
+ case OSServiceId_GetTaskState:
+ case OSServiceId_SetEvent:
+ service_index = 0U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = (EE_os_param_id)EE_AS_RPC_TASKS_SIZE;
+ }
+ break;
+#ifndef __OO_NO_ALARMS__
+ case OSServiceId_GetAlarmBase:
+ case OSServiceId_GetAlarm:
+ case OSServiceId_SetRelAlarm:
+ case OSServiceId_SetAbsAlarm:
+ case OSServiceId_CancelAlarm:
+ service_index = 1U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = EE_AS_RPC_ALARMS_SIZE;
+ }
+ break;
+ case OSServiceId_GetCounterValue:
+ case OSServiceId_GetElapsedValue:
+ service_index = 2U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = EE_AS_RPC_COUNTERS_SIZE;
+ }
+ break;
+#endif /* !__OO_NO_ALARMS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ case OSServiceId_StartScheduleTableRel:
+ case OSServiceId_StartScheduleTableAbs:
+ case OSServiceId_StopScheduleTable:
+ case OSServiceId_GetScheduleTableStatus:
+ service_index = 3U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = EE_AS_RPC_SCHEDTABS_SIZE;
+ }
+ break;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ case OSServiceId_GetApplicationState:
+ case OSServiceId_TerminateApplication:
+ service_index = 4U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = EE_AS_RPC_OSAPPLS_SIZE;
+ }
+ break;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#ifdef EE_AS_IOC__
+ /* Inter OSApplication Communication (IOC) */
+ case OSServiceId_IOCService:
+ service_index = 5U;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = ((EE_os_param_id)-1); /* TODO EG: Check This better !!! */
+ }
+ break;
+#endif /* EE_AS_IOC__ */
+ default:
+ /* Wrong Service ID return a Error Value */
+ service_index = EE_UREG_MINUS1;
+ if (limit_id_ref != NULL) {
+ *limit_id_ref = 0U;
+ }
+ break;
+ }
+
+ return service_index;
+}
+
+#ifdef __EE_MEMORY_PROTECTION__
+
+static void EE_as_rpc_conf_call_params(EE_TYPEASRPC volatile *rpc_ref,
+ OSServiceIdType ServiceId,
+ EE_os_param_id param1_id,
+ EE_os_param param2,
+ EE_os_param param3)
+{
+ rpc_ref->remote_procedure = ServiceId;
+ rpc_ref->param1.value_param = param1_id;
+
+ switch (ServiceId) {
+ case OSServiceId_GetTaskState:
+ rpc_ref->param2.task_state_ref = &EE_as_rpc_out_param2[EE_CURRENTCPU].
+ task_state;
+ rpc_ref->param3 = param3;
+ break;
+#ifndef __OO_NO_ALARMS__
+ case OSServiceId_GetAlarmBase:
+ rpc_ref->param2.alarm_base_ref = &EE_as_rpc_out_param2[EE_CURRENTCPU].
+ alarm_base;
+ rpc_ref->param3 = param3;
+ break;
+ case OSServiceId_GetAlarm:
+ rpc_ref->param2.tick_ref = &EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ rpc_ref->param3 = param3;
+ break;
+ case OSServiceId_GetCounterValue:
+ rpc_ref->param2.tick_ref = &EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ rpc_ref->param3 = param3;
+ break;
+ case OSServiceId_GetElapsedValue:
+ rpc_ref->param2.tick_ref = &EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ rpc_ref->param3.tick_ref = &EE_as_rpc_out_param3[EE_CURRENTCPU].tick;
+ break;
+#endif /* !__OO_NO_ALARMS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ case OSServiceId_GetScheduleTableStatus:
+ rpc_ref->param2.schedule_table_status_ref =
+ &EE_as_rpc_out_param2[EE_CURRENTCPU].schedule_table_status;
+ rpc_ref->param3 = param3;
+ break;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ case OSServiceId_GetApplicationState:
+ rpc_ref->param2.application_state_ref =
+ &EE_as_rpc_out_param2[EE_CURRENTCPU].application_state;
+ rpc_ref->param3 = param3;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+ break;
+ default:
+ rpc_ref->param2 = param2;
+ rpc_ref->param3 = param3;
+ break;
+ }
+}
+
+static void EE_as_rpc_get_inout_params(OSServiceIdType ServiceId,
+ EE_os_param *param2_ref,
+ EE_os_param *param3_ref)
+{
+ switch (ServiceId) {
+ case OSServiceId_GetTaskState:
+ *(param2_ref->task_state_ref) = EE_as_rpc_out_param2[EE_CURRENTCPU].
+ task_state;
+ break;
+#ifndef __OO_NO_ALARMS__
+ case OSServiceId_GetAlarmBase:
+ *(param2_ref->alarm_base_ref) = EE_as_rpc_out_param2[EE_CURRENTCPU].
+ alarm_base;
+ break;
+ case OSServiceId_GetAlarm:
+ *(param2_ref->tick_ref) = EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ break;
+ case OSServiceId_GetCounterValue:
+ *(param2_ref->tick_ref) = EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ break;
+ case OSServiceId_GetElapsedValue:
+ *(param2_ref->tick_ref) = EE_as_rpc_out_param2[EE_CURRENTCPU].tick;
+ *(param3_ref->tick_ref) = EE_as_rpc_out_param3[EE_CURRENTCPU].tick;
+ break;
+#endif /* !__OO_NO_ALARMS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ case OSServiceId_GetScheduleTableStatus:
+ *(param2_ref->schedule_table_status_ref) =
+ EE_as_rpc_out_param2[EE_CURRENTCPU].schedule_table_status;
+ break;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ case OSServiceId_GetApplicationState:
+ *(param2_ref->application_state_ref) =
+ EE_as_rpc_out_param2[EE_CURRENTCPU].application_state;
+ break;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+ default:
+ break;
+ }
+}
+
+#else /* __EE_MEMORY_PROTECTION__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_as_rpc_conf_call_params(
+ EE_TYPEASRPC volatile *rpc_ref,
+ OSServiceIdType ServiceId,
+ EE_os_param_id param1_id,
+ EE_os_param param2,
+ EE_os_param param3)
+{
+ if (rpc_ref != NULL) {
+ rpc_ref->remote_procedure = ServiceId;
+ rpc_ref->param1.value_param = param1_id;
+ rpc_ref->param2 = param2;
+ rpc_ref->param3 = param3;
+ }
+}
+/* Nothing to do in case of no memory protection */
+#define EE_as_rpc_get_inout_params(ServiceId, param2_ref, param3_ref) ((void)0)
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+/* Called Inside a Primitive: no need to handle Interrupts */
+StatusType EE_as_rpc(OSServiceIdType ServiceId,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3)
+{
+ /* Uninitialized locals */
+ register EE_TYPEASRPC volatile *rpc_ref;
+ register EE_TYPEASREMOTEIDCONSTREF r_id_ref;
+ register StatusType ret_value;
+ register CoreIdType rp_cpu;
+ EE_os_param_id limit_id = INVALID_OBJECTID;
+ /* Initialized locals */
+ register EE_UREG const service_index =
+ EE_as_get_service_index_and_limit(ServiceId, &limit_id);
+
+ /* [OS589]: All functions that are not allowed to operate cross core shall
+ * return E_OS_CORE in extended status if called with parameters that require
+ * a cross core operation. (BSW4080013) */
+ if ((service_index == EE_UREG_MINUS1) ||
+ (EE_as_rpc_services_table[service_index] == NULL)) {
+ /* This condition correspond to a kernel bug: check the configuration */
+ ret_value = E_OS_CORE;
+ } else if (param1.value_param > limit_id) {
+ /* Check if object id of the service is valid */
+ /* This condition correspond to an error in service caller site */
+ ret_value = E_OS_ID;
+ } else {
+ /* Get the Remote Id Structure */
+ r_id_ref = &EE_as_rpc_services_table[service_index][param1.value_param];
+ rp_cpu = r_id_ref->core_id;
+
+ /* Check if the requiring core is different from actual core */
+ if (rp_cpu == EE_CURRENTCPU) {
+ /* This condition correspond to an error in service caller site */
+ ret_value = E_OS_ID;
+ } else
+#ifdef EE_SERVICE_PROTECTION__
+ /* Check for service access right */
+ if ((r_id_ref->core0_index != EE_UREG_MINUS1) &&
+ ((EE_as_rpc_remote_access_rules[r_id_ref->core0_index + EE_CURRENTCPU] &
+ EE_APP_TO_MASK(EE_as_active_app)) == 0)) {
+ ret_value = E_OS_ACCESS;
+ } else
+#ifdef EE_AS_OSAPPLICATIONS__
+ if ((ServiceId == OSServiceId_TerminateApplication) &&
+ (EE_as_Application_ROM[EE_as_active_app].Mode == EE_MEMPROT_USR_MODE)) {
+ ret_value = E_OS_ACCESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#endif /* EE_SERVICE_PROTECTION__ */
+ {
+ /* Select the Right RPC RAM Structure to be populated */
+ rpc_ref = &EE_as_rpc_RAM[EE_CURRENTCPU];
+
+ /* Configure RPC parameters */
+ EE_as_rpc_conf_call_params(rpc_ref, ServiceId, r_id_ref->param_id, param2,
+ param3);
+
+ {
+ /* Initialized locals */
+ /* Select the Right Spinlock Where Synchronize on */
+ register EE_TYPESPIN spinlock_id = EE_as_core_spinlocks[rp_cpu];
+
+ /* Enter RPC Critical Section */
+ EE_hal_spin_in(spinlock_id);
+ /* Configure an Active RPC and, if needed, signal it */
+ rpc_ref->serving_core = rp_cpu;
+ if (EE_as_rpc_serving[rp_cpu] == 0U) {
+ /* In any case we shall assure that EE_hal_IRQ_interprocessor can
+ * handle multiple sequential calls */
+ EE_hal_IRQ_interprocessor((EE_UINT8)rp_cpu);
+ }
+ /* Exit RPC Critical Section */
+ EE_hal_spin_out(spinlock_id);
+ }
+
+ while (rpc_ref->serving_core == rp_cpu) {
+ ; /* Wait that remote call Terminate */
+ }
+
+ /* Move in-out parameters in Call domain in case of memory protection */
+ EE_as_rpc_get_inout_params(ServiceId, ¶m2, ¶m3);
+ ret_value = rpc_ref->error;
+ }
+ }
+ return ret_value;
+}
+
+#ifndef __OO_NO_ALARMS__
+static StatusType EE_as_rpc_execute(OSServiceIdType ServiceId,
+ EE_os_param
+ param1,
+ EE_os_param param2,
+ EE_os_param param3)
+#else
+static StatusType EE_as_rpc_execute(OSServiceIdType ServiceId,
+ EE_os_param
+ param1,
+ EE_os_param param2)
+#endif /* __OO_NO_ALARMS__ */
+{
+ register StatusType ret_value;
+
+#ifdef __OO_HAS_ERRORHOOK__
+ /* The ErrorHook have to be called in requiring core so I set error flag to
+ * prevent the call inside the handling core */
+ EE_ErrorHook_nested_flag = 1U;
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+ switch (ServiceId) {
+ case OSServiceId_ActivateTask:
+ case OSServiceId_ChainTask:
+ ret_value = EE_oo_ActivateTask((TaskType)param1.value_param);
+ break;
+ case OSServiceId_GetTaskState:
+ ret_value = EE_oo_GetTaskState((TaskType)param1.value_param, param2.task_state_ref);
+ break;
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ case OSServiceId_SetEvent:
+ ret_value = EE_oo_SetEvent((TaskType)param1.value_param, (EventMaskType)param2.
+ value_param);
+ break;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+#ifndef __OO_NO_ALARMS__
+ case OSServiceId_GetAlarmBase:
+ ret_value = EE_oo_GetAlarmBase((AlarmType)param1.value_param,
+ param2.alarm_base_ref);
+ break;
+ case OSServiceId_GetAlarm:
+ ret_value = EE_oo_GetAlarm((AlarmType)param1.value_param,
+ param2.tick_ref);
+ break;
+ case OSServiceId_SetRelAlarm:
+ ret_value = EE_oo_SetRelAlarm((AlarmType)param1.value_param,
+ (TickType)param2.value_param, (TickType)param3.value_param);
+ break;
+ case OSServiceId_SetAbsAlarm:
+ ret_value = EE_oo_SetAbsAlarm((AlarmType)param1.value_param,
+ (TickType)param2.value_param, (TickType)param3.value_param);
+ break;
+ case OSServiceId_CancelAlarm:
+ ret_value = EE_oo_CancelAlarm((AlarmType)param1.value_param);
+ break;
+ case OSServiceId_GetCounterValue:
+ ret_value = EE_oo_GetCounterValue((CounterType)param1.value_param,
+ param2.tick_ref);
+ break;
+ case OSServiceId_GetElapsedValue:
+ ret_value = EE_oo_GetElapsedValue((CounterType)param1.value_param,
+ param2.tick_ref, param3.tick_ref);
+ break;
+#endif /* __OO_NO_ALARMS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ case OSServiceId_StartScheduleTableRel:
+ ret_value = EE_as_StartScheduleTableRel((ScheduleTableType)param1.
+ value_param, (TickType)param2.value_param);
+ break;
+ case OSServiceId_StartScheduleTableAbs:
+ ret_value = EE_as_StartScheduleTableAbs((ScheduleTableType)param1.
+ value_param, (TickType)param2.value_param);
+ break;
+ case OSServiceId_StopScheduleTable:
+ ret_value = EE_as_StopScheduleTable((ScheduleTableType)param1.
+ value_param);
+ break;
+ case OSServiceId_GetScheduleTableStatus:
+ ret_value = EE_as_GetScheduleTableStatus((ScheduleTableType)param1.
+ value_param, param2.schedule_table_status_ref);
+ break;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ case OSServiceId_GetApplicationState:
+ ret_value = EE_as_GetApplicationState((ApplicationType)param1.value_param,
+ param2.application_state_ref);
+ break;
+ case OSServiceId_TerminateApplication:
+ ret_value = EE_as_TerminateApplication((ApplicationType)param1.
+ value_param, (RestartType)param2.value_param);
+ break;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+ default:
+ /* Wrong Service ID: this should never happens at this point */
+ ret_value = E_OS_CORE;
+ break;
+ }
+
+#ifdef __OO_HAS_ERRORHOOK__
+ /* Restore initial condition: reset ErrorHook flag */
+ EE_ErrorHook_nested_flag = 0U;
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+ /* return error status */
+ return ret_value;
+}
+
+#define EE_AS_RPC_INCREMENT_AND_HANDLE_WRAPAROUND(v) \
+ ((v) = ((v) == (EE_UREG)(EE_MAX_CPU - 1)) ? 0U : ((v) + 1U))
+
+void EE_as_rpc_handler(void)
+{
+ /* Uninitialized locals */
+ register EE_UREG prev_requiring_core_index;
+ /* Constants */
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+ register EE_TYPESPIN const spinlock_id = EE_as_core_spinlocks[EE_CURRENTCPU];
+ /* Initialized locals */
+ register EE_TYPEASRPC volatile *rpc_ref = 0U;
+ register EE_UREG requiring_core_index =
+ (EE_UREG)EE_CURRENTCPU;
+
+ register EE_BIT to_shutdown = 0U;
+
+#if defined(EE_AS_IOC__) && defined(EE_AS_IOC_HAS_CALLBACKS__)
+ register EE_BIT to_IOC = 0U;
+#endif /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+
+ /* Enter RPC critical section */
+ EE_hal_spin_in(spinlock_id);
+
+ /* If the ShutdownAllCores have not been called search the RPC to be served */
+ if (EE_as_shutdown_all_cores_flag != 0U) {
+ /* Start shutdown procedure */
+ to_shutdown = 1U;
+ }
+#if defined(EE_AS_IOC__) && defined(EE_AS_IOC_HAS_CALLBACKS__)
+ else if (EE_as_rpc_IOC[EE_CURRENTCPU] != 0U) {
+ /* Start IOC procedure */
+ to_IOC = 1U;
+ /* Reset IOC Flag */
+ EE_as_rpc_IOC[EE_CURRENTCPU] = 0U;
+ }
+#endif /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+ else {
+ /* Declare to other CPUs that this core started serving RPCs */
+ EE_as_rpc_serving[EE_CURRENTCPU] = 1U;
+
+ /* Search the requiring core */
+ for (requiring_core_index = 0U; requiring_core_index < (EE_UREG)EE_MAX_CPU;
+ ++requiring_core_index) {
+ /*
+ * Perform the following operation only for
+ * index values other then current cpu id.
+ */
+ if (requiring_core_index != (EE_UREG)EE_CURRENTCPU) {
+ /* Select the RPC Structure */
+ rpc_ref = &EE_as_rpc_RAM[requiring_core_index];
+
+ if (rpc_ref->serving_core == EE_CURRENTCPU) {
+ break;
+ }
+ }
+ }
+ }
+
+ /* Exit RPC critical section */
+ EE_hal_spin_out(spinlock_id);
+
+ do {
+ /* If ShutdownAllCores have been called just shut this core down */
+ if (to_shutdown != 0U) {
+ EE_oo_ShutdownOS_internal(EE_as_shutdown_all_cores_error);
+ }
+#if defined(EE_AS_IOC__) && defined(EE_AS_IOC_HAS_CALLBACKS__)
+ else if (to_IOC != 0U) {
+ EE_as_IOC_callback_sequence();
+ }
+#endif /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+ else {
+ if (rpc_ref != NULL) {
+ /* Otherwise call the service */
+#ifndef __OO_NO_ALARMS__
+ rpc_ref->error = EE_as_rpc_execute(rpc_ref->remote_procedure,
+ rpc_ref->param1, rpc_ref->param2, rpc_ref->param3);
+#else
+ rpc_ref->error = EE_as_rpc_execute(rpc_ref->remote_procedure,
+ rpc_ref->param1, rpc_ref->param2);
+#endif /* __OO_NO_ALARMS__ */
+ }
+ }
+
+ /* Enter RPC critical section */
+ EE_hal_spin_in(spinlock_id);
+
+#if defined(EE_AS_IOC__) && defined(EE_AS_IOC_HAS_CALLBACKS__)
+ /* If the just served service is OSServiceId_IOCService skip reset:
+ * this call type is not synchronous so it could incorrectly free
+ * core for following remote calls */
+ if (to_IOC == 0U) {
+ if (rpc_ref != NULL) {
+ /* Reset actual RPC */
+ rpc_ref->serving_core = INVALID_CORE_ID;
+ }
+ } else {
+ /* Reset IOC flag */
+ to_IOC = 0U;
+ }
+#else /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+
+ if (rpc_ref != NULL) {
+ /* Reset actual RPC */
+ rpc_ref->serving_core = INVALID_CORE_ID;
+ }
+#endif /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+
+ /* If the ShutdownAllCores have been called: Start shutdown procedure */
+ if (EE_as_shutdown_all_cores_flag != 0U) {
+ to_shutdown = 1U;
+ }
+#if defined(EE_AS_IOC__) && defined(EE_AS_IOC_HAS_CALLBACKS__)
+ else if (EE_as_rpc_IOC[EE_CURRENTCPU] != 0U) {
+ /* Start IOC procedure */
+ to_IOC = 1U;
+ /* Reset IOC Flag */
+ EE_as_rpc_IOC[EE_CURRENTCPU] = 0U;
+ }
+#endif /* EE_AS_IOC__ && EE_AS_IOC_HAS_CALLBACKS__ */
+ else {
+ /* Save previous core index value to check request list empty condition
+ * and (post)increment requiring_core_index. On start-up and increment
+ * handle wrap around. This has been made to avoid starvation on cores
+ * that could happen if all the time I restart from index 0 */
+ prev_requiring_core_index = requiring_core_index;
+ EE_AS_RPC_INCREMENT_AND_HANDLE_WRAPAROUND(requiring_core_index);
+ while (requiring_core_index != prev_requiring_core_index) {
+ if (requiring_core_index != (EE_UREG)EE_CURRENTCPU) {
+ /* Select the RPC Structure */
+ rpc_ref = &EE_as_rpc_RAM[requiring_core_index];
+
+ if (rpc_ref->serving_core == EE_CURRENTCPU) {
+ break;
+ }
+ }
+
+ EE_AS_RPC_INCREMENT_AND_HANDLE_WRAPAROUND(requiring_core_index);
+ }
+
+ /* If no other RPC requiring cores have been found reset serving flag */
+ if (requiring_core_index == prev_requiring_core_index) {
+ EE_as_rpc_serving[EE_CURRENTCPU] = 0U;
+ /* Acknowledge current IIRQ */
+ EE_hal_IRQ_interprocessor_served((EE_UINT8)EE_CURRENTCPU);
+ }
+ }
+
+ /* Exit RPC critical section */
+ EE_hal_spin_out(spinlock_id);
+ } while (EE_as_rpc_serving[EE_CURRENTCPU] != 0U);
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#ifndef __PRIVATE_SHUTDOWNOS__
+void EE_as_ShutdownAllCores(StatusType Error)
+{
+ register EE_SREG i;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SHUTDOWNALLCORES);
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* ShutdownAllCores is callable by Task and ISR2, ErrorHook and StartupHook */
+ if (EE_oo_check_disableint_error()) {
+ ; /* Nothing to do, just get that this an Error */
+ } else if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != StartupHook_Context)) {
+ ; /* Nothing to do, just get that this an Error */
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* [OS716]: If ShutdownAllCores is called from non trusted code the call
+ * shall be ignored. (BSW4080007) */
+ if (EE_as_Application_ROM[EE_as_active_app].Mode != EE_MEMPROT_TRUST_MODE) {
+ ; /* Nothing to do, just get that this an Error */
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ */
+ {
+ /* Acquire all cores spinlocks to signal that shutdown procedure is started.
+ * Spinlock are assigned to various core ain reverse order, but it's
+ * just a convention so I can acquire them in direct order */
+ for (i = 0; i < EE_MAX_CPU; ++i) {
+ EE_hal_spin_in(EE_as_core_spinlocks[i]);
+ }
+
+ /* If the procedure have been already started (by another core), just shut
+ * this core down, after have released all spinlocks */
+ if (EE_as_shutdown_all_cores_flag != 0U) {
+ /* Release all cores spinlocks */
+ for (i = 0; i < EE_MAX_CPU; ++i) {
+ EE_hal_spin_out(EE_as_core_spinlocks[i]);
+ }
+ /* This won't never return */
+ EE_oo_ShutdownOS_internal(EE_as_shutdown_all_cores_error);
+ }
+
+ /* Save the Error parameter to be used in all other cores */
+ EE_as_shutdown_all_cores_error = Error;
+
+ /* set ShutdownAllCores global flag */
+ EE_as_shutdown_all_cores_flag = 1U;
+
+ /* Eventually signal cores with an IIRQ */
+ for (i = 0; i < EE_MAX_CPU; ++i) {
+ /* Perform the following operation only for
+ * index values other then current cpu id. */
+ if (i != EE_CURRENTCPU) {
+ if (EE_as_rpc_serving[i] == 0U) {
+ /* In any case we shall assure that EE_hal_IRQ_interprocessor can
+ * handle multiple sequential calls */
+ EE_hal_IRQ_interprocessor((EE_UINT8)i);
+ }
+ }
+ }
+
+ /* Release all cores spinlocks */
+ for (i = 0; i < EE_MAX_CPU; ++i) {
+ EE_hal_spin_out(EE_as_core_spinlocks[i]);
+ }
+ /* After signaling the shutdown all cores status: shut this core down:
+ * This won't never return */
+ EE_oo_ShutdownOS_internal(Error);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SHUTDOWNALLCORES);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+ return;
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* !__PRIVATE_SHUTDOWNOS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_schedule_tables.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_schedule_tables.c
new file mode 100644
index 0000000..43b2879
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_schedule_tables.c
@@ -0,0 +1,990 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_schedule_tables.h
+ * @brief AUTOSAR Schedule Table Types and Functions definitions
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#include "ee_internal.h"
+
+/* 8.4.8 StartScheduleTableRel [OS347]
+ *
+ * This service starts the processing of a schedule table at "Offset" relative
+ * to the "Now" value on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * param ScheduleTableID Schedule table to be started.
+ *
+ * param Offset Number of ticks on the counter before the the schedule table
+ * processing is started
+ *
+ * return StatusType -
+ * E_OK: No Error
+ * E_OS_ID: (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE: (only in EXTENDED status): Offset is greater than
+ * (OsCounterMaxAllowedValue - InitialOffset) or is equal to 0.
+ * E_OS_STATE: Schedule table was already started.
+ */
+StatusType EE_as_StartScheduleTableRel(ScheduleTableType ScheduleTableID,
+ TickType Offset)
+{
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ /* Counter Object ID that represent ScheduleTableID */
+ register const CounterObjectType obj_id = EE_MAX_ALARM + ScheduleTableID;
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+ /* Return error value */
+ register StatusType ev;
+ /* Primitive kernel locking */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STARTSCHEDULETABLEREL);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* StartScheduleTableRel is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(ScheduleTableID)) {
+ EE_os_param const
+ unmarked_sched_table_id = {
+ EE_AS_UNMARK_REMOTE_ID(ScheduleTableID)
+ },
+ as_offset = {
+ Offset
+ };
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_StartScheduleTableRel, unmarked_sched_table_id,
+ as_offset, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local schedule tables are not defined cut everything else */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ /* [OS275] If the schedule table <ScheduleTableID> in a call of
+ * StartScheduleTableRel() is not valid, StartScheduleTableRel()
+ * shall return E_OS_ID. */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else if (EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [OS452] If the schedule table <ScheduleTableID> in a call of
+ * StartScheduleTableRel() is implicitly synchronized
+ * (OsScheduleTblSyncStrategy = IMPLICIT), StartScheduleTableRel()
+ * shall return E_OS_ID. */
+ /* [OS332] If <Offset> in a call of StartScheduleTableRel() is zero
+ * StartScheduleTableRel() shall return E_OS_VALUE. */
+ /* [OS276] If the offset <Offset>) is greater than OsCounterMaxAllowedValue
+ * of the underlying counter minus the Initial Offset, StartScheduleTableRel()
+ * shall return E_OS_VALUE. */
+ /* [OS277] If the schedule table <ScheduleTableID> in a call of
+ * StartScheduleTableRel() is not in the state SCHEDULETABLE_STOPPED,
+ * StartScheduleTableRel() shall return E_OS_STATE. */
+ if (EE_as_Schedule_Table_ROM[ScheduleTableID].sync_strategy ==
+ EE_SCHEDTABLE_SYNC_IMPLICIT) {
+ ev = E_OS_ID;
+ } else if ((Offset == 0) || (Offset >
+ EE_counter_ROM[EE_oo_counter_object_ROM[obj_id].c].maxallowedvalue)) {
+ ev = E_OS_VALUE;
+ } else if (EE_as_Schedule_Table_RAM[ScheduleTableID].status !=
+ SCHEDULETABLE_STOPPED) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* [OS278] If the input parameters of StartScheduleTableRel()
+ * are valid and the state of schedule table <ScheduleTableID> is
+ * SCHEDULETABLE_STOPPED, then StartScheduleTableRel() shall start the
+ * processing of a schedule table <ScheduleTableID>.
+ * The Initial Expiry Point shall be processed after
+ * <Offset> + Initial Offset ticks have elapsed on the underlying counter.
+ * The state of <ScheduleTableID> is set to SCHEDULETABLE_RUNNING before
+ * the service returns to the caller. */
+ EE_as_Schedule_Table_RAM[ScheduleTableID].status = SCHEDULETABLE_RUNNING;
+ EE_as_Schedule_Table_RAM[ScheduleTableID].position =
+ EE_as_Schedule_Table_ROM[ScheduleTableID].expiry_point_first;
+ EE_as_Schedule_Table_RAM[ScheduleTableID].deviation = 0U;
+ EE_as_Schedule_Table_RAM[ScheduleTableID].next_table =
+ INVALID_SCHEDULETABLE;
+
+ /* Insert the alarm corresponding to this Schedule Table in alarm list */
+ EE_oo_handle_rel_counter_object_insertion(obj_id, Offset +
+ EE_as_Expiry_Point_ROM[EE_as_Schedule_Table_ROM[ScheduleTableID].
+ expiry_point_first].offset, 0U);
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_SCHEDULETABLE > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0U */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_sched_table_id);
+ EE_OS_PARAM(os_offset);
+ EE_OS_PARAM_VALUE(os_sched_table_id, ScheduleTableID);
+ EE_OS_PARAM_VALUE(os_offset, Offset);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_StartScheduleTableRel, os_sched_table_id,
+ os_offset, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTSCHEDULETABLEREL);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+/* 8.4.9 StartScheduleTableAbs [SWS_Os_00358]
+ *
+ * This service starts the processing of a schedule table at an absolute
+ * value "Start" on the underlying counter.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * param ScheduleTableID: Schedule table to be started
+ * param Start: Absolute counter tick value at which the schedule table is
+ * started
+ *
+ * return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_VALUE (only in EXTENDED status): "Start" is greater than
+ * OsCounterMaxAllowedValue
+ * E_OS_STATE: Schedule table was already started Description:
+ */
+StatusType EE_as_StartScheduleTableAbs(ScheduleTableType ScheduleTableID,
+ TickType Start)
+{
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ /* Counter Object ID that represent ScheduleTableID */
+ register const CounterObjectType obj_id = EE_MAX_ALARM + ScheduleTableID;
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+ /* Return error value */
+ register StatusType ev;
+ /* Primitive kernel locking */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STARTSCHEDTABABS);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* StartScheduleTableAbs is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(ScheduleTableID)) {
+ EE_os_param const
+ unmarked_sched_table_id = {
+ EE_AS_UNMARK_REMOTE_ID(ScheduleTableID)
+ },
+ as_start = {
+ Start
+ };
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_StartScheduleTableAbs, unmarked_sched_table_id,
+ as_start, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local schedule tables are not defined cut everything else */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+ /* [SWS_Os_00348] If the schedule table <ScheduleTableID> in a call of
+ * StartScheduleTableAbs() is not valid, StartScheduleTableAbs()
+ * shall return E_OS_ID. */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else if (EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [SWS_Os_00349] If the <Start> in a call of StartScheduleTableAbs()
+ * is greater than the OsCounterMaxAllowedValue of the underlying counter,
+ * StartScheduleTableAbs() shall return E_OS_VALUE. */
+ /* [SWS_Os_00350] If the schedule table <ScheduleTableID> in a call of
+ * StartScheduleTableAbs() is not in the state SCHEDULETABLE_STOPPED,
+ * StartScheduleTableAbs() shall return E_OS_STATE. */
+ if (Start > EE_counter_ROM[EE_oo_counter_object_ROM[obj_id].c].
+ maxallowedvalue) {
+ ev = E_OS_VALUE;
+ } else if (EE_as_Schedule_Table_RAM[ScheduleTableID].
+ status != SCHEDULETABLE_STOPPED) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* [SWS_Os_00351] If the input parameters of StartScheduleTableAbs() are
+ * valid and <ScheduleTableID> is in the state SCHEDULETABLE_STOPPED,
+ * StartScheduleTableAbs() shall start the processing of schedule table
+ * <ScheduleTableID> when the underlying counter next equals <Start> and
+ * shall set the state of <ScheduleTableID> to
+ * - SCHEDULETABLE_RUNNING (for a non-synchronized / Explicitly
+ * synchronized schedule table) OR
+ * - SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS (for implicitly synchronized
+ * schedule table)
+ * before returning to the user. (The Initial Expiry Point will be
+ * processed when the underlying counter next equals
+ * <Start>+Initial Offset). */
+ EE_as_Schedule_Table_RAM[ScheduleTableID].status =
+ (EE_as_Schedule_Table_ROM[ScheduleTableID].
+ sync_strategy == EE_SCHEDTABLE_SYNC_IMPLICIT) ?
+ SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS : SCHEDULETABLE_RUNNING;
+
+ EE_as_Schedule_Table_RAM[ScheduleTableID].position =
+ EE_as_Schedule_Table_ROM[ScheduleTableID].expiry_point_first;
+ EE_as_Schedule_Table_RAM[ScheduleTableID].deviation = 0U;
+ EE_as_Schedule_Table_RAM[ScheduleTableID].next_table =
+ INVALID_SCHEDULETABLE;
+
+ /* Insert the alarm corresponding to this Schedule Table in alarm list */
+ EE_oo_handle_abs_counter_object_insertion(obj_id, Start +
+ EE_as_Expiry_Point_ROM[EE_as_Schedule_Table_ROM[ScheduleTableID].
+ expiry_point_first].offset, 0U);
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_SCHEDULETABLE > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0U */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_sched_table_id);
+ EE_OS_PARAM(os_start);
+ EE_OS_PARAM_VALUE(os_sched_table_id, ScheduleTableID);
+ EE_OS_PARAM_VALUE(os_start, Start);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_StartScheduleTableAbs, os_sched_table_id,
+ os_start, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTSCHEDTABABS);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+/* 8.4.10 StopScheduleTable [SWS_Os_00006]
+ *
+ * This service cancels the processing of a schedule table immediately at any
+ * point while the schedule table is running.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * param ScheduleTableID: Schedule table to be stopped
+ *
+ * return StatusType
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID not valid.
+ * E_OS_NOFUNC: Schedule table was already stopped.
+ */
+StatusType EE_as_StopScheduleTable(ScheduleTableType ScheduleTableID)
+{
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+ /* Counter Object ID that represent ScheduleTableID */
+ register const CounterObjectType obj_id = EE_MAX_ALARM + ScheduleTableID;
+ /* To Stop Eventual Next Table */
+ register ScheduleTableType next_table;
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+ /* Return error value */
+ register StatusType ev;
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STOPSCHEDULETABLE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* StopScheduleTable is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(ScheduleTableID)) {
+ EE_os_param const
+ unmarked_sched_table_id = {
+ EE_AS_UNMARK_REMOTE_ID(ScheduleTableID)
+ };
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_StopScheduleTable, unmarked_sched_table_id,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local schedule tables are not defined cut everything else */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+ /* [SWS_Os_00279] If the schedule table identifier <ScheduleTableID> in a
+ * call of StopScheduleTable() is not valid, StopScheduleTable()
+ * shall return E_OS_ID. */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else if (EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [SWS_Os_00280] If the schedule table with identifier <ScheduleTableID> is
+ * in state SCHEDULETABLE_STOPPED when calling StopScheduleTable(),
+ * StopScheduleTable() shall return E_OS_NOFUNC. */
+ if (EE_as_Schedule_Table_RAM[ScheduleTableID].
+ status == SCHEDULETABLE_STOPPED) {
+ ev = E_OS_NOFUNC;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* [SWS_Os_00281] If the input parameters of StopScheduleTable() are valid,
+ * StopScheduleTable()shall set the state of <ScheduleTableID> to
+ * SCHEDULETABLE_STOPPED and (stop the schedule table <ScheduleTableID> from
+ * processing any further expiry points and) shall return E_OK. */
+ next_table = EE_as_Schedule_Table_RAM[ScheduleTableID].next_table;
+ if (next_table != INVALID_SCHEDULETABLE) {
+ /* Stop the next_table */
+ EE_as_Schedule_Table_RAM[next_table].status = SCHEDULETABLE_STOPPED;
+ }
+
+ EE_as_Schedule_Table_RAM[ScheduleTableID].status = SCHEDULETABLE_STOPPED;
+
+ /* Cancel the alarm related with the schedule table */
+ EE_oo_handle_counter_object_cancellation(obj_id);
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_SCHEDULETABLE > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0U */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_sched_table_id);
+ EE_OS_PARAM_VALUE(os_sched_table_id, ScheduleTableID);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_StopScheduleTable, os_sched_table_id,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STOPSCHEDULETABLE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+/* 8.4.15 GetScheduleTableStatus [SWS_Os_00227]
+ *
+ * This service queries the state of a schedule table (also with respect to
+ * synchronization).
+ *
+ * Sync/Async: Synchronous
+ *
+ * Reentrancy: Reentrant
+ *
+ * param ScheduleTableID (in): Schedule table for which status is requested.
+ * param ScheduleStatus (out): Reference to ScheduleTableStatusType.
+ *
+ * return StatusType:
+ * E_OK: No Error
+ * E_OS_ID (only in EXTENDED status): Invalid ScheduleTableID
+ *
+ * (SRS_Os_11002)
+ */
+StatusType EE_as_GetScheduleTableStatus(ScheduleTableType ScheduleTableID,
+ ScheduleTableStatusRefType ScheduleStatus)
+{
+ /* Return error value */
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETSCHEDULETABLESTATUS);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetScheduleTableStatus is callable only by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* OS566: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL.
+ +
+ + MISRA dictate NULL check for pointers always. */
+ if (ScheduleStatus == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if defined(__EE_MEMORY_PROTECTION__) && defined(EE_SERVICE_PROTECTION__)
+ /* [SWS_Os_00051] If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ ScheduleStatus, sizeof(*ScheduleStatus)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* __EE_MEMORY_PROTECTION__ && EE_SERVICE_PROTECTION__ */
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(ScheduleTableID)) {
+ EE_os_param as_schedule_status;
+ EE_os_param const
+ unmarked_sched_table_id = {
+ EE_AS_UNMARK_REMOTE_ID(ScheduleTableID)
+ };
+ as_schedule_status.schedule_table_status_ref = ScheduleStatus;
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc_from_us(OSServiceId_GetScheduleTableStatus,
+ unmarked_sched_table_id, as_schedule_status, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+ /* If local schedule tables are not defined cut everything else */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+ /* [SWS_Os_00293] If the identifier <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() is NOT valid, GetScheduleTableStatus() shall
+ * return E_OS_ID. */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else if (EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+ {
+ /* [SWS_Os_00289] If the schedule table <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() is NOT started, GetScheduleTableStatus()
+ * shall pass back SCHEDULETABLE_STOPPED via the reference parameter
+ * <ScheduleStatus> AND shall return E_OK. */
+ /* [SWS_Os_00353] If the schedule table <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() was used in a NextScheduleTable() call AND
+ * waits for the end of the current schedule table,
+ * GetScheduleTableStatus() shall return SCHEDULETABLE_NEXT via the
+ * reference parameter <ScheduleStatus> AND shall return E_OK. */
+ /* [SWS_Os_00354] If the schedule table <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() is configured with explicit synchronization
+ * AND <ScheduleTableID> was started with StartScheduleTableSynchron()
+ * AND no synchronization count was provided to the Operating System,
+ * GetScheduleTableStatus() shall return SCHEDULETABLE_WAITING via the
+ * reference parameter <ScheduleStatus> AND shall return E_OK. */
+ /* [SWS_Os_00290] If the schedule table <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() is started AND synchronous,
+ * GetScheduleTableStatus() shall pass back
+ * SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS via the reference parameter
+ * <ScheduleStatus> AND shall return E_OK. */
+ /* [SWS_Os_00291] If the schedule table <ScheduleTableID> in a call of
+ * GetScheduleTableStatus() is started AND NOT synchronous
+ * (deviation is not within the precision interval OR the schedule table
+ * has been set asynchronous), GetScheduleTableStatus() shall pass back
+ * SCHEDULETABLE_RUNNING via the reference parameter ScheduleStatus AND
+ * shall return E_OK. */
+ /* XXX: ScheduleTableStatusType is a EE_TYPESTATUS that is a EE_UREG so a
+ * read it SHOULD Atomic (Check this in other Architectures other than
+ * TriCore) */
+ *ScheduleStatus = EE_as_Schedule_Table_RAM[ScheduleTableID].status &
+ (~SCHEDULETABLE_ASYNC);
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_SCHEDULETABLE > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0U */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(ScheduleTableID);
+ EE_OS_ERROR_PARAMETERS_PARAM2_REF(schedule_table_status_ref, ScheduleStatus);
+
+ EE_os_notify_error_from_us(OSServiceId_GetScheduleTableStatus,
+ &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETSCHEDULETABLESTATUS);
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETSCHEDULETABLESTATUS);
+ }
+
+ return ev;
+}
+
+/* The following primitives are available only on local objects */
+#if defined(EE_MAX_SCHEDULETABLE) && (EE_MAX_SCHEDULETABLE > 0)
+
+/* 8.4.11 NextScheduleTable [SWS_Os_00191]
+ *
+ * This service switches the processing from one schedule table to another
+ * schedule table.
+ *
+ * Sync/Async: Synchronous
+ * Reentrancy: Reentrant
+ *
+ * @param ScheduleTableID_From: Currently processed schedule table
+ * @param ScheduleTableID_To: Schedule table that provides its series of
+ * expiry points
+ *
+ * @return StatusType
+ * E_OK: No error
+ * E_OS_ID (only in EXTENDED status): ScheduleTableID_From or
+ * ScheduleTableID_To not valid.
+ * E_OS_NOFUNC: ScheduleTableID_From not started
+ * E_OS_STATE: ScheduleTableID_To is started or next
+ *
+ * (SRS_Os_00099)
+ */
+StatusType EE_as_NextScheduleTable(ScheduleTableType ScheduleTableID_From,
+ ScheduleTableType ScheduleTableID_To)
+{
+ /* Return error value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_NEXTSCHEDULETABLE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* NextScheduleTable is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [SWS_Os_00282] If the input parameter <ScheduleTableID_From> or
+ * <ScheduleTableID_To> in a call of NextScheduleTable() is not valid,
+ * NextScheduleTable() shall return E_OS_ID. */
+ /* [SWS_Os_00330] If in a call of NextScheduleTable() schedule table
+ * <ScheduleTableID_To> is driven by different counter than schedule table
+ * <ScheduleTableID_From> then NextScheduleTable() shall return an error
+ * E_OS_ID. */
+ /* [SWS_Os_00279] If the schedule table identifier <ScheduleTableID> in a
+ * call of StopScheduleTable() is not valid, StopScheduleTable()
+ * shall return E_OS_ID. */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ if ((ScheduleTableID_From >= EE_MAX_SCHEDULETABLE) ||
+ (ScheduleTableID_To >= EE_MAX_SCHEDULETABLE)) {
+ ev = E_OS_ID;
+ } else if (
+ EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID_From, EE_as_active_app) ||
+ EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID_To, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if ((ScheduleTableID_From >= EE_MAX_SCHEDULETABLE) ||
+ (ScheduleTableID_To >= EE_MAX_SCHEDULETABLE)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+ /* [SWS_Os_00484] If OsScheduleTblSyncStrategy of <ScheduleTableID_To> in a
+ * call of NextScheduleTable() is not equal to the OsScheduleTblSyncStrategy
+ * of <ScheduleTableID_From> then NextScheduleTable() shall return E_OS_ID.
+ */
+ /* [SWS_Os_00283] If the schedule table <ScheduleTableID_From> in a call
+ * of NextScheduleTable() is in state SCHEDULETABLE_STOPPED OR in state
+ * SCHEDULETABLE_NEXT, NextScheduleTable() shall leave the state of
+ * <ScheduleTable_From> and <ScheduleTable_To> unchanged and return
+ * E_OS_NOFUNC. */
+ /* XXX: !!! Contradiction with SWS_Os_00324 && SWS_Os_00453 !!! */
+ /* [SWS_Os_00309] If the schedule table <ScheduleTableID_To> in a call of
+ * NextScheduleTable() is not in state SCHEDULETABLE_STOPPED,
+ * NextScheduleTable() shall leave the state of <ScheduleTable_From> and
+ * <ScheduleTable_To> unchanged and return E_OS_STATE. */
+ if ((EE_oo_counter_object_ROM[EE_MAX_ALARM + ScheduleTableID_From].c !=
+ EE_oo_counter_object_ROM[EE_MAX_ALARM + ScheduleTableID_To].c) ||
+ (EE_as_Schedule_Table_ROM[ScheduleTableID_From].sync_strategy !=
+ EE_as_Schedule_Table_ROM[ScheduleTableID_To].sync_strategy)) {
+ ev = E_OS_ID;
+ } else if ((EE_as_Schedule_Table_RAM[ScheduleTableID_From].
+ status == SCHEDULETABLE_STOPPED) ||
+ (EE_as_Schedule_Table_RAM[ScheduleTableID_From].
+ status == SCHEDULETABLE_NEXT)) {
+ ev = E_OS_NOFUNC;
+ } else if (EE_as_Schedule_Table_RAM[ScheduleTableID_To].
+ status != SCHEDULETABLE_STOPPED) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* [SWS_Os_00284] If the input parameters of NextScheduleTable() are valid
+ * then NextScheduleTable() shall start the processing of schedule table
+ * <ScheduleTableID_To> <ScheduleTableID_From>. FinalDelay ticks after the
+ * Final Expiry Point on <ScheduleTableID_From> is processed and shall
+ * return E_OK. NextScheduleTable() shall process the Initial Expiry Point
+ * on <ScheduleTableID_To> at <ScheduleTableID_From>.
+ * Final Delay + <ScheduleTable_To>.Initial Offset ticks after the Final
+ * Expiry Point on <ScheduleTableID_From> is processed. */
+ /* [SWS_Os_00324] If the input parameters of NextScheduleTable() are valid
+ * AND the <ScheduleTableID_From> already has a "next" schedule table then
+ * NextScheduleTable()shall replace the previous "next" schedule table with
+ * <ScheduleTableID_To> and shall change the old "next" schedule table state
+ * to SCHEDULETABLE_STOPPED.
+ * XXX: !!! Contradiction with SWS_Os_00283 !!! */
+ /* [SWS_Os_00505] If OsScheduleTblSyncStrategy of the schedule tables
+ * <ScheduleTableID_From> and <ScheduleTableID_To> in a call of
+ * NextScheduleTable() is EXPLICIT and the Operating System module already
+ * synchronizes <ScheduleTableID_From>, NextScheduleTable() shall continue
+ * synchronization after the start of processing <ScheduleTableID_To>. */
+ /* [SWS_Os_00453] If the <ScheduleTableID_From> in a call of
+ * NextScheduleTable() is stopped, NextScheduleTable() shall not start the
+ * "next" schedule table and change its state to SCHEDULETABLE_STOPPED.
+ * XXX: !!! Contradiction with SWS_Os_00283 !!! */
+ EE_as_Schedule_Table_RAM[ScheduleTableID_From].
+ next_table = ScheduleTableID_To;
+ EE_as_Schedule_Table_RAM[ScheduleTableID_To].status = SCHEDULETABLE_NEXT;
+
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_sched_table_id_from);
+ EE_OS_PARAM(os_sched_table_id_to);
+ EE_OS_PARAM_VALUE(os_sched_table_id_from, ScheduleTableID_From);
+ EE_OS_PARAM_VALUE(os_sched_table_id_to, ScheduleTableID_To);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_NextScheduleTable, os_sched_table_id_from,
+ os_sched_table_id_to, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_NEXTSCHEDULETABLE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+StatusType EE_as_SyncScheduleTable(ScheduleTableType ScheduleTableID,
+ TickType Value)
+{
+ /* Return error value */
+ register StatusType ev;
+
+ /* Schedule Table position locals */
+ register EE_UREG i;
+ register TickType st_pos;
+ register TickType next_ep_delay;
+ register TickType temp_deviation;
+
+ /* Counter Object ID that represent ScheduleTableID */
+ register const CounterObjectType obj_id = EE_MAX_ALARM + ScheduleTableID;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SYNCSCHEDULETABLE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* SyncScheduleTable is callable only by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ /* [SWS_Os_00279] If the schedule table identifier <ScheduleTableID> in a
+ * call of StopScheduleTable() is not valid, StopScheduleTable()
+ * shall return E_OS_ID. */
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else if (EE_SCHED_TABLE_ACCESS_ERR(ScheduleTableID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (ScheduleTableID >= EE_MAX_SCHEDULETABLE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [SWS_Os_00454] If the <ScheduleTableID> in a call of SyncScheduleTable()
+ * is not valid OR schedule table can not be explicitly synchronized
+ * (OsScheduleTblSyncStrategy is not equal to EXPLICIT)
+ * SyncScheduleTable() shall return E_OS_ID. */
+ /* [SWS_Os_00454] If the <ScheduleTableID> in a call of SyncScheduleTable()
+ * is not valid OR schedule table can not be explicitly synchronized
+ * (OsScheduleTblSyncStrategy is not equal to EXPLICIT)
+ * SyncScheduleTable() shall return E_OS_ID. */
+ /* [SWS_Os_00455] If the <Value> in a call of SyncScheduleTable() is
+ * greater or equal than the OsScheduleTableDuration, SyncScheduleTable()
+ * shall return E_OS_VALUE. */
+ /* [SWS_Os_00456] If the state of the schedule table <ScheduleTableID> in a
+ * call of SyncScheduleTable() is equal to SCHEDULETABLE_STOPPED or
+ * SCHEDULETABLE_NEXT SyncScheduleTable() shall return E_OS_STATE. */
+ if (EE_as_Schedule_Table_ROM[ScheduleTableID].sync_strategy !=
+ EE_SCHEDTABLE_SYNC_EXPLICIT) {
+ ev = E_OS_ID;
+ } else if (Value >= EE_as_Schedule_Table_ROM[ScheduleTableID].duration) {
+ ev = E_OS_VALUE;
+ } else if ((EE_as_Schedule_Table_RAM[ScheduleTableID].
+ status == SCHEDULETABLE_STOPPED) ||
+ (EE_as_Schedule_Table_RAM[ScheduleTableID].status == SCHEDULETABLE_NEXT)) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* Check if the ScheduleTable is Started */
+ if ((EE_as_Schedule_Table_RAM[ScheduleTableID].status &
+ SCHEDULETABLE_RUNNING) == SCHEDULETABLE_RUNNING) {
+ /* [SWS_Os_00457] If the parameters in a call of SyncScheduleTable() are
+ * valid, SyncScheduleTable() shall provide the Operating System module
+ * with the current synchronization count for the given schedule table.
+ * (It is used to synchronize the processing of the schedule table to the
+ * synchronization counter.) */
+ for (i = 0U, st_pos = 0; i <= EE_as_Schedule_Table_RAM[ScheduleTableID].
+ position; ++i) {
+ st_pos += EE_as_Expiry_Point_ROM[EE_as_Schedule_Table_ROM[
+ ScheduleTableID].expiry_point_first + i].offset;
+ }
+ /* After have summed all the passed and next expiry points offsets,
+ * subtract the remaining tick before the alarm => alarm delta.
+ * N.B delta == 0 in alarm is next tick */
+ next_ep_delay = EE_oo_counter_object_RAM[obj_id].delta;
+ st_pos -= (next_ep_delay + 1U);
+
+ /* Evaluate Schedule Table Deviation before synchronization */
+ temp_deviation = st_pos - Value;
+
+ /* [SWS_Os_00420]: IF the deviation is non-zero AND the next expiry point
+ * is adjustable AND the table is behind the sync counter
+ * (TableTicksAheadOfSyncCounter <= TableTicksBehindOfSyncCounter)
+ * THEN the OS shall set the next EP to expire
+ * delay - min(MaxShorten, Deviation) ticks from the current expiry. */
+ /* [SWS_Os_00421]: IF the deviation is non-zero AND the next expiry point
+ * is adjustable AND the table is ahead of the sync counter
+ * (TableTicksAheadOfSyncCounter > TableTicksBehindOfSyncCounter)
+ * THEN the OS shall set the next EP to expire delay +
+ * min(MaxLengthen, Deviation) ticks from the current expiry. */
+ /* Try to synchronize */
+ if (temp_deviation != 0U) {
+ if (temp_deviation < EE_TYPETICK_HALF_VALUE) {
+ /* Schedule Table is in advance */
+ TickType max_shorten = EE_as_Expiry_Point_ROM[
+ EE_as_Schedule_Table_RAM[ScheduleTableID].position].max_shorten;
+ TickType shortening = EE_as_tick_min(max_shorten, temp_deviation);
+ /* Shorten ep delay */
+ next_ep_delay -= shortening;
+ /* Adjust deviation */
+ temp_deviation -= shortening;
+ } else {
+ /* Schedule Table is in delay */
+ TickType max_lengthen = EE_as_Expiry_Point_ROM[
+ EE_as_Schedule_Table_RAM[ScheduleTableID].position].max_lengthen;
+ TickType lengthening = EE_as_tick_min(max_lengthen, -temp_deviation);
+ /* Lengthen ep delay */
+ next_ep_delay += lengthening;
+ /* Adjust deviation */
+ temp_deviation -= lengthening;
+ }
+
+ /* Cancel the alarm related with the schedule table */
+ EE_oo_handle_counter_object_cancellation(obj_id);
+ /* Restart the alarm related with the schedule table */
+ EE_oo_handle_rel_counter_object_insertion(obj_id, next_ep_delay, 0U);
+ }
+
+ /* if st abs(deviation) < st precision -> synchronized! */
+ if (EE_as_abs(temp_deviation) <
+ EE_as_Schedule_Table_ROM[ScheduleTableID].precision) {
+ /* [SWS_Os_00418]: The Operating System module shall set the state of
+ * an explicitly synchronized schedule table to
+ * "running and synchronous" if the deviation is less than or equal to
+ * the configured OsScheduleTblExplicitPrecision threshold. */
+ EE_as_Schedule_Table_RAM[ScheduleTableID].status =
+ SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS;
+ } else {
+ /* Try to synchronize */
+ /* [SWS_Os_00419]: The Operating System module shall set the state of
+ * an explicitly synchronized schedule table to "running" if the
+ * deviation is greater than the configured
+ * OsScheduleTblExplicitPrecision threshold. */
+ EE_as_Schedule_Table_RAM[ScheduleTableID].status =
+ SCHEDULETABLE_RUNNING;
+ }
+ EE_as_Schedule_Table_RAM[ScheduleTableID].deviation = temp_deviation;
+ } else {
+ /* Otherwise is waiting for synchronization before start
+ * (p_schedule_table_RAM->status == SCHEDULETABLE_WAITING) */
+ /* TODO: handle Schedule Table Synchronous Start */
+ }
+
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_schedule_table_id);
+ EE_OS_PARAM(os_value);
+ EE_OS_PARAM_VALUE(os_schedule_table_id, ScheduleTableID);
+ EE_OS_PARAM_VALUE(os_value, Value);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_SyncScheduleTable, os_schedule_table_id,
+ os_value, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SYNCSCHEDULETABLE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_spinlocks.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_spinlocks.c
new file mode 100644
index 0000000..45a274c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_spinlocks.c
@@ -0,0 +1,459 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_spinlocks.c
+ * @brief Autosar API and data structures for spinlocks management
+ * @author Errico Guidieri
+ * @date 2012
+ */
+
+#include "ee_internal.h"
+
+#ifndef EE_PRIVATE_SPINLOCK__
+
+StatusType EE_as_GetSpinlock(SpinlockIdType SpinlockId)
+{
+ /* Error Value */
+ register StatusType ev;
+ /* TASK or ISR2 current id */
+ register EE_TID current;
+
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETSPINLOCK);
+
+ EE_as_monitoring_the_stack();
+
+ /* If actually we are inside an ISR2 assign a fake TID to access stack */
+ if (EE_hal_get_IRQ_nesting_level() > 0U) {
+ current = EE_oo_assign_TID_to_ISR2();
+ } else {
+ current = EE_stk_queryfirst();
+ }
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* [OS650]: GetSpinlock shall be callable from TASK level. (BSW4080018,
+ * BSW4080021) */
+ /* [OS651]: GetSpinlock shall be callable from ISR2 level. (BSW4080021) */
+ /* The behavior of GetSpinlock is undefined if called from a category 1 ISR */
+ /* [OS693]: It shall be allowed to call the function GetSpinlock while
+ * interrupts are disabled. (BSW4080021) */
+ /* [OS694]: It shall be allowed to call the function GetSpinlock while a
+ * RESOURCE is occupied. (BSW4080021) */
+ /* GetSpinlock is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ /* [OS692]: The function GetSpinlock shall return E_OS_ACCESS if the accessing
+ * OS-Application was not listed in the configuration (OsSpinlock).
+ * (BSW4080021) */
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else if (EE_SPINLOCK_ACCESS_ERR(SpinlockId, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [OS689]: The function GetSpinlock shall return E_OS_ID if the parameter
+ * SpinlockID refers to a spinlock that does not exist. (BSW4080021) */
+ /* [OS658]: The AUTOSAR Operating System shall generate an error if a TASK
+ * tries to occupy a spinlock that is assigned to a TASK/ISR2 on the same
+ * core (including itself). (BSW4080018, BSW4080021) */
+ /* [OS659]: The AUTOSAR Operating System shall generate an error if an ISR2
+ * tries to occupy a spinlock that is assigned to a TASK/ISR2 on the same
+ * core. (BSW4080018, BSW4080021) */
+ /* [OS690]: The function GetSpinlock shall return E_OS_INTERFERENCE_DEADLOCK
+ * if the spinlock referred by the parameter SpinlockID is already occupied
+ * by a TASK/ISR2 on the same core. (BSW4080021) */
+ /* [OS660]: A unique order in which multiple spinlocks can be occupied by a
+ * TASK/ISR2 should be configurable in the AUTOSAR Operating System. This
+ * might be realized by the configuration item
+ * (OsSpinlockSuccessor{NEXT_SPINLOCK}) where "NEXT_SPINLOCK" refers to the
+ * consecutive spinlock. (See chapter 10.2.5) (BSW4080018, BSW4080021) */
+ /* [OS661]: The AUTOSAR Operating System shall generate an error if a
+ * TASK/ISR2 that currently holds a spinlock tries to seize another spinlock
+ * that has not been configured as a direct or indirect successor of the
+ * latest acquired spinlock (by means of the OsSpinlockSuccessor
+ * configuration parameter) or if no successor is configured.
+ * (BSW4080018, BSW4080021) */
+ /* [OS691]: The function GetSpinlock shall return E_OS_NESTING_DEADLOCK if the
+ * sequence by which multiple spinlocks are occupied at the same time do not
+ * comply with the configured order. (BSW4080021) */
+ if (current == EE_NIL) {
+ ev = E_OS_ACCESS;
+ } else if (EE_as_spinlocks_locker_core[SpinlockId] == EE_CURRENTCPU) {
+ ev = E_OS_INTERFERENCE_DEADLOCK;
+ } else
+#if defined(EE_SPINLOCK_ORDERED)
+ if ((EE_as_spinlocks_last[EE_CURRENTCPU] != INVALID_SPINLOCK) &&
+ (EE_as_spinlocks_last[EE_CURRENTCPU] >= SpinlockId))
+#else /* EE_SPINLOCK_ORDERED */
+ if (EE_as_spinlocks_last[EE_CURRENTCPU] != INVALID_SPINLOCK)
+#endif /* EE_SPINLOCK_ORDERED */
+ {
+ ev = E_OS_NESTING_DEADLOCK;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* [OS649]: The AUTOSAR Operating System shall provide a GetSpinlock
+ * function which occupies a spinlock. If the spinlock is already occupied,
+ * GetSpinlock shall keep on trying to occupy the spinlock until it
+ * succeeds. (BSW4080018, BSW4080021) Same of [OS687] */
+
+ /* Spin until get the lock */
+ EE_hal_spin_in(SpinlockId);
+
+ /* Populate Spinlocks Stack for CURRENT CPU */
+ EE_as_spinlocks_stack[SpinlockId] = EE_as_spinlocks_last[EE_CURRENTCPU];
+ EE_as_spinlocks_last[EE_CURRENTCPU] = SpinlockId;
+
+ /* Set CURRENT CPU and CURRENT THREAD (means TASK or ISR2) as
+ * spinlock locker */
+ EE_as_spinlocks_locker_core[SpinlockId] = (EE_TYPECOREID)EE_CURRENTCPU;
+
+ EE_as_spinlocks_locker_task_or_isr2[SpinlockId] = current;
+
+ /* [OS688]: The function GetSpinlock shall return E_OK if no error was
+ * detected. The spinlock is now occupied by the calling TASK/ISR2 on the
+ * calling core. */
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_spinlock_id);
+ EE_OS_PARAM_VALUE(os_spinlock_id, SpinlockId);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_GetSpinlock, os_spinlock_id,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETSPINLOCK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+StatusType EE_as_ReleaseSpinlock(SpinlockIdType SpinlockId)
+{
+ /* Error Value */
+ register StatusType ev;
+ register TaskType current;
+
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RELEASESPINLOCK);
+
+ EE_as_monitoring_the_stack();
+
+ /* If actually we are inside an ISR2 assign a fake TID to access stack */
+ if (EE_hal_get_IRQ_nesting_level() > 0U) {
+ current = EE_oo_assign_TID_to_ISR2();
+ } else {
+ current = EE_stk_queryfirst();
+ }
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* [OS655]: The AUTOSAR Operating System shall provide a ReleaseSpinlock
+ * function which releases an occupied spinlock. If the spinlock is not
+ * occupied an error shall be returned. (BSW4080018, BSW4080021) */
+ /* [OS656]: ReleaseSpinlock shall be callable from TASK level. (BSW4080018,
+ * BSW4080021)
+ * [OS657]: ReleaseSpinlock shall be callable from ISR2 level. (BSW4080018,
+ * BSW4080021) */
+
+ /* ReleaseSpinlock is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ /* [OS700]: The function ReleaseSpinlock shall return E_OS_ACCESS if the TASK
+ * has no access to the spinlock referred by the parameter SpinlockID
+ * (BSW4080021) */
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else if (EE_SPINLOCK_ACCESS_ERR(SpinlockId, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* [OS698]: The function ReleaseSpinlock shall return E_OS_ID if the parameter
+ * SpinlockID refers to a spinlock that does not exist. (BSW4080021) */
+ /* [OS699]: The function ReleaseSpinlock shall return E_OS_STATE if the
+ * parameter SpinlockID refers to a spinlock that is not occupied by the
+ * calling TASK. (BSW4080021) */
+ /* [OS701]: The function ReleaseSpinlock shall return E_OS_NOFUNC if the TASK
+ * tries to release a spinlock while another spinlock has to be released
+ * before. No functionality shall be performed. (BSW4080021) */
+ /* [OS702]: Spinlocks and RESOURCEs can only be locked and unlocked in strict
+ * LIFO order. Otherwise E_OS_RESOURCE shall be returned. (BSW4080021) */
+ if (current == EE_NIL) {
+ ev = E_OS_ACCESS;
+ } else if ((EE_as_spinlocks_locker_core[SpinlockId] != EE_CURRENTCPU) ||
+ (EE_as_spinlocks_locker_task_or_isr2[SpinlockId] != current)) {
+ ev = E_OS_STATE;
+ } else if (EE_as_spinlocks_last[EE_CURRENTCPU] != SpinlockId) {
+ ev = E_OS_NOFUNC;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* Remove the last entry from the data structure */
+ EE_as_spinlocks_last[EE_CURRENTCPU] = EE_as_spinlocks_stack[SpinlockId];
+
+ /* Free the spinlock */
+ EE_as_spinlocks_locker_core[SpinlockId] = INVALID_CORE_ID;
+ EE_as_spinlocks_locker_task_or_isr2[SpinlockId] = EE_NIL;
+
+ /* Release the lock */
+ EE_hal_spin_out(SpinlockId);
+
+ ev = E_OK;
+ }
+
+ /* [OS697]: The function ReleaseSpinlock shall return E_OK if no error was
+ * detected. The spinlock is now free and can be occupied by the same or
+ * other TASKs. (BSW4080021) */
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_spinlock_id);
+ EE_OS_PARAM_VALUE(os_spinlock_id, SpinlockId);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_ReleaseSpinlock, os_spinlock_id,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RELEASESPINLOCK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+ return ev;
+}
+
+StatusType EE_as_TryToGetSpinlock(SpinlockIdType SpinlockId,
+ TryToGetSpinlockType *Success)
+{
+ register EE_TID current;
+ register EE_BIT try_to_spin_in_flag;
+ /* Error Value */
+ register StatusType ev;
+
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_TRYTOGETSPINLOCK);
+
+ EE_as_monitoring_the_stack();
+
+ /* If actually we are inside an ISR2 assign a fake TID to access stack */
+ if (EE_hal_get_IRQ_nesting_level() > 0U) {
+ current = EE_oo_assign_TID_to_ISR2();
+ } else {
+ current = EE_stk_queryfirst();
+ }
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* [OS652]: The AUTOSAR Operating System shall provide a TryToGetSpinlock
+ * function which occupies a spinlock. If the spinlock is already occupied
+ * by a TASK, TryToGetSpinlock shall return. (BSW4080018, BSW4080021) */
+ /* [OS653]: TryToGetSpinlock shall be callable from TASK level.
+ * (BSW4080018, BSW4080021) */
+ /* [OS654]: TryToGetSpinlock shall be callable from ISR2 level.
+ * (BSW4080018, BSW4080021) */
+ /* [OS711]: It shall be allowed to call the function TryToGetSpinlock while
+ * interrupts are disabled. (BSW4080021) */
+ /* [OS712]: It shall be allowed to call the function TryToGetSpinlock while a
+ * RESOURCE is occupied. (BSW4080021) */
+
+ /* TryToGetSpinlock is callable by Task, ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__) && defined(EE_SERVICE_PROTECTION__))
+ /* [OS710]: The function TryToGetSpinlock shall return E_OS_ACCESS if the
+ * TASK has no access to the spinlock referred by the parameter SpinlockID
+ * (BSW4080021) */
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else if (EE_SPINLOCK_ACCESS_ERR(SpinlockId, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (SpinlockId >= (EE_TYPESPIN)EE_MAX_SPINLOCK_USER) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_FULL_SERVICE_PROTECTION || __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+
+ /* [OS706]: If the function TryToGetSpinlock does not return E_OK, the OUT
+ * parameter "Success" shall be undefined. (BSW4080021) */
+ /* [OS708]: The function TryToGetSpinlock shall return
+ * E_OS_INTERFERENCE_DEADLOCK if the spinlock referred by the parameter
+ * SpinlockID is already occupied by a TASK on the same core.(BSW4080021) */
+ /* [OS660]: A unique order in which multiple spinlocks can be occupied by a
+ * TASK/ISR2 should be configurable in the AUTOSAR Operating System. This
+ * might be realized by the configuration item
+ * (OsSpinlockSuccessor{NEXT_SPINLOCK}) where "NEXT_SPINLOCK" refers to the
+ * consecutive spinlock. (See chapter 10.2.5) (BSW4080018, BSW4080021) */
+ /* [OS661]: The AUTOSAR Operating System shall generate an error if a
+ * TASK/ISR2 that currently holds a spinlock tries to seize another spinlock
+ * that has not been configured as a direct or indirect successor of the
+ * latest acquired spinlock (by means of the OsSpinlockSuccessor
+ * configuration parameter) or if no successor is configured.
+ * (BSW4080018, BSW4080021) */
+ /* [OS709]: The function TryToGetSpinlock shall return E_OS_NESTING_DEADLOCK
+ * if a TASK tries to occupy a spinlock while holding a different spinlock
+ * in a way that may cause a deadlock. */
+ if (current == EE_NIL) {
+ ev = E_OS_ACCESS;
+ } else if (EE_as_spinlocks_locker_core[SpinlockId] == EE_CURRENTCPU) {
+ ev = E_OS_INTERFERENCE_DEADLOCK;
+ } else
+#if defined(EE_SPINLOCK_ORDERED)
+ if ((EE_as_spinlocks_last[EE_CURRENTCPU] != INVALID_SPINLOCK) &&
+ (EE_as_spinlocks_last[EE_CURRENTCPU] >= SpinlockId))
+#else /* EE_SPINLOCK_ORDERED */
+ if (EE_as_spinlocks_last[EE_CURRENTCPU] != INVALID_SPINLOCK)
+#endif /* EE_SPINLOCK_ORDERED */
+ {
+ ev = E_OS_NESTING_DEADLOCK;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL. +
+ * MISRA dictate NULL check for pointers always. */
+ if (Success == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else {
+ /* Try to Spin in, return immediately if it doesn't */
+ try_to_spin_in_flag = EE_hal_try_to_spin_in(SpinlockId);
+
+ /* [OS705]: The function TryToGetSpinlock shall set the OUT parameter
+ * "Success" to TRYTOGETSPINLOCK_SUCCESS if the spinlock was successfully
+ * occupied, and TRYTOGETSPINLOCK_NOSUCCESS if not. In both cases
+ * E_OK shall be returned. (BSW4080021) */
+ if (try_to_spin_in_flag == 0U) {
+ *Success = TRYTOGETSPINLOCK_NOSUCCESS;
+ } else {
+ /* Populate Spinlocks Stack for CURRENT CPU */
+ EE_as_spinlocks_stack[SpinlockId] = EE_as_spinlocks_last[EE_CURRENTCPU];
+ EE_as_spinlocks_last[EE_CURRENTCPU] = SpinlockId;
+
+ /* Set CURRENT CPU and CURRENT THREAD (means TASK or ISR2) as
+ * Spinlock locker */
+ EE_as_spinlocks_locker_core[SpinlockId] = (EE_TYPECOREID)EE_CURRENTCPU;
+
+ EE_as_spinlocks_locker_task_or_isr2[SpinlockId] = current;
+
+ *Success = TRYTOGETSPINLOCK_SUCCESS;
+ }
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_spinlock_id);
+ EE_OS_PARAM(os_success);
+ EE_OS_PARAM_VALUE(os_spinlock_id, SpinlockId);
+ EE_OS_PARAM_REF(os_success, try_to_get_spinlock_ref, Success);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSServiceId_TryToGetSpinlock, os_spinlock_id,
+ os_success, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_TRYTOGETSPINLOCK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+SpinlockIdType EE_as_release_all_spinlocks(EE_TID tid)
+{
+ /* ALLERT! This method have to be called only inside a critical section
+ * (e.g. interrupt disabled) */
+ register SpinlockIdType curSpin, spinId = INVALID_SPINLOCK;
+
+ curSpin = EE_as_spinlocks_last[EE_CURRENTCPU];
+ while ((curSpin != INVALID_SPINLOCK) &&
+ (EE_as_spinlocks_locker_task_or_isr2[curSpin] == tid)) {
+ spinId = curSpin;
+ /* Remove the last entry from the data structure */
+ EE_as_spinlocks_last[EE_CURRENTCPU] = EE_as_spinlocks_stack[curSpin];
+
+ /* Free the spinlock */
+ EE_as_spinlocks_locker_core[curSpin] = INVALID_CORE_ID;
+ EE_as_spinlocks_locker_task_or_isr2[curSpin] = EE_NIL;
+
+ /* Release the lock */
+ EE_hal_spin_out(curSpin);
+
+ curSpin = EE_as_spinlocks_last[EE_CURRENTCPU];
+ }
+
+ return spinId;
+}
+
+#endif /* EE_PRIVATE_SPINLOCK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_timing_prot.c b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_timing_prot.c
new file mode 100644
index 0000000..3061b50
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/as/src/ee_as_timing_prot.c
@@ -0,0 +1,590 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/** @file ee_as_timing_prot.c
+ * @brief AUTOSAR timing protection implementation
+ * @author Errico Guidieri
+ * @date 2013
+ */
+
+#include "ee_internal.h"
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+/* The following code belong to ERIKA OS section: ee_kernel_text */
+#define OS_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** Active Timing Protection Information set */
+EE_as_tp_active_type EE_as_tp_active = {
+ INVALID_TIMING_PROTECTION, NULL,
+ NULL
+};
+
+/** Be Aware that Reclamation Time Frame Budget Can Interrupt the Kernel
+ * because it updates only TP data structures */
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+
+/** Shortcut to the Time Frames Reclaim Budget conf structure */
+static const EE_as_tp_budget_conf_type *const
+reclamation_time_frame_budget_conf_ref =
+ &EE_as_tp_budget_confs[EE_RECLAMATION_TIME_FRAMES_BUDGET_ID];
+/** Shortcut to the Time Frames Reclaim Budget data structure */
+static EE_as_tp_budget_data_type *const
+reclamation_time_frame_budget_data_ref =
+ &EE_as_tp_budget_data[EE_RECLAMATION_TIME_FRAMES_BUDGET_ID];
+/** This hold the last update time for Time Frames Reclamation Budget */
+static TickType reclamation_time_frame_budget_last_update = 0U;
+
+static void EE_as_tp_update_reclamation_budget(TickType now)
+{
+ const TickType delta = EE_hal_swfrt_eval_elapsed_time(now,
+ reclamation_time_frame_budget_last_update);
+
+ reclamation_time_frame_budget_last_update = now;
+
+ /* Set a remaining budget of 0 in case (delta > real remaining budget) */
+ if (delta < reclamation_time_frame_budget_data_ref->remaining_budget) {
+ reclamation_time_frame_budget_data_ref->remaining_budget -= delta;
+ } else {
+ reclamation_time_frame_budget_data_ref->remaining_budget = 0U;
+ }
+}
+
+static void EE_as_tp_RAM_first_expiring_against_reclamation(
+ EE_as_tp_RAM_ref const tp_ram_ref)
+{
+ if (EE_as_tp_budget_data[tp_ram_ref->first_expiring].
+ remaining_budget > reclamation_time_frame_budget_data_ref->
+ remaining_budget) {
+ tp_ram_ref->first_expiring = EE_RECLAMATION_TIME_FRAMES_BUDGET_ID;
+ }
+}
+
+static void EE_as_tp_time_frames_reclaim(void)
+{
+ TickType const now = EE_hal_swfrt_get_current_time();
+ TimingProtectionType tp_id;
+
+ for (tp_id = 0U; tp_id < EE_MAX_TP; ++tp_id) {
+ const EE_as_tp_ROM_const_ref tp_rom_ref = EE_as_tp_ROM_refs[tp_id];
+ const EE_as_tp_RAM_ref tp_ram_ref = EE_as_tp_RAM_refs[tp_id];
+
+ if ((tp_rom_ref != NULL) && (tp_ram_ref != NULL)) {
+ const TickType delta =
+ EE_hal_swfrt_eval_elapsed_time(now, tp_ram_ref->interarrival_frame.
+ frame_start);
+
+ if (delta >= tp_rom_ref->frame_duration) {
+ tp_ram_ref->interarrival_frame.active = EE_FALSE;
+ }
+ }
+ }
+
+ /* RESET the Time Frames Reclamation Budget and Update
+ * reclamation_time_frame_budget_last_update */
+ reclamation_time_frame_budget_data_ref->remaining_budget =
+ reclamation_time_frame_budget_conf_ref->budget_value;
+ reclamation_time_frame_budget_last_update = now;
+}
+
+void EE_as_tp_active_start_idle(void)
+{
+ TickType const now = EE_hal_swfrt_get_current_time();
+
+ EE_as_tp_active_set(INVALID_TIMING_PROTECTION);
+
+ EE_as_tp_update_reclamation_budget(now);
+
+ if (reclamation_time_frame_budget_data_ref->
+ remaining_budget == 0U) {
+ /* Handle here the Time Frames Reclamation Budget */
+ EE_as_tp_time_frames_reclaim();
+ }
+
+ /* Just Re-enable Time Frame Reclamation Budget */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+}
+
+#else /* !EE_NO_RECLAMATION_TIME_FRAMES */
+#define EE_as_tp_update_reclamation_budget(now) ((void)0)
+#define EE_as_tp_RAM_first_expiring_against_reclamation(tp_ram_ref) ((void)0)
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+
+/** Update Active Budgets: It return the active budget reference */
+static EE_as_tp_budget_data_type *EE_as_tp_active_update_budgets(
+ TickType now,
+ BudgetType *first_expiring_index_ref)
+{
+ /* Update budgets */
+ BudgetType b_index;
+
+ EE_as_tp_budget_data_type *first_expiring_budget_ref;
+ EE_as_tp_RAM_type *const tp_ram = EE_as_tp_active.active_tp_RAM_ref;
+ EE_as_tp_ROM_type const *const tp_rom = EE_as_tp_active.active_tp_ROM_ref;
+ TickType const delta = EE_hal_swfrt_eval_elapsed_time(now,
+ tp_ram->last_update);
+
+ tp_ram->last_update = now;
+
+ /* Prepare return values */
+ (*first_expiring_index_ref) = tp_ram->first_expiring;
+ first_expiring_budget_ref =
+ &EE_as_tp_budget_data[(*first_expiring_index_ref)];
+
+ /* Always Update the Reclaim Time Frames budget */
+ EE_as_tp_update_reclamation_budget(now);
+
+ for (b_index = tp_rom->budgets_begin_index;
+ b_index <= tp_rom->budgets_end_index; ++b_index) {
+ if (EE_as_tp_budget_data[b_index].active != EE_FALSE) {
+ if (delta < EE_as_tp_budget_data[b_index].remaining_budget) {
+ EE_as_tp_budget_data[b_index].remaining_budget -= delta;
+ } else {
+ EE_as_tp_budget_data[b_index].remaining_budget = 0U;
+ }
+ }
+ }
+
+ return first_expiring_budget_ref;
+}
+
+static void EE_as_tp_active_handle_budget_expired(EE_as_tp_budget_type
+ expired)
+{
+ switch (expired) {
+ case EE_EXECUTION_BUDGET:
+ EE_as_call_protection_error(EE_as_active_app,
+ E_OS_PROTECTION_TIME);
+ break;
+ case EE_RESOURCE_LOCK_BUDGET:
+ case EE_OS_INTERRUPT_LOCK_BUDGET:
+ case EE_ALL_INTERRUPT_LOCK_BUDGET:
+ EE_as_call_protection_error(EE_as_active_app,
+ E_OS_PROTECTION_LOCKED);
+ break;
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ case EE_RECLAMATION_TIME_FRAMES_BUDGET:
+ /* Reclaim the already expired Time Frames */
+ EE_as_tp_time_frames_reclaim();
+ break;
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+ default:
+ /* THIS CANNOT NEVER HAPPENS (Signal the biggest error, just in case) */
+ EE_as_call_protection_error(EE_as_active_app,
+ E_OS_PROTECTION_EXCEPTION);
+ break;
+ }
+}
+
+/* Get the budget index to the TP represented by tp_rom_ref */
+static BudgetType EE_as_tp_active_get_budget(EE_as_tp_ROM_const_ref const
+ tp_rom_ref,
+ EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id)
+{
+ BudgetType budget_index;
+
+ switch (budget_type) {
+ case EE_EXECUTION_BUDGET:
+ budget_index = tp_rom_ref->execution_budget_index;
+ break;
+#ifndef __OO_NO_RESOURCES__
+ case EE_RESOURCE_LOCK_BUDGET:
+ if (tp_rom_ref->resources_lock_budgets_ref != NULL) {
+ budget_index = (*tp_rom_ref->resources_lock_budgets_ref)[ref_object_id];
+ } else {
+ budget_index = INVALID_BUDGET;
+ }
+ break;
+#endif /* __OO_NO_RESOURCES__ */
+ case EE_OS_INTERRUPT_LOCK_BUDGET:
+ budget_index = tp_rom_ref->os_isr_lock_budget_index;
+ break;
+ case EE_ALL_INTERRUPT_LOCK_BUDGET:
+ budget_index = tp_rom_ref->all_isr_lock_budget_index;
+ break;
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ case EE_RECLAMATION_TIME_FRAMES_BUDGET:
+ /* budget_index = EE_RECLAMATION_TIME_FRAMES_BUDGET_ID; */
+ /* break; */
+ /* XXX: EE_RECLAMATION_TIME_FRAME_BUDGET is an invalid budget where
+ * this function is called */
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+ default:
+ /* THIS CANNOT NEVER HAPPENS */
+ budget_index = INVALID_BUDGET;
+ break;
+ }
+
+ return budget_index;
+}
+
+/** Set active Timing Protection from TASK Id, saving "now" in "last update" */
+void EE_as_tp_active_set_from_TASK(TaskType task_id)
+{
+ EE_as_tp_active_set(EE_AS_TP_ID_FROM_TASK(task_id));
+
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ /* Frame reclamation check against first expiring */
+ EE_as_tp_RAM_first_expiring_against_reclamation(EE_as_tp_active.
+ active_tp_RAM_ref);
+
+ EE_as_tp_active.active_tp_RAM_ref->last_update =
+ EE_hal_swfrt_get_current_time();
+ }
+}
+
+/** Set active timing protection from TP Id, saving "now" in "last update" */
+void EE_as_tp_active_set_from_id_with_restart(TimingProtectionType tp_id)
+{
+ EE_as_tp_RAM_type *tp_ram_ref;
+
+ EE_as_tp_active_set(tp_id);
+
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ tp_ram_ref = EE_as_tp_active.active_tp_RAM_ref;
+ tp_ram_ref->last_update = EE_hal_swfrt_get_current_time();
+
+ /* Frame reclamation check against first expiring */
+ EE_as_tp_RAM_first_expiring_against_reclamation(tp_ram_ref);
+
+ /* Restart the first expiring budget */
+ EE_hal_tp_set_expiration(EE_as_tp_budget_data[tp_ram_ref->first_expiring].
+ remaining_budget);
+ }
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ else {
+ /* Just restart the Time Frames Reclamation Budget */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+ }
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+}
+
+/** Start timing protection for the TASK that is going to be started or
+ * released from a wait */
+void EE_as_tp_active_start_on_TASK_stacking(TaskType task_id)
+{
+ BudgetType execution_budget_index;
+
+ EE_as_tp_active_set_from_TASK(task_id);
+
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ /* On Activation/Release the only budget going active is EXECUTIONBUDGET */
+ execution_budget_index = EE_as_tp_active.active_tp_ROM_ref->
+ execution_budget_index;
+ if (execution_budget_index != INVALID_BUDGET) {
+ EE_as_tp_RAM_ref const tp_ram_ref = EE_as_tp_active.active_tp_RAM_ref;
+ EE_as_tp_budget_data_type *const execution_budget_ref =
+ &EE_as_tp_budget_data[execution_budget_index];
+
+ /* Update TP RAM and execution budget */
+ tp_ram_ref->first_expiring = execution_budget_index;
+ execution_budget_ref->active = EE_TRUE;
+
+ /* Frame reclamation check against first expiring */
+ EE_as_tp_RAM_first_expiring_against_reclamation(tp_ram_ref);
+
+ /* Update the last update */
+ tp_ram_ref->last_update = EE_hal_swfrt_get_current_time();
+ /* Restart the first expiring budget */
+ EE_hal_tp_set_expiration(EE_as_tp_budget_data[tp_ram_ref->first_expiring].
+ remaining_budget);
+ }
+ }
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ else {
+ /* Just restart the Time Frames Reclamation Budget */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+ }
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+}
+
+/** Start timing protection for a new ISR2 */
+void EE_as_tp_active_start_for_ISR2(ISRType isr2_id)
+{
+ BudgetType execution_budget_index;
+
+ /* Activate the TP for the ISR2 */
+ EE_as_tp_active_set(EE_AS_TP_ID_FROM_ISR2(isr2_id));
+
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ /* At the beginning of a ISR2 the only budget going active is
+ * EXECUTIONBUDGET. */
+ execution_budget_index = EE_as_tp_active.active_tp_ROM_ref->
+ execution_budget_index;
+
+ if (execution_budget_index != INVALID_BUDGET) {
+ EE_as_tp_RAM_ref const tp_ram_ref = EE_as_tp_active.active_tp_RAM_ref;
+ EE_as_tp_budget_data_type *const execution_budget_ref =
+ &EE_as_tp_budget_data[execution_budget_index];
+
+ /* Update TP RAM and execution budget */
+ tp_ram_ref->first_expiring = execution_budget_index;
+ execution_budget_ref->active = EE_TRUE;
+
+ /* Frame reclamation check against first expiring */
+ EE_as_tp_RAM_first_expiring_against_reclamation(tp_ram_ref);
+
+ /* Update the last update */
+ tp_ram_ref->last_update = EE_hal_swfrt_get_current_time();
+ /* Restart the first expiring budget */
+ EE_hal_tp_set_expiration(EE_as_tp_budget_data[tp_ram_ref->first_expiring].
+ remaining_budget);
+ }
+ }
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ else {
+ /* Just restart the Time Frames Reclamation Budget */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+ }
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+}
+
+/** Stop the active timing protection without updates. Used where we are
+ * sure that current TP won't be restarted. Instead the Time Frame Reclamation
+ * Budget is enabled if needed */
+void EE_as_tp_active_stop(void)
+{
+ EE_hal_tp_stop();
+ EE_as_tp_active_set(INVALID_TIMING_PROTECTION);
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ /* Just Re-enable Time Frame Reclamation Budget */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+}
+
+void EE_as_tp_active_pause_and_update_budgets_impl(void)
+{
+ /* Not used */
+ BudgetType b_index;
+
+ (void)EE_as_tp_active_update_budgets(EE_hal_tp_get_current_time_and_pause(),
+ &b_index);
+}
+
+void EE_as_tp_active_update_budgets_and_restart_impl(void)
+{
+ EE_as_tp_budget_data_type *first_expiring_budget_ref;
+ BudgetType first_expiring_index;
+
+ first_expiring_budget_ref =
+ EE_as_tp_active_update_budgets(EE_hal_swfrt_get_current_time(),
+ &first_expiring_index);
+
+ /* This function is the TP's CRITICAL SECTION end it have to handle
+ * Trusted Function Call TP Error Delaying. */
+ /* [SWS_Os_00565]: When CallTrustedFunction() is called and the caller of
+ * CallTrustedFunction() is supervised with timing protection, the Operating
+ * System shall delay any timing protection errors until the return of
+ * CallTrustedFunction(). */
+ /* [SWS_Os_00564]: If such a violation is detected inside a nested call
+ * sequence of CallTrustedFunction() of a task, the delay shall last until
+ * the return of the last CallTrustedFunction(). */
+ if (!EE_as_active_app_is_inside_trusted_function_call()) {
+ if (first_expiring_budget_ref->remaining_budget > 0U) {
+ /* Restart the timing protection */
+ EE_hal_tp_set_expiration(first_expiring_budget_ref->remaining_budget);
+ } else {
+ /* Handle Budget Expiration */
+ EE_as_tp_active_handle_budget_expired(
+ EE_as_tp_budget_confs[first_expiring_index].budget_type);
+ /* The following code it's executed only if first expiring was
+ * EE_RECLAMATION_TIME_FRAMES_BUDGET_ID */
+ EE_as_tp_active_eval_first_expiring();
+ }
+ }
+}
+
+void EE_as_tp_active_budget_expired(void)
+{
+ if (EE_as_tp_active.active_tp != INVALID_TIMING_PROTECTION) {
+ EE_as_tp_active_handle_budget_expired(EE_as_tp_budget_confs[
+ EE_as_tp_active.active_tp_RAM_ref->first_expiring].budget_type);
+ } else {
+#ifndef EE_NO_RECLAMATION_TIME_FRAMES
+ /* EE_as_tp_active_handle_budget_expired(EE_RECLAMATION_TIME_FRAMES_BUDGET);
+ * Better the following */
+ /* Handle Time Frames Reclamation Budget... */
+ EE_as_tp_time_frames_reclaim();
+ /* ...And Re-enable it */
+ EE_hal_tp_set_expiration(reclamation_time_frame_budget_data_ref->
+ remaining_budget);
+#else /* !EE_NO_RECLAMATION_TIME_FRAMES */
+ /* KERNEL BUG Condition! Signal the worst condition */
+ EE_as_call_protection_error(EE_as_active_app, E_OS_PROTECTION_EXCEPTION);
+#endif /* !EE_NO_RECLAMATION_TIME_FRAMES */
+ }
+}
+
+/** This function update actual active budgets, active a new budget for
+ * the active TP, after that reassess the first expiring budget */
+void EE_as_tp_active_activate_budget_impl(EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL start_first)
+{
+ EE_as_tp_budget_data_type *first_expiring_budget_ref;
+ /* Not Used: just to feed EE_as_tp_active_update_budgets... */
+ BudgetType b_index_first_expiring;
+
+ /* Index and Reference to the budget to be activated */
+ BudgetType time_budget_index;
+ EE_as_tp_budget_data_type *time_budget_ref;
+
+ /* Get TP {RAM, ROM} references */
+ EE_as_tp_RAM_type *const tp_ram_ref = EE_as_tp_active.active_tp_RAM_ref;
+ EE_as_tp_ROM_type const *const tp_rom_ref =
+ EE_as_tp_active.active_tp_ROM_ref;
+
+ /* Check if the budget to be activated is configured */
+ time_budget_index = EE_as_tp_active_get_budget(tp_rom_ref, budget_type,
+ ref_object_id);
+
+ /* If the budget is really configured: handle the update + activation */
+ if (time_budget_index != INVALID_BUDGET) {
+ /* Update active budgets and get information for the first expiring
+ * budget */
+ first_expiring_budget_ref = EE_as_tp_active_update_budgets(
+ EE_hal_swfrt_get_current_time(), &b_index_first_expiring);
+
+ /* Get the budget data structure */
+ time_budget_ref = &EE_as_tp_budget_data[time_budget_index];
+
+ /* Activate the new one */
+ time_budget_ref->active = EE_TRUE;
+
+ /* Eventually change the first expiring budget */
+ if (time_budget_ref->remaining_budget < first_expiring_budget_ref->
+ remaining_budget) {
+ tp_ram_ref->first_expiring = time_budget_index;
+ if (start_first) {
+ EE_hal_tp_set_expiration(time_budget_ref->remaining_budget);
+ }
+ } else {
+ if (start_first) {
+ EE_hal_tp_set_expiration(first_expiring_budget_ref->remaining_budget);
+ }
+ }
+ }
+}
+
+/** This function update actual active budgets, active a new budget for
+ * the active TP, after that reassess the first expiring budget */
+void EE_as_tp_active_stop_budget_impl(EE_as_tp_budget_type budget_type,
+ EE_UTID ref_object_id,
+ EE_TYPEBOOL start_first)
+{
+ /* Index of stopping budget */
+ BudgetType time_budget_index;
+
+ /* Get TP {RAM, ROM} references */
+ EE_as_tp_RAM_type *const tp_ram_ref = EE_as_tp_active.active_tp_RAM_ref;
+ EE_as_tp_ROM_type const *const tp_rom_ref =
+ EE_as_tp_active.active_tp_ROM_ref;
+
+ /* Check if the budget to be activated is configured */
+ time_budget_index = EE_as_tp_active_get_budget(tp_rom_ref, budget_type,
+ ref_object_id);
+
+ /* If the budget is really configured: handle the update + activation */
+ if (time_budget_index != INVALID_BUDGET) {
+ /* Stop and reset the given budget */
+ EE_as_tp_stop_budget(tp_ram_ref, time_budget_index);
+ /* Check if a new first expiring budget have to be set and evaluate it */
+ if (time_budget_index == tp_ram_ref->first_expiring) {
+ EE_as_tp_active_eval_first_expiring();
+ }
+
+ if (start_first) {
+ /* Restart the first expiring budget */
+ EE_hal_tp_set_expiration(EE_as_tp_budget_data[tp_ram_ref->first_expiring].
+ remaining_budget);
+ }
+ }
+}
+
+EE_TYPEBOOL EE_as_tp_handle_interarrival(TimingProtectionType tp_id)
+{
+ TickType now;
+ EE_TYPEBOOL interarrival_ok = EE_TRUE;
+ const EE_as_tp_ROM_const_ref tp_rom_ref = EE_as_tp_ROM_refs[tp_id];
+ const EE_as_tp_RAM_ref tp_ram_ref = EE_as_tp_RAM_refs[tp_id];
+
+ /* If this tp_id is really exist... ( If EE_as_tp_RAM_refs[tp_id] is NULL it
+ * MUST be NULL EE_as_tp_ROM_refs[tp_id] too!!! )
+ * (I check both pointers to make MISRA Happy) */
+ if ((tp_rom_ref != NULL) && (tp_ram_ref != NULL)) {
+ /* If the inter-arrival frame protection is configured for this TP... */
+ if (tp_rom_ref->frame_duration != EE_OS_NO_TIME) {
+ now = EE_hal_swfrt_get_current_time();
+
+ /* Activation/Release is allowed if the frame is expired
+ * OR if inter-arrival protection is disabled */
+ if ((EE_hal_swfrt_eval_elapsed_time(now, tp_ram_ref->interarrival_frame.
+ frame_start) > tp_rom_ref->frame_duration) ||
+ (tp_ram_ref->interarrival_frame.active == EE_FALSE)) {
+ /* Save the new frame start time */
+ tp_ram_ref->interarrival_frame.frame_start = now;
+ /* Active inter-arrival protection */
+ tp_ram_ref->interarrival_frame.active = EE_TRUE;
+ } else {
+ /* Inter-arrival Error: Call the Protection(Hook) */
+ EE_as_call_protection_error(EE_as_active_app, E_OS_PROTECTION_ARRIVAL);
+ /* And tell to the Kernel to not perform Activation/Release */
+ interarrival_ok = EE_FALSE;
+ }
+ }
+ }
+ return interarrival_ok;
+}
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#define OS_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/edf/cfg/cfg.mk
new file mode 100644
index 0000000..0f787d0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/cfg/cfg.mk
@@ -0,0 +1,56 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.1.1.1 2007/04/10 12:53:52 claudio Exp $
+
+ifeq ($(call iseeopt, __EDF__), yes)
+EE_SRCS += pkg/kernel/edf/src/ee_gettime.c
+EE_SRCS += pkg/kernel/edf/src/ee_irqsc.c
+EE_SRCS += pkg/kernel/edf/src/ee_rqexchg.c
+EE_SRCS += pkg/kernel/edf/src/ee_rqinsert.c
+EE_SRCS += pkg/kernel/edf/src/ee_schedule.c
+EE_SRCS += pkg/kernel/edf/src/ee_thact.c
+EE_SRCS += pkg/kernel/edf/src/ee_thendin.c
+
+ ifneq ($(call iseeopt, __EDF_NO_RESOURCE__), yes)
+ EE_SRCS += pkg/kernel/edf/src/ee_mutex.c
+ endif
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_api.h
new file mode 100644
index 0000000..7fa7ae9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_api.h
@@ -0,0 +1,78 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ * CVS: $Id: ee_api.h,v 1.3 2007/05/25 15:55:12 pj Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_EDF_EE_API__
+#define __INCLUDE_KERNEL_EDF_EE_API__
+
+#ifdef __EDF__
+
+#ifndef Schedule
+#define Schedule EE_edf_Schedule
+#endif
+
+#ifndef ActivateTask
+#define ActivateTask EE_edf_ActivateTask
+#endif
+
+#ifndef GetResource
+#define GetResource EE_edf_GetResource
+#endif
+
+#ifndef ReleaseResource
+#define ReleaseResource EE_edf_ReleaseResource
+#endif
+
+#ifndef GetTime
+#ifdef __TIME_SUPPORT__
+#ifndef __JANUS__
+#define GetTime EE_edf_GetTime
+#endif
+#endif
+#endif
+
+#endif /* __EDF__ */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_edf_common.h b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_edf_common.h
new file mode 100644
index 0000000..2b8ec4d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_edf_common.h
@@ -0,0 +1,140 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/*
+ * Author: 2001,2002 Paolo Gai
+ * CVS: $Id: ee_common.h,v 1.4 2008/07/15 13:22:09 pj Exp $
+ */
+
+#ifndef __INCLUDE_EDF_COMMON_H__
+#define __INCLUDE_EDF_COMMON_H__
+
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* invalid TID */
+#define EE_NIL ((EE_TID)-1)
+
+/* Task statuses */
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+/* This is needed for initialization purposes
+ * in the source code generated by RT-Druid
+ */
+#define EE_READY 1
+#endif
+
+/*************************************************************************
+* Kernel Types
+*************************************************************************/
+
+/* priority type */
+#ifndef EE_TYPEPRIO
+#define EE_TYPEPRIO EE_UREG
+#endif
+
+/* status type */
+#ifndef EE_TYPESTATUS
+#define EE_TYPESTATUS EE_UREG
+#endif
+
+/* pending activation type */
+#ifndef EE_TYPENACT
+#define EE_TYPENACT EE_UREG
+#endif
+
+/* Maximum number of pending activations */
+#ifndef EE_MAX_NACT
+#define EE_MAX_NACT ((EE_UREG)-1)
+#endif
+
+/* Resource ID type */
+#ifndef EE_TYPERESOURCE
+#define EE_TYPERESOURCE EE_UREG
+#endif
+
+/* relative deadline type */
+#ifndef EE_TYPERELDLINE
+#define EE_TYPERELDLINE EE_TIME
+#endif
+
+/* absolute deadline type */
+#ifndef EE_TYPEABSDLINE
+#define EE_TYPEABSDLINE EE_TIME
+#endif
+
+
+/*************************************************************************
+* Kernel Variables
+*************************************************************************/
+
+/* ROM */
+extern const EE_TYPEPRIO EE_th_ready_prio[]; /* task preemption level */
+extern const EE_TYPEPRIO EE_th_dispatch_prio[]; /* task threshold */
+#ifndef __EDF_NO_RESOURCE__
+extern const EE_TYPEPRIO EE_resource_ceiling[]; /* resource ceiling */
+#endif
+
+/* RAM */
+extern EE_TYPESTATUS EE_th_status[]; /* task status */
+extern EE_TYPENACT EE_th_nact[]; /* pending activations */
+extern EE_TID EE_th_next[]; /* next task in queue */
+
+extern EE_TYPEPRIO EE_sys_ceiling; /* system ceiling */
+#ifndef __EDF_NO_RESOURCE__
+extern EE_TYPEPRIO EE_resource_oldceiling[]; /* old resource ceiling */
+#endif
+
+/* The first task into the ready queue */
+extern EE_TID EE_rqfirst;
+
+/* The first stacked task */
+extern EE_TID EE_stkfirst;
+
+#ifdef __REL_DEADLINES_IN_RAM__
+extern EE_TYPERELDLINE EE_th_reldline[]; /* task relative deadline */
+#else
+extern const EE_TYPERELDLINE EE_th_reldline[]; /* task relative deadline */
+#endif
+
+extern EE_TYPEABSDLINE EE_th_absdline[]; /* task absolute deadline */
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_internal.h
new file mode 100644
index 0000000..fa53b6a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_internal.h
@@ -0,0 +1,136 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001,2002 Paolo Gai
+ * CVS: $Id: ee_internal.h,v 1.3 2007/05/25 15:55:12 pj Exp $
+ */
+
+#include "kernel/edf/inc/ee_edf_common.h"
+#include "kernel/edf/inc/ee_irq.h"
+
+#ifndef __INCLUDE_EDF_INTERNAL_H__
+#define __INCLUDE_EDF_INTERNAL_H__
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* Task statuses:
+ * In general, a task status is needed for two reasons:
+ * - for debug purposes,
+ * - and, if used with a Multistack HAL, for storing a flag that let
+ * the kernel know if the task has some space allocated on its stack.
+ */
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+/* #define EE_READY 1 in ee_common.h */
+#define EE_STACKED 2
+
+/* used by semaphores and blocking primitives in general */
+#define EE_BLOCKED 4
+
+#if defined(__MULTI__)
+/* used to know if a task has some space allocated on its stack */
+#define EE_WASSTACKED 8
+#endif
+
+#endif
+
+
+
+/*************************************************************************
+* System functions
+*************************************************************************/
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+void EE_thread_end_instance(void);
+#endif
+
+
+/*************************************************************************
+* Internal Queue management functions
+*************************************************************************/
+
+
+#ifndef __PRIVATE_RQ_QUERYFIRST__
+/* return the first ready task without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst(void)
+{
+ return EE_rqfirst;
+}
+#endif
+
+#ifndef __PRIVATE_STK_QUERYFIRST__
+/* return the first stacked task (the running task) without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void)
+{
+ return EE_stkfirst;
+}
+#endif
+
+#ifndef __PRIVATE_STK_GETFIRST__
+/* extract the running task from the stack */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_getfirst(void)
+{
+ EE_stkfirst = EE_th_next[EE_stkfirst];
+}
+#endif
+
+#ifndef __PRIVATE_STK_INSERTFIRST__
+/* insert a task into the stack data structures */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_insertfirst(EE_TID t)
+{
+ EE_th_next[t] = EE_stkfirst;
+ EE_stkfirst = t;
+}
+#endif
+
+#ifndef __PRIVATE_RQ_INSERT__
+/* insert a task into the ready queue */
+void EE_rq_insert(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+/* put the first ready task into the stack */
+EE_TID EE_rq2stk_exchange(void);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_irq.h
new file mode 100644
index 0000000..4c4f3d0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_irq.h
@@ -0,0 +1,52 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2012 Errico Guidieri
+ */
+
+#ifndef INCLUDE_EDF_IRQ_H__
+#define INCLUDE_EDF_IRQ_H__
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+void EE_IRQ_end_instance(void);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_kernel.h
new file mode 100644
index 0000000..430ec2c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/inc/ee_kernel.h
@@ -0,0 +1,102 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001,2002 Paolo Gai
+ * CVS: $Id: ee_kernel.h,v 1.2 2007/05/25 15:55:12 pj Exp $
+ */
+
+#include "kernel/edf/inc/ee_edf_common.h"
+
+#ifndef __INCLUDE_EDF_KERN_H__
+#define __INCLUDE_EDF_KERN_H__
+
+
+/*************************************************************************
+* Public Kernel Types and Constants
+*************************************************************************/
+
+#define INVALID_TASK EE_NIL
+
+typedef EE_TID TaskType;
+typedef EE_TYPERESOURCE ResourceType;
+typedef EE_TYPERELDLINE TimeRelType;
+typedef EE_TYPEABSDLINE TimeAbsType;
+
+/*************************************************************************
+* Kernel Primitives
+*************************************************************************/
+
+/* This macros are used to define a task */
+#define DeclareTask(t) void Func##t(void)
+#define TASK(t) void Func##t(void)
+
+#ifndef __PRIVATE_ACTIVATETASK__
+/* This primitive activates a task once and then execute the
+ * preemption test */
+void EE_edf_ActivateTask(TaskType t);
+#endif
+
+#ifndef __PRIVATE_SCHEDULER__
+void EE_edf_Schedule(void);
+#endif
+
+
+#ifndef __EDF_NO_RESOURCE__
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_edf_GetResource(ResourceType m);
+#endif
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_edf_ReleaseResource(ResourceType m);
+#endif
+
+#endif
+
+
+#ifndef __PRIVATE_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_edf_GetTime(void);
+#endif
+#endif
+
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_gettime.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_gettime.c
new file mode 100644
index 0000000..c6b70e0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_gettime.c
@@ -0,0 +1,61 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_gettime.c,v 1.2 2007/05/25 15:55:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_edf_GetTime()
+{
+ EE_TIME t;
+ register EE_FREG flags;
+
+ flags = EE_hal_begin_nested_primitive();
+ t = EE_hal_gettime();
+ EE_hal_end_nested_primitive(flags);
+ return t;
+}
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_irqsc.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_irqsc.c
new file mode 100644
index 0000000..915a7c5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_irqsc.c
@@ -0,0 +1,105 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_irqsc.c,v 1.3 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allows IRQ nesting, then the C_end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the
+ * stack
+ * - if there are other interrupts on the stack the IRQ scheduler should do
+ * nothing
+ */
+void EE_IRQ_end_instance(void)
+{
+ register EE_TID t;
+
+ t = EE_rq_queryfirst();
+
+ /* check if there is to schedule a ready task or pop a */
+ /* preempted task */
+ /* th_absdline[stk_queryfirst()] <= th_absdline[rq_queryfirst()] */
+ /* see also thendin.c */
+ if (t == EE_NIL || /* this test works also for the main task */
+ (EE_stk_queryfirst() != EE_NIL &&
+ ((EE_STIME)(EE_th_absdline[EE_stk_queryfirst()] - EE_th_absdline[t]) <= 0
+ || EE_sys_ceiling >= EE_th_ready_prio[t]))) {
+ /* we have to schedule an interrupted task (already on */
+ /* the stack!!!) the state is already STACKED! */
+ EE_hal_IRQ_stacked(EE_stk_queryfirst());
+ /* never returns !!! */
+ } else {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[t] & EE_WASSTACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[t];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_STACKED;
+#endif
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_IRQ_stacked(EE_rq2stk_exchange());
+ } else {
+ EE_hal_IRQ_ready(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_IRQ_ready(EE_rq2stk_exchange());
+#endif
+ }
+
+ /*
+ * NOOOOOOOO!!!!
+ * hal_IRQ_end_primitive();
+ */
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_mutex.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_mutex.c
new file mode 100644
index 0000000..5679c50
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_mutex.c
@@ -0,0 +1,144 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ * CVS: $Id: ee_mutex.c,v 1.2 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_edf_GetResource(EE_TYPERESOURCE m)
+{
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ register EE_FREG np_flags;
+ np_flags = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ /* mask off the MSB, that indicates whether this is a global or a
+ * local resource */
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ EE_resource_oldceiling[tmp] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[tmp];
+
+ /* if this is a global resource, lock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_in(tmp);
+ }
+
+#else
+
+ EE_resource_oldceiling[m] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[m];
+
+#endif
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif /* __PRIVATE_GETRESOURCE__ */
+
+
+
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_edf_ReleaseResource(EE_TYPERESOURCE m)
+{
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ register EE_TID t;
+
+ register EE_FREG np_flags;
+ np_flags = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ /* if this is a global resource, unlock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_out(tmp);
+ }
+
+ EE_sys_ceiling = EE_resource_oldceiling[tmp];
+#else
+ EE_sys_ceiling = EE_resource_oldceiling[m];
+#endif
+
+ /* this code is similar to the EE_edf_Schedule()!!! */
+ t = EE_rq_queryfirst();
+ /* check if there is a preemption */
+ if (t != EE_NIL &&
+ (EE_STIME)(EE_th_absdline[EE_stk_queryfirst()] -
+ EE_th_absdline[t]) > 0
+ && EE_sys_ceiling < EE_th_ready_prio[t]) {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[t] & EE_WASSTACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[t];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_STACKED;
+#endif
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+ }
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+
+#endif /* __PRIVATE_RELEASERESOURCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqexchg.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqexchg.c
new file mode 100644
index 0000000..c0e540f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqexchg.c
@@ -0,0 +1,63 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_rqexchg.c,v 1.1.1.1 2007/04/10 12:53:52 claudio Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+EE_TID EE_rq2stk_exchange(void)
+{
+ EE_TID temp;
+
+ temp = EE_rqfirst;
+
+ /* extract the first task from the ready queue */
+ EE_rqfirst = EE_th_next[temp];
+ /* insert the extracted task on the topo of the stack */
+ EE_th_next[temp] = EE_stkfirst;
+ EE_stkfirst = temp;
+
+ return temp;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqinsert.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqinsert.c
new file mode 100644
index 0000000..2316151
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_rqinsert.c
@@ -0,0 +1,76 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_rqinsert.c,v 1.4 2008/04/28 14:34:55 francesco Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_INSERT__
+
+/* this function inserts a task into the ready queue */
+void EE_rq_insert(EE_TID t)
+{
+ EE_TIME prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_rq_queryfirst();
+ prio = EE_th_absdline[t];
+
+ while ((q != EE_NIL) &&
+ (EE_STIME)(prio - EE_th_absdline[q]) >= 0
+ ) {
+ p = q;
+ q = EE_th_next[q];
+ }
+
+ if (p != EE_NIL) {
+ EE_th_next[p] = t;
+ } else {
+ EE_rqfirst = t;
+ }
+
+ EE_th_next[t] = q;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_schedule.c
new file mode 100644
index 0000000..7f6ddc0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_schedule.c
@@ -0,0 +1,98 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ * CVS: $Id: ee_schedule.c,v 1.2 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SCHEDULER__
+void EE_edf_Schedule(void)
+{
+ register EE_TID tmp_rq;
+ register EE_TID tmp_stk;
+
+ register EE_FREG np_flags;
+
+ np_flags = EE_hal_begin_nested_primitive();
+
+ tmp_rq = EE_rq_queryfirst();
+ tmp_stk = EE_stk_queryfirst();
+
+ /* Check if there is a preemption.
+ * The check is done as the task would not hold any resource. */
+ if (tmp_stk == EE_NIL ||/* main task! */
+ (tmp_rq != EE_NIL
+ && (EE_STIME)(EE_th_absdline[tmp_stk] - EE_th_absdline[tmp_rq]) > 0
+ && EE_th_ready_prio[tmp_stk] < EE_th_ready_prio[tmp_rq])) {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[tmp_rq] & EE_WASSTACKED;
+#endif
+
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[tmp_stk];
+ EE_sys_ceiling |= EE_th_ready_prio[tmp_stk];
+ EE_sys_ceiling |= EE_th_dispatch_prio[tmp_rq];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[tmp_rq] = EE_STACKED;
+#endif
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+
+ EE_sys_ceiling &= ~EE_th_ready_prio[tmp_stk];
+ EE_sys_ceiling |= EE_th_dispatch_prio[tmp_stk];
+ }
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thact.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thact.c
new file mode 100644
index 0000000..92deb3e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thact.c
@@ -0,0 +1,127 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ * CVS: $Id: ee_thact.c,v 1.2 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_ACTIVATETASK__
+
+void EE_edf_ActivateTask(EE_TID t)
+{
+ register EE_TID tmp_rq;
+ register EE_TID tmp_stk;
+ register EE_FREG flag;
+ int rn_ret_val;
+
+#ifdef __RN_TASK__
+ if (t & EE_REMOTE_TID) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1;
+ /* forward the request to another CPU whether the task do
+ * not become to the current CPU */
+ rn_ret_val = EE_rn_send(t & ~EE_REMOTE_TID, EE_RN_TASK, par);
+ } else {
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (EE_th_nact[t] == 0) {
+ /* compute the deadline */
+ EE_th_absdline[t] = EE_hal_gettime() + EE_th_reldline[t];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_READY;
+#endif
+
+ EE_rq_insert(t);
+ }
+
+ /* activate the task avoiding the counter wraparound */
+ if (EE_th_nact[t] != EE_MAX_NACT) {
+ EE_th_nact[t]++;
+ }
+
+ /* check if there is a preemption */
+ if (!EE_hal_get_IRQ_nesting_level()) {
+ tmp_rq = EE_rq_queryfirst();
+ tmp_stk = EE_stk_queryfirst();
+
+ if (tmp_stk == EE_NIL ||/* main task! */
+ (tmp_rq != EE_NIL
+ && (EE_STIME)(EE_th_absdline[tmp_stk] - EE_th_absdline[tmp_rq]) > 0
+ && EE_sys_ceiling < EE_th_ready_prio[tmp_rq])) {
+ /* we have to schedule a ready task (that maybe is different
+ * from the task we have just activated) */
+#if defined(__MULTI__)
+ register int wasstacked;
+
+ wasstacked = EE_th_status[tmp_rq] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[tmp_rq] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[tmp_rq];
+
+#if defined(__MULTI__)
+ if (wasstacked) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+ }
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+#ifdef __RN_TASK__
+}
+#endif
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thendin.c
new file mode 100644
index 0000000..de5e8ea
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/edf/src/ee_thendin.c
@@ -0,0 +1,121 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_thendin.c,v 1.2 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+void EE_thread_end_instance(void)
+{
+ EE_TID current;
+
+ current = EE_stk_queryfirst();
+
+ /* decrease the pending activations... ready or stacked => (nact>0) */
+ EE_th_nact[current]--;
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ /* The task state switch from STACKED TO READY because it end its
+ * instance. Note that status=READY and nact=0 ==>> the task is
+ * suspended!!! */
+ EE_th_status[current] = EE_READY;
+#endif
+
+ /* reset the task priority bit in the system_ceiling */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+
+ /* extract the task from the stk data structure */
+ EE_stk_getfirst();
+
+ if (EE_th_nact[current] > 0) {
+ /* compute the deadline */
+ EE_th_absdline[current] = EE_hal_gettime() + EE_th_reldline[current];
+
+ /* there are pending activations... */
+ /* we have to reinsert the task into the ready queue before rescheduling!!! */
+ EE_rq_insert(current);
+ }
+
+ /* check if there is to schedule a ready task or pop a preempted task */
+ /* th_absdline[stk_queryfirst()] <= th_absdline[rq_queryfirst()] */
+ /* see also irq_sched.c */
+ if (EE_rq_queryfirst() == EE_NIL || /* note that this test work also for the main task! */
+ (EE_stk_queryfirst() != EE_NIL &&
+ (
+ (EE_STIME)(EE_th_absdline[EE_stk_queryfirst()] -
+ EE_th_absdline[EE_rq_queryfirst()]) <= 0
+ || EE_sys_ceiling >= EE_th_ready_prio[EE_rq_queryfirst()]
+ )
+ )
+ ) {
+ /* we have to schedule an interrupted task (already on the stack!!!) */
+ /* the state is already STACKED! */
+ EE_hal_endcycle_stacked(EE_stk_queryfirst());
+ /* never returns !!! */
+ } else {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[EE_rq_queryfirst()] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[EE_rq_queryfirst()] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[EE_rq_queryfirst()];
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_endcycle_stacked(EE_rq2stk_exchange());
+ } else {
+ EE_hal_endcycle_ready(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_endcycle_ready(EE_rq2stk_exchange());
+#endif
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/fp/cfg/cfg.mk
new file mode 100644
index 0000000..844f9e6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/cfg/cfg.mk
@@ -0,0 +1,56 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.9 2006/12/03 22:04:56 pj Exp $
+
+ifeq ($(call iseeopt, __FP__), yes)
+EE_SRCS += pkg/kernel/fp/src/ee_irqsc.c
+EE_SRCS += pkg/kernel/fp/src/ee_rqexchg.c
+EE_SRCS += pkg/kernel/fp/src/ee_rqinsert.c
+EE_SRCS += pkg/kernel/fp/src/ee_schedule.c
+EE_SRCS += pkg/kernel/fp/src/ee_thact.c
+EE_SRCS += pkg/kernel/fp/src/ee_thendin.c
+
+ ifneq ($(call iseeopt, __FP_NO_RESOURCE__), yes)
+ EE_SRCS += pkg/kernel/fp/src/ee_mutex.c
+ endif
+
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_api.h
new file mode 100644
index 0000000..0eb5ffa
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_api.h
@@ -0,0 +1,71 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ * CVS: $Id: ee_api.h,v 1.7 2006/12/03 22:04:56 pj Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_FP_EE_API__
+#define __INCLUDE_KERNEL_FP_EE_API__
+
+
+#ifdef __FP__
+
+#ifndef Schedule
+#define Schedule EE_fp_Schedule
+#endif
+
+#ifndef ActivateTask
+#define ActivateTask EE_fp_ActivateTask
+#endif
+
+#ifndef GetResource
+#define GetResource EE_fp_GetResource
+#endif
+
+#ifndef ReleaseResource
+#define ReleaseResource EE_fp_ReleaseResource
+#endif
+
+#endif /* __FP__ */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_fp_common.h b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_fp_common.h
new file mode 100644
index 0000000..1d02d24
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_fp_common.h
@@ -0,0 +1,126 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/*
+ * Author: 2001,2002 Paolo Gai
+ *
+ * CVS: $Id: ee_common.h,v 1.5 2006/12/03 22:04:56 pj Exp $
+ */
+
+#ifndef __INCLUDE_FP_COMMON_H__
+#define __INCLUDE_FP_COMMON_H__
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* invalid TID */
+#define EE_NIL ((EE_TID)-1)
+
+/* Maximum number of pending activations - see below */
+
+/* Task statuses */
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+/* This is needed for initialization purposes
+ * in the source code generated by RT-Druid
+ */
+#define EE_READY 1
+#endif
+
+/*************************************************************************
+* Kernel Types
+*************************************************************************/
+
+/* priority type */
+#ifndef EE_TYPEPRIO
+#define EE_TYPEPRIO EE_UREG
+#endif
+
+/* status type */
+#ifndef EE_TYPESTATUS
+#define EE_TYPESTATUS EE_UREG
+#endif
+
+/* pending activation type */
+#ifndef EE_TYPENACT
+#define EE_TYPENACT EE_UREG
+#endif
+
+/* Maximum number of pending activations */
+#ifndef EE_MAX_NACT
+#define EE_MAX_NACT ((EE_UREG)-1)
+#endif
+
+/* Resource ID type */
+#ifndef EE_TYPERESOURCE
+#define EE_TYPERESOURCE EE_UREG
+#endif
+
+
+/*************************************************************************
+* Kernel Variables
+*************************************************************************/
+
+/* ROM */
+extern const EE_TYPEPRIO EE_th_ready_prio[]; /* ready priority (for preemption) */
+extern const EE_TYPEPRIO EE_th_dispatch_prio[]; /* dispatch priority (when running) */
+#ifndef __FP_NO_RESOURCE__
+extern const EE_TYPEPRIO EE_resource_ceiling[]; /* resource ceiling */
+#endif
+
+/* RAM */
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+extern EE_TYPESTATUS EE_th_status[]; /* task status (Init: 0) */
+#endif
+
+extern EE_TYPENACT EE_th_nact[]; /* pending activations (Init: 0) */
+extern EE_TID EE_th_next[]; /* next task in queue (Init: EE_NIL) */
+extern EE_TYPEPRIO EE_sys_ceiling; /* system ceiling (Init: 0)*/
+#ifndef __FP_NO_RESOURCE__
+extern EE_TYPEPRIO EE_resource_oldceiling[]; /* old resource ceiling */
+#endif
+/* The first task into the ready queue */
+extern EE_TID EE_rqfirst; /* Init: EE_NIL */
+
+/* The first stacked task */
+extern EE_TID EE_stkfirst; /* Init: EE_NIL */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_internal.h
new file mode 100644
index 0000000..929b736
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_internal.h
@@ -0,0 +1,136 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * CVS: $Id: ee_internal.h,v 1.7 2006/05/14 17:49:02 pj Exp $
+ */
+
+#ifndef __INCLUDE_FP_INTERNAL_H__
+#define __INCLUDE_FP_INTERNAL_H__
+
+#include "kernel/fp/inc/ee_fp_common.h"
+#include "kernel/fp/inc/ee_irq.h"
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* Task statuses:
+ * In general, a task status is needed for two reasons:
+ * - for debug purposes,
+ *
+ * - and, if used with a Multistack HAL, for storing a flag that let
+ * the kernel know if the task has some space allocated on its stack.
+ */
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+#if 0 /* defined in ee_common.h */
+#define EE_READY 1 in ee_common.h
+#endif /* 0 - defined in ee_common.h */
+#define EE_STACKED 2
+
+/* used by semaphores and blocking primitives in general */
+#define EE_BLOCKED 4
+
+#if defined(__MULTI__)
+/* used to know if a task has some space allocated on its stack */
+#define EE_WASSTACKED 8
+#endif
+
+#endif
+
+
+
+/*************************************************************************
+* System functions
+*************************************************************************/
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+void EE_thread_end_instance(void);
+#endif
+
+/*************************************************************************
+* Internal Queue management functions
+*************************************************************************/
+
+/* return the first ready task without extracting it */
+#ifndef __PRIVATE_RQ_QUERYFIRST__
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst(void)
+{
+ return EE_rqfirst;
+}
+#endif
+
+/* return the first stacked task (the running task) without extracting it */
+#ifndef __PRIVATE_STK_QUERYFIRST__
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void)
+{
+ return EE_stkfirst;
+}
+#endif
+
+/* extract the running task from the stack */
+#ifndef __PRIVATE_STK_GETFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_getfirst(void)
+{
+ EE_stkfirst = EE_th_next[EE_stkfirst];
+}
+#endif
+
+/* insert a task into the stack data structures */
+#ifndef __PRIVATE_STK_INSERTFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_insertfirst(EE_TID t)
+{
+ EE_th_next[t] = EE_stkfirst;
+ EE_stkfirst = t;
+}
+#endif
+
+/* insert a task into the ready queue */
+#ifndef __PRIVATE_RQ_INSERT__
+void EE_rq_insert(EE_TID t);
+#endif
+
+/* put the first ready task into the stack */
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+EE_TID EE_rq2stk_exchange(void);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_irq.h
new file mode 100644
index 0000000..fb0f87f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_irq.h
@@ -0,0 +1,56 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2012 Errico Guidieri
+ */
+
+#ifndef INCLUDE_FP_IRQ_H__
+#define INCLUDE_FP_IRQ_H__
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+void EE_IRQ_end_instance(void);
+#endif
+
+/* No ORTI support for the FP kernel */
+#define EE_ORTI_get_runningisr2() (NULL)
+#define EE_ORTI_set_runningisr2(isr2) ((void)0)
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_kernel.h
new file mode 100644
index 0000000..32f56de
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/inc/ee_kernel.h
@@ -0,0 +1,95 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001,2002 Paolo Gai
+ *
+ * CVS: $Id: ee_kernel.h,v 1.10 2006/12/05 21:18:57 pj Exp $
+ */
+
+#ifndef __INCLUDE_FP_KERN_H__
+#define __INCLUDE_FP_KERN_H__
+
+#include "kernel/fp/inc/ee_fp_common.h"
+
+/*************************************************************************
+* Public Kernel Types and Constants
+*************************************************************************/
+
+#define INVALID_TASK EE_NIL
+
+typedef EE_TID TaskType;
+typedef EE_TYPERESOURCE ResourceType;
+
+
+/*************************************************************************
+* Kernel Primitives
+*************************************************************************/
+
+
+/* This macros are used to define a task */
+#define DeclareTask(t) void Func##t(void)
+#define TASK(t) void Func##t(void)
+
+
+/* This primitive activates a task once and then execute the
+ * preemption test */
+#ifndef __PRIVATE_ACTIVATETASK__
+void EE_fp_ActivateTask(TaskType t);
+#endif
+
+#ifndef __PRIVATE_SCHEDULER__
+void EE_fp_Schedule(void);
+#endif
+
+
+#ifndef __FP_NO_RESOURCE__
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_fp_GetResource(ResourceType m);
+#endif
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_fp_ReleaseResource(ResourceType m);
+#endif
+
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_irqsc.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_irqsc.c
new file mode 100644
index 0000000..53a5196
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_irqsc.c
@@ -0,0 +1,88 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ * CVS: $Id: ee_irqsc.c,v 1.3 2006/05/14 17:49:02 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allow IRQ nesting the C_end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the stack
+ * - if there are other interrupts on the stack the IRQ end_instance should do nothing
+ */
+void EE_IRQ_end_instance(void)
+{
+ register EE_TID t;
+
+ t = EE_rq_queryfirst();
+ if ((t != EE_NIL) && (EE_sys_ceiling < EE_th_ready_prio[t])) {
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[t] & EE_WASSTACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[t];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_STACKED;
+#endif
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_IRQ_stacked(EE_rq2stk_exchange());
+ } else {
+ EE_hal_IRQ_ready(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_IRQ_ready(EE_rq2stk_exchange());
+#endif
+ } else {
+ EE_hal_IRQ_stacked(EE_stk_queryfirst());
+ }
+}
+
+#endif /* __PRIVATE_IRQ_END_INSTANCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_mutex.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_mutex.c
new file mode 100644
index 0000000..fb502a5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_mutex.c
@@ -0,0 +1,142 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ * CVS: $Id: ee_mutex.c,v 1.5 2006/12/03 22:04:56 pj Exp $
+ */
+
+#include "ee_internal.h"
+#include "../inc/ee_kernel.h"
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_fp_GetResource(ResourceType m)
+{
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ register EE_FREG np_flags;
+ np_flags = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ /* mask off the MSB, that indicates whether this is a global or a
+ * local resource */
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ EE_resource_oldceiling[tmp] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[tmp];
+
+ /* if this is a global resource, lock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_in((EE_TYPESPIN)tmp);
+ }
+
+#else
+
+ EE_resource_oldceiling[m] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[m];
+
+#endif
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif /* __PRIVATE_GETRESOURCE__ */
+
+
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_fp_ReleaseResource(ResourceType m)
+{
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ register EE_TID t;
+
+ register EE_FREG np_flags;
+ np_flags = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ /* if this is a global resource, unlock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_out((EE_TYPESPIN)tmp);
+ }
+
+ EE_sys_ceiling = EE_resource_oldceiling[tmp];
+#else
+ EE_sys_ceiling = EE_resource_oldceiling[m];
+#endif
+
+ /* The following code is the same as the code contained into schedule.c! */
+
+ t = EE_rq_queryfirst();
+ /* check if there is a preemption */
+ if (t != EE_NIL) {
+ if (EE_sys_ceiling < EE_th_ready_prio[t]) {
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[t] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[t];
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+ }
+ }
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif /* __PRIVATE_RELEASERESOURCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqexchg.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqexchg.c
new file mode 100644
index 0000000..6c216c1
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqexchg.c
@@ -0,0 +1,63 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_rqexchg.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+EE_TID EE_rq2stk_exchange(void)
+{
+ EE_TID temp;
+
+ temp = EE_rqfirst;
+
+ /* extract the first task from the ready queue */
+ EE_rqfirst = EE_th_next[temp];
+ /* insert the extracted task on the topo of the stack */
+ EE_th_next[temp] = EE_stkfirst;
+ EE_stkfirst = temp;
+
+ return temp;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqinsert.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqinsert.c
new file mode 100644
index 0000000..e2b433a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_rqinsert.c
@@ -0,0 +1,72 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_rqinsert.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_INSERT__
+/* this function inserts a task into the ready queue */
+void EE_rq_insert(EE_TID t)
+{
+ EE_TYPEPRIO prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_rqfirst;
+ prio = EE_th_ready_prio[t];
+
+ while ((q != EE_NIL) && (prio <= EE_th_ready_prio[q])) {
+ p = q;
+ q = EE_th_next[q];
+ }
+
+ if (p != EE_NIL) {
+ EE_th_next[p] = t;
+ } else {
+ EE_rqfirst = t;
+ }
+
+ EE_th_next[t] = q;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_schedule.c
new file mode 100644
index 0000000..793bca6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_schedule.c
@@ -0,0 +1,96 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_schedule.c,v 1.6 2006/12/03 22:04:56 pj Exp $
+ */
+
+#include "ee_internal.h"
+#include "../inc/ee_kernel.h"
+
+#ifndef __PRIVATE_SCHEDULER__
+
+void EE_fp_Schedule(void)
+{
+ register EE_TID t, current;
+
+ register EE_FREG np_flags;
+
+ np_flags = EE_hal_begin_nested_primitive();
+
+ t = EE_rq_queryfirst();
+
+ if (t != EE_NIL) {
+ current = EE_stk_queryfirst();
+ if (EE_th_ready_prio[current] < EE_th_ready_prio[t]) {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[t] & EE_WASSTACKED;
+#endif
+
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+ EE_sys_ceiling |= EE_th_ready_prio[current];
+ EE_sys_ceiling |= EE_th_dispatch_prio[t];
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_STACKED;
+#endif
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+
+ EE_sys_ceiling &= ~EE_th_ready_prio[current];
+ EE_sys_ceiling |= EE_th_dispatch_prio[current];
+ }
+ }
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thact.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thact.c
new file mode 100644
index 0000000..0c0aed2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thact.c
@@ -0,0 +1,122 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001-2002 Paolo Gai
+ *
+ * CVS: $Id: ee_thact.c,v 1.8 2006/12/03 22:04:56 pj Exp $
+ */
+
+#include "ee_internal.h"
+#include "../inc/ee_kernel.h"
+
+#ifndef __PRIVATE_ACTIVATETASK__
+
+void EE_fp_ActivateTask(TaskType t)
+{
+ register EE_TID tmp;
+ register EE_FREG flag;
+
+#ifdef __RN_TASK__
+ int rn_return_val;
+
+ if (EE_IS_TID_REMOTE(t)) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1U;
+ /* forward the request to another CPU whether the task do
+ * not become to the current CPU */
+ rn_return_val = EE_rn_send((EE_SREG)EE_MARK_REMOTE_TID(t),
+ EE_RN_TASK, par);
+ } else {
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* check for first activation */
+ if (EE_th_nact[t] == (EE_UREG)0U) {
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_READY;
+#endif
+ EE_rq_insert(t);
+ }
+
+ /* activate the task avoiding the counter wraparound */
+ if (EE_th_nact[t] != EE_MAX_NACT) {
+ EE_th_nact[t]++;
+ }
+
+ /* check for preemption */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ tmp = EE_rq_queryfirst();
+ if (tmp != EE_NIL) {
+ if (EE_sys_ceiling < EE_th_ready_prio[tmp]) {
+#if defined(__MULTI__)
+ register int wasstacked;
+
+ wasstacked = EE_th_status[tmp] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[tmp] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[tmp];
+
+#if defined(__MULTI__)
+ if (wasstacked) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+ }
+ }
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+#ifdef __RN_TASK__
+}
+#endif
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thendin.c
new file mode 100644
index 0000000..a28f9c0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/fp/src/ee_thendin.c
@@ -0,0 +1,111 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ *
+ * CVS: $Id: ee_thendin.c,v 1.4 2006/01/24 10:21:14 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+void EE_thread_end_instance(void)
+{
+ EE_TID current;
+
+ current = EE_stk_queryfirst();
+
+ /* decrease the pending activations... ready or stacked => (nact>0) */
+ EE_th_nact[current]--;
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ /* The task state switches from STACKED TO READY because it ends its
+ * instance. Note that status=READY and nact=0 ==>> the task is
+ * suspended!!! */
+ EE_th_status[current] = EE_READY;
+#endif
+
+ /* reset the task priority bit in the system_ceiling */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+
+ /* extract the task from the stk data structure */
+ EE_stk_getfirst();
+
+ if (EE_th_nact[current] > 0U) {
+ /* there are pending activations... */
+ /* we have to reinsert the task into the ready queue before
+ * rescheduling!!! */
+ EE_rq_insert(current);
+ }
+
+ /* check if there is to schedule a ready task pop a preempted
+ * task */
+ if ((EE_rq_queryfirst() == EE_NIL) ||
+ (EE_sys_ceiling >= EE_th_ready_prio[EE_rq_queryfirst()])) {
+ /* we have to schedule an interrupted task (already on the
+ * stack!!!) the state is already STACKED! */
+ EE_hal_endcycle_stacked(EE_stk_queryfirst());
+ } else {
+ /* we have to schedule a ready task */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[EE_rq_queryfirst()] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[EE_rq_queryfirst()] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[EE_rq_queryfirst()];
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_endcycle_stacked(EE_rq2stk_exchange());
+ } else {
+ EE_hal_endcycle_ready(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_endcycle_ready(EE_rq2stk_exchange());
+#endif
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/README.txt b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/README.txt
new file mode 100644
index 0000000..3edad76
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/README.txt
@@ -0,0 +1,5 @@
+This directory contains an implementation of the IRIS scheduler.
+On top of this implementation, a subset of the FRSH API has been implemented.
+The API is still half the OSEK API and half the FRSH API. It will be soon harmonized.
+
+PJ
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/cfg/cfg.mk
new file mode 100644
index 0000000..9ab39e3
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/cfg/cfg.mk
@@ -0,0 +1,88 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+
+ifeq ($(call iseeopt, __FRSH__), yes)
+
+INTERNAL_FRSH_PATH := -I"$(shell cygpath -w $(PKGBASE))\\."/kernel/frsh/frsh_include
+ALLINCPATH += $(INTERNAL_FRSH_PATH)
+## New Include mechanism
+INCLUDE_PATH += $(PKGBASE)/kernel/frsh/frsh_include
+
+EE_SRCS += pkg/kernel/frsh/src/ee_cap.c
+EE_SRCS += pkg/kernel/frsh/src/ee_dlcheck.c
+EE_SRCS += pkg/kernel/frsh/src/ee_end_budget.c
+EE_SRCS += pkg/kernel/frsh/src/ee_end_recharging.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_bind.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_unbind.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_bind_utils.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_contracts.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_getvresid.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_getcontract.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_init.c
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_strerror.c
+EE_SRCS += pkg/kernel/frsh/src/ee_gettime.c
+EE_SRCS += pkg/kernel/frsh/src/ee_irq_sc.c
+EE_SRCS += pkg/kernel/frsh/src/ee_mutex.c
+EE_SRCS += pkg/kernel/frsh/src/ee_rcg_inser.c
+EE_SRCS += pkg/kernel/frsh/src/ee_rq_extract.c
+EE_SRCS += pkg/kernel/frsh/src/ee_rq_inser.c
+EE_SRCS += pkg/kernel/frsh/src/ee_schedule.c
+EE_SRCS += pkg/kernel/frsh/src/ee_thact.c
+EE_SRCS += pkg/kernel/frsh/src/ee_thendin.c
+
+
+ifeq ($(call iseeopt, __FRSH_SINGLEIRQ__), yes)
+EE_SRCS += pkg/kernel/frsh/src/ee_frsh_timers.c
+endif
+
+ifeq ($(call iseeopt, __FRSH_SYNCHOBJ__), yes)
+EE_SRCS +=pkg/kernel/frsh/src/ee_frsh_syncobj_signal.c
+EE_SRCS +=pkg/kernel/frsh/src/ee_frsh_syncobj_wait.c
+EE_SRCS +=pkg/kernel/frsh/src/ee_frsh_syncobj_waittimeout.c
+EE_SRCS +=pkg/kernel/frsh/src/ee_frsh_syncobj_wait_utils.c
+EE_SRCS +=pkg/kernel/frsh/src/ee_frsh_syncobj_timedwait.c
+endif
+
+endif
+
+
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_configuration_parameters.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_configuration_parameters.h
new file mode 100644
index 0000000..cb52115
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_configuration_parameters.h
@@ -0,0 +1,123 @@
+/* ----------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* based on previous work (FSF) done in the FIRST project */
+/* */
+/* Copyright (C) 2005 Mälardalen University, SWEDEN */
+/* Scuola Superiore S.Anna, ITALY */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* */
+/* FSF API web pages: http://marte.unican.es/fsf/docs */
+/* http://shark.sssup.it/contrib/first/docs/ */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/* ----------------------------------------------------------------------- */
+/* frsh_configuration_parameters.h */
+/* ============================================== */
+/* ******** ******* ******** ** ** */
+/* ** ///// / ** //// ** ** ////// / ** / ** */
+/* ** / ** / ** / ** / ** / ** */
+/* ******* / ******* / ********* / ********** */
+/* ** //// / ** /// ** //////// ** / ** ////// ** */
+/* ** / ** // ** / ** / ** / ** */
+/* ** / ** // ** ******** / ** / ** */
+/* // // // //////// // // */
+/* */
+/* FRSH(FRescor ScHeduler), pronounced "fresh" */
+/* ============================================== */
+
+/* This is a reduced version used for ERIKA Enterprise */
+
+#ifndef _FRSH_CONFIGURATION_PARAMETERS_H_
+#define _FRSH_CONFIGURATION_PARAMETERS_H_
+
+/* #define FRSH_ADMISSION_TEST_IS_ENABLED false */
+/* #define FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE false */
+/* #define FRSH_DISTRIBUTED_MODULE_SUPPORTED false */
+/* #define FRSH_RESOURCE_ID_DEFAULT 0 */
+/* #define FRSH_CPU_ID_DEFAULT 0 */
+/* #define FRSH_NETWORK_ID_DEFAULT 0 */
+
+/* /\** Maximum number of accepted contracts (vres) **\/ */
+/* #define FRSH_MAX_N_VRES EE_MAX_CONTRACT */
+
+/* /\** Maximum number of threads that may be scheduled by the framework **\/ */
+/* #define FRSH_MAX_N_THREADS EE_MAX_TASK */
+
+/* /\** */
+/* * Maximum number of critical sections that can be stored in a */
+/* * contract parameters object */
+/* **\/ */
+/* #define FRSH_MAX_N_CRITICAL_SECTIONS 0 */
+
+/* /\** */
+/* * Maximum number of memory areas that can be specified for a */
+/* * wite operation in a critical section */
+/* **\/ */
+/* #define FRSH_MAX_N_MEMORY_AREAS 0 */
+
+/* /\** */
+/* * Maximum number of utilization values (pairs of budget and period) */
+/* * that can be stored in a contract parameters object */
+/* **\/ */
+/* #define FRSH_MAX_N_UTILIZATION_VALUES 0 */
+
+/* /\** Number of importance levels for spare capacity allocation **\/ */
+/* #define FRSH_N_IMPORTANCE_LEVELS 0 */
+
+/**
+ * Maximum number of synchronization objects
+ **/
+#define FRSH_MAX_N_SYNCH_OBJECTS EE_MAX_SEM
+
+/* /\** Maximum number of shared objects **\/ */
+/* #define FRSH_MAX_N_SHARED_OBJECTS 0 */
+
+/* /\** Maximum number of send and receive endpoints in a single node **\/ */
+/* #define FRSH_MAX_N_ENDPOINTS 10 */
+
+
+
+#define FRSH_CONTRACT_LABEL_MAXLENGTH 15
+
+#endif /* _FRSH_CONFIGURATION_PARAMETERS_H_ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_core_types.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_core_types.h
new file mode 100644
index 0000000..581f023
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_core_types.h
@@ -0,0 +1,179 @@
+/* ----------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* based on previous work (FSF) done in the FIRST project */
+/* */
+/* Copyright (C) 2005 Mälardalen University, SWEDEN */
+/* Scuola Superiore S.Anna, ITALY */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* */
+/* FSF API web pages: http://marte.unican.es/fsf/docs */
+/* http://shark.sssup.it/contrib/first/docs/ */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/* ----------------------------------------------------------------------- */
+/* frsh_core_types.h */
+/* ============================================== */
+/* ******** ******* ******** ** ** */
+/* ** ///// / ** //// ** ** ////// / ** / ** */
+/* ** / ** / ** / ** / ** / ** */
+/* ******* / ******* / ********* / ********** */
+/* ** //// / ** /// ** //////// ** / ** ////// ** */
+/* ** / ** // ** / ** / ** / ** */
+/* ** / ** // ** ******** / ** / ** */
+/* // // // //////// // // */
+/* */
+/* FRSH(FRescor ScHeduler), pronounced "fresh" */
+/* ============================================== */
+
+/* this is a reduced version of the frsh_core_types.h as defined by
+ * the IST FRESCOR Project
+ */
+
+#ifndef FRSH_CORE_TYPES_H_
+#define FRSH_CORE_TYPES_H_
+
+#include "frsh_time_types.h"
+
+
+/** identifier of a frsh thread **/
+#define frsh_thread_id_t EE_TID
+
+
+/** thread attributes object **/
+/* typedef fosa_thread_attr_t frsh_thread_attr_t; */
+
+/**
+ * The type references a function that may become a thread's
+ * code
+ **/
+/* typedef fosa_thread_code_t frsh_thread_code_t; */
+
+
+/* EE does not handle signals */
+#define frsh_signal_t EE_UREG
+#define frsh_signal_info_t EE_UREG
+
+
+/** Kind of workload expected in vres: bounded or indeterminate **/
+typedef enum {
+ FRSH_WT_BOUNDED = 0,
+ FRSH_WT_INDETERMINATE = 1,
+ FRSH_WT_SYNCHRONIZED = 2
+} frsh_workload_t;
+
+
+#define FRSH_NULL_DEADLINE 0
+/* #define FRSH_NULL_SIGNAL 0 / * Defined at frsh_adaption.h * / */
+
+/** Negotiation status: In_progress, rejected, admitted, not_requested **/
+/* typedef enum {FRSH_RS_IN_PROGRESS, */
+/* FRSH_RS_REJECTED, */
+/* FRSH_RS_ADMITTED, */
+/* FRSH_RS_NOT_REQUESTED} frsh_renegotiation_status_t; */
+
+/**
+ * Vres Id type, that identifies a vres created to manage a given
+ * contract
+ **/
+#define frsh_vres_id_t EE_TYPECONTRACT
+
+/** Contract ressource type: processor, network, memory **/
+typedef enum {
+ FRSH_RT_PROCESSOR = 0,
+ FRSH_RT_NETWORK = 1,
+ FRSH_RT_MEMORY = 2,
+ FRSH_RT_DISK = 3,
+ FRSH_RT_FPGA = 4
+} frsh_resource_type_t;
+
+/** Ressource Id: processor_id or network_id **/
+/**********************************************/
+#define frsh_resource_id_t EE_UREG
+
+/** Kind of contract: regular, background or dummy **/
+typedef enum {
+ FRSH_CT_REGULAR = 0,
+ FRSH_CT_BACKGROUND = 1,
+ FRSH_CT_DUMMY = 2
+} frsh_contract_type_t;
+
+/* The name of this constant has been updated to have the FRSH_ prefix */
+/* typedef char frsh_contract_label_t[FRSH_CONTRACT_LABEL_MAXLENGTH + 1]; */
+
+/**
+ * Contract parameters type; it is an opaque type (i.e. the internal
+ * structure of this data type is implementation dependent). The user
+ * can access and modify the parameters of a contract only with the
+ * proper functions, and should never access the data directly.
+ **/
+#define frsh_contract_t EE_TYPECONTRACTSTRUCT
+
+
+/** List of vres **/
+/* typedef struct { */
+/* int size; */
+/* frsh_vres_id_t vres[FRSH_MAX_GROUP_OPS]; */
+/* } frsh_vres_group_t; */
+
+/** List of contracts to negotiate **/
+/* typedef struct { */
+/* int size; */
+/* frsh_contract_t contracts[FRSH_MAX_GROUP_OPS]; */
+/* } frsh_contracts_group_t; */
+
+/* typedef FRSH_GROUP_ID_T_OPAQUE frsh_group_id_t; */
+
+/**
+ * An abstract synchronization object is defined by the application.
+ * This object can be used by an application to wait for an event to
+ * arrive by invoking the frsh_sychobj_wait() operation. It
+ * can also be used to signal the event either causing a waiting
+ * vres to wake up, or the event to be queued if no vres is
+ * waiting for it.
+ **/
+/* typedef FRSH_SYNCHOBJ_HANDLE_T_OPAQUE frsh_synchobj_handle_t; */
+
+
+
+#endif /* !FRSH_CORE_TYPES_H_ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_error.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_error.h
new file mode 100644
index 0000000..8768eae
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_error.h
@@ -0,0 +1,269 @@
+/* ----------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* based on previous work (FSF) done in the FIRST project */
+/* */
+/* Copyright (C) 2005 Mälardalen University, SWEDEN */
+/* Scuola Superiore S.Anna, ITALY */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* */
+/* FSF API web pages: http://marte.unican.es/fsf/docs */
+/* http://shark.sssup.it/contrib/first/docs/ */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/* ----------------------------------------------------------------------- */
+/* frsh_error.h */
+/* ============================================== */
+/* ******** ******* ******** ** ** */
+/* ** ///// / ** //// ** ** ////// / ** / ** */
+/* ** / ** / ** / ** / ** / ** */
+/* ******* / ******* / ********* / ********** */
+/* ** //// / ** /// ** //////// ** / ** ////// ** */
+/* ** / ** // ** / ** / ** / ** */
+/* ** / ** // ** ******** / ** / ** */
+/* // // // //////// // // */
+/* */
+/* FRSH(FRescor ScHeduler), pronounced "fresh" */
+/* ============================================== */
+
+
+/* Note for ERIKA Enterprise users: This is a reduced version of the
+ * frsh_error.h file. In particular, the macros have been commented out. */
+
+
+#ifndef FRSH_ERROR_H_
+#define FRSH_ERROR_H_
+
+/**
+ * @file frsh_error.h
+ **/
+
+/**
+ * addtogroup core
+ *
+ * @{
+ **/
+
+/* Error codes */
+#define FRSH_NO_ERROR 0
+
+#define FRSH_ERR_BASE_VALUE 0x4000
+
+#define FRSH_ERR_TOO_MANY_TASKS 0x4001
+#define FRSH_ERR_BAD_ARGUMENT 0x4002
+#define FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE 0x4003
+#define FRSH_ERR_NO_RENEGOTIATION_REQUESTED 0x4004
+#define FRSH_ERR_CONTRACT_REJECTED 0x4005
+#define FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD 0x4006
+#define FRSH_ERR_NOT_BOUND 0x4007
+#define FRSH_ERR_UNKNOWN_SCHEDULED_THREAD 0x4008
+#define FRSH_ERR_NOT_CONTRACTED_VRES 0x4009
+#define FRSH_ERR_NOT_SCHEDULED_THREAD 0x400A
+#define FRSH_ERR_TOO_MANY_SERVICE_JOBS 0x400B
+#define FRSH_ERR_TOO_MANY_SYNCH_OBJS 0x400C
+#define FRSH_ERR_TOO_MANY_VRES_IN_SYNCH_OBJ 0x400D
+#define FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ 0x400E
+#define FRSH_ERR_INTERNAL_ERROR 0x400F
+#define FRSH_ERR_TOO_MANY_VRES 0x4010
+#define FRSH_ERR_INVALID_SCHEDULER_REPLY 0x4011
+#define FRSH_ERR_TOO_MANY_PENDING_REPLENISHMENTS 0x4012
+#define FRSH_ERR_SYSTEM_ALREADY_INITIALIZED 0x4013
+#define FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED 0x4014
+#define FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED 0x4015
+#define FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE 0x4016
+#define FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE 0x4017
+#define FRSH_ERR_ALREADY_BOUND 0x4018
+#define FRSH_ERR_RESOURCE_ID_INVALID 0x4019
+#define FRSH_ERR_TOO_LARGE 0x401A
+#define FRSH_ERR_BUFFER_FULL 0x401B
+#define FRSH_ERR_NO_SPACE 0x401C
+#define FRSH_ERR_NO_MESSAGES 0x401D
+#define FRSH_WRN_MODULE_NOT_SUPPORTED 0x401E
+#define FRSH_ERR_NOT_INITIALIZED 0x401F
+#define FRSH_ERR_TOO_MANY_SHARED_OBJS 0x4020
+#define FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS 0x4021
+#define FRSH_ERR_BUDGET_EXPIRED 0x4022
+#define FRSH_ERR_SHARED_OBJECT_NOT_PROTECTED 0x4023
+#define FRSH_ERR_NOT_IMPLEMENTED 0x4024
+#define FRSH_ERR_CONTRACT_TYPE_NOT_COMPATIBLE 0x4025
+#define FRSH_ERR_CAPACITY_NOT_DECREASING 0x4026
+#define FRSH_ERR_CONTRACT_LABEL_UNKNOWN 0x4027
+#define FRSH_ERR_OUT_OF_BUDGET 0x4028
+#define FRSH_ERR_ALREADY_IN_FRSH 0x4029
+
+#define FRSH_ERR_LAST_VALUE 0x4030
+
+/* #define ERROR(nn,ss) do {if(nn>FRSH_ERR_BASE_VALUE) my_frsh_strerror(nn, ss); else perror(ss); exit (nn);} while (0) */
+
+/* for size_t */
+#include <string.h>
+
+int frsh_strerror(int error,
+ char *message,
+ size_t size);
+/* void my_frsh_strerror(int error, char *sss); */
+
+/**
+ * This str_helper is needed to ensure argument expansion,
+ * see http://www.iar.com/p180591/p180591_eng.php
+ **/
+/* #define STR_HELPER(x) #x */
+
+/**
+ * PERROR_FRESCOR
+ *
+ * This macro checks the given error number and composes a messages accordingly.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+/* #define PERROR_FRESCOR(_nn_,_ss_) do { \ */
+/* \ */
+/* char error_string[1024]; \ */
+/* \ */
+/* sprintf(error_string, "File: %s, in function %s at line %d, error %d: %s\n", __FILE__, __FUNCTION__, __LINE__, (_nn_), _ss_); \ */
+/* \ */
+/* if( (_nn_)>FRSH_ERR_BASE_VALUE ) { \ */
+/* my_frsh_strerror( (_nn_), error_string); \ */
+/* } else { \ */
+/* perror(error_string); \ */
+/* } \ */
+/* } while(0) */
+
+
+
+/**
+ * PERROR_AND_RETURN
+ *
+ * Macro that displays an error code and message and then returns from
+ * the current function
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+/* #define PERROR_AND_RETURN(nn,ss) do { \ */
+/* PERROR_FRESCOR(nn, ss); \ */
+/* return (nn); \ */
+/* } while (0) */
+
+
+
+
+/**
+ * PERROR_AND_EXIT
+ *
+ * Macro that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+/* #define PERROR_AND_EXIT(nn,ss) do { \ */
+/* PERROR_FRESCOR(nn,ss); \ */
+/* exit(nn); \ */
+/* } while (0) */
+
+
+/**
+ * PRW: Perror and Return Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and returns from the function.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ * case.
+ **/
+/* #define PRW(funccall) do { \ */
+/* if ( (terror = funccall ) != 0) \ */
+/* { \ */
+/* PERROR_AND_RETURN( terror, STR_HELPER(funccall) ); \ */
+/* } \ */
+/* } while(0) */
+
+
+
+/**
+ * PXW: Perror and eXit Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and ABORTS the program.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ * case.
+ **/
+/* #define PXW(funccall) do { \ */
+/* if ( (terror = funccall ) != 0) \ */
+/* { \ */
+/* PERROR_AND_EXIT( terror, STR_HELPER(funccall) ); \ */
+/* } \ */
+/* } while(0) */
+
+
+
+/**
+ * PERROR_KERN_AND_EXIT
+ *
+ * Function that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+/* #define PERROR_KERN_AND_EXIT(nn, ss) do { \ */
+/* errno = errno ? errno : (nn); \ */
+/* kern_printf(ss); \ */
+/* exit(nn); \ */
+/* } while (0) */
+
+
+
+
+/*}*/
+
+#endif /* !FRSH_ERROR_H_ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_time_types.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_time_types.h
new file mode 100644
index 0000000..79fc99a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/frsh_time_types.h
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* based on previous work (FSF) done in the FIRST project */
+/* */
+/* Copyright (C) 2005 Mälardalen University, SWEDEN */
+/* Scuola Superiore S.Anna, ITALY */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* */
+/* FSF API web pages: http://marte.unican.es/fsf/docs */
+/* http://shark.sssup.it/contrib/first/docs/ */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/* ----------------------------------------------------------------------- */
+/* frsh_spare_capacity_types.h */
+/* ============================================== */
+/* ******** ******* ******** ** ** */
+/* ** ///// / ** //// ** ** ////// / ** / ** */
+/* ** / ** / ** / ** / ** / ** */
+/* ******* / ******* / ********* / ********** */
+/* ** //// / ** /// ** //////// ** / ** ////// ** */
+/* ** / ** // ** / ** / ** / ** */
+/* ** / ** // ** ******** / ** / ** */
+/* // // // //////// // // */
+/* */
+/* FRSH(FRescor ScHeduler), pronounced "fresh" */
+/* ============================================== */
+
+#ifndef FRSH_TIME_TYPES_H_
+#define FRSH_TIME_TYPES_H_
+
+#define frsh_abs_time_t EE_TYPEABSDLINE
+#define frsh_rel_time_t EE_TYPERELDLINE
+
+
+#endif /* !FRSH_TIME_TYPES_H_ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/readme.txt b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/readme.txt
new file mode 100644
index 0000000..e8c97e6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/frsh_include/readme.txt
@@ -0,0 +1,5 @@
+This directory is typically not present in the standard structure of
+an ERIKA Enterprise package.
+
+It basically stores the include files specified in the IST FRESCOR
+WP2_D-AC2v2 deliverable.
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_api.h
new file mode 100644
index 0000000..e10f530
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_api.h
@@ -0,0 +1,149 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ * CVS: $Id: ee_api.h,v 1.4 2008/07/16 09:46:12 francesco Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_FRSH_EE_API__
+#define __INCLUDE_KERNEL_FRSH_EE_API__
+
+#ifdef __FRSH__
+
+#ifndef Schedule
+#define Schedule EE_frsh_Schedule
+#endif
+
+#ifndef ActivateTask
+#define ActivateTask EE_frsh_thread_activate
+#endif
+
+#ifndef GetResource
+#define GetResource EE_frsh_GetResource
+#endif
+
+#ifndef ReleaseResource
+#define ReleaseResource EE_frsh_ReleaseResource
+#endif
+
+#ifndef EE_sys_gettime
+#ifdef __TIME_SUPPORT__
+#define EE_sys_gettime EE_frsh_sys_gettime
+#endif
+#endif
+
+#ifndef GetTime
+#ifdef __TIME_SUPPORT__
+#define GetTime EE_frsh_sys_gettime
+#endif
+#endif
+
+
+/* FRSH specific API */
+
+#ifndef frsh_init
+#define frsh_init EE_frsh_init
+#endif
+
+#ifndef frsh_strerror
+#define frsh_strerror EE_frsh_strerror
+#endif
+
+#ifndef frsh_contract_get_basic_params
+#define frsh_contract_get_basic_params EE_frsh_contract_get_basic_params
+#endif
+
+#ifndef frsh_contract_get_timing_reqs
+#define frsh_contract_get_timing_reqs EE_frsh_contract_get_timing_reqs
+#endif
+
+#ifndef frsh_thread_bind
+#define frsh_thread_bind EE_frsh_BindTask
+#endif
+
+#ifndef frsh_thread_unbind
+#define frsh_thread_unbind EE_frsh_UnbindTask
+#endif
+
+#ifndef frsh_thread_get_vres_id
+#define frsh_thread_get_vres_id EE_frsh_thread_get_vres_id
+#endif
+
+#ifndef frsh_vres_get_contract
+#define frsh_vres_get_contract EE_frsh_vres_get_contract
+#endif
+
+#ifndef frsh_synchobj_signal
+#define frsh_synchobj_signal EE_frsh_synchobj_signal
+#endif
+
+#ifndef frsh_synchobj_wait
+#define frsh_synchobj_wait EE_frsh_synchobj_wait
+#endif
+
+#ifndef frsh_synchobj_wait_with_timeout
+#define frsh_synchobj_wait_with_timeout EE_frsh_synchobj_wait_with_timeout
+#endif
+
+#ifndef frsh_timed_wait
+#define frsh_timed_wait EE_frsh_timed_wait
+#endif
+
+#ifndef frsh_config_is_admission_test_enabled
+#define frsh_config_is_admission_test_enabled EE_frsh_config_is_admission_test_enabled
+#endif
+
+#ifndef frsh_vres_get_remaining_budget
+#define frsh_vres_get_remaining_budget EE_frsh_vres_get_remaining_budget
+#endif
+
+#ifndef frsh_vres_get_usage
+#define frsh_vres_get_usage EE_frsh_vres_get_usage
+#endif
+
+#ifndef frsh_vres_get_budget_and_period
+#define frsh_vres_get_budget_and_period EE_frsh_vres_get_budget_and_period
+#endif
+
+
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_common.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_common.h
new file mode 100644
index 0000000..e57a4a3
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_common.h
@@ -0,0 +1,397 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_common.h,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#ifndef __INCLUDE_FRSH_COMMON_H__
+#define __INCLUDE_FRSH_COMMON_H__
+
+
+/*************************************************************************
+ * Note
+ *************************************************************************
+ *
+ * Some details about the FRSH implementation:
+ *
+ * FRSH uses a stacked queue.
+ *
+ * The stacked queue contains all the tasks that has been executed for
+ * some time, and that have locked a resource
+ *
+ * Note that if a task has been executed it must have been that the task
+ * preemption level was greater than the system ceiling, and that their
+ * absolute deadline was earlier than the task on the top of the stacked
+ * queue.
+ *
+ * This also means that the stacked queue is by construction ordered by
+ * increasing deadlines.
+ *
+ * When a task is preempted and it has a locked resource, then the task
+ * ends up in the stacked queue, otherwise it ends up into the ready
+ * queue.
+ *
+ * In fact, when activating a task the ActivateTask does a preemption
+ * Check between the running task and the first task in the ready queue,
+ * including the preeemption level.
+ *
+ * When a task terminates, we suppose that NO RESOURCES are locked. If
+ * the task has a nact>0 the task is inserted in the ready queue (there
+ * are no resources locked), and the next running task is chosen between
+ * the ready and the stacked queue. The task on the ready queue wins if
+ * it has a deadline earlier than the task on the stacked queue and if it
+ * has a preemption level greater than the system ceiling (the system
+ * ceiling subsumes in a single value all the ceilings of the locked
+ * resources by the tasks in the stacked queue)
+ *
+ * If a task to execute is chosen from the stacked queue, then the task
+ * is removed from the stacked queue and it is put into exec.
+ */
+
+/*
+ * Please note the following difference between (FP, EDF) and FRSH. FRSH
+ * does a distinction between exec and stkfirst. the rationale is that
+ * exec may not influence the system ceiling (for example, the running
+ * task did not lock any resource). The stacked queue maintains the
+ * meaning of containing all the tasks that modified the system ceiling
+ * (that is, that locked a resource).
+ *
+ * There is a need to have a separate stacked queue because if the top
+ * ready task fails the preemption test at the end of a task, then the
+ * running task must become the highest priority task (the one with the
+ * earliest deadline) among those who modified the system ceiling.
+ *
+ * Finally note that since FP and EDF implements preemption thresholds,
+ * all the tasks at the end make a modification to the system ceiling,
+ * and then the exec task can coincide without problems to the first
+ * stacked task.
+ */
+
+/*
+ * Notes on thread and VRES status and parameters
+ * ----------------------------------------------
+ * The kernel makes a distinction between the tasks and VRES
+ *
+ * Tasks are the executing entities. All queues in the system queue the
+ * tasks as executing entities.
+ *
+ * Tasks have allocated a VRES. the VRES is the container which controls
+ * when a task can be executed. the parameters of a VRES are:
+ * - period
+ * - budget
+ * - absolute deadline
+ * - active
+ * - status
+ *
+ * Please note that the VRES status and the task status are distinct
+ * - the VRES status maps the capability of a VRES to execute
+ * - the task status maps the status of the task
+ *
+ * Example: a task may block on a semaphore for an indefinite time. while
+ * the status becomes BLOCKED, the VRES status is initially Active, then
+ * after a while it will become Inactive, and after a long time it will
+ * be set to freezed.
+ */
+
+/*
+ * Notes on the freezed state
+ * --------------------------
+ * The FRSH Kernel is using a timer representation embedded in a timer
+ * value. All times in the system are relative to the value of the
+ * current timer.
+ *
+ * When a task stop executing for some time, its deadline is no more
+ * updated, and it will tend to go far in the past. Since the time
+ * reference is relative to the current timer value, it may happen
+ * after some time (half the lifetime of the timer), that this deadline
+ * in the past becomes a deadline "in the future". At that point, all
+ * the deadline update strategies will fail.
+ *
+ * To avoid that, the system have to periodically "take a look" at
+ * all the task deadlines to see if they go too much in the past
+ * (if a deadline goes in the past it measn the task has not executed
+ * for a while). If that happens, then the function
+ * EE_frsh_deadlinecheck will set these VRES to "freezed", and then
+ * when the task wuill be activated again a fresh deadline will be
+ * assigned (done into EE_frsh_updatecapacity.
+ * -- end note */
+
+
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* invalid TID */
+#define EE_NIL ((EE_TID)-1)
+
+/* invalid TID, used in the VRES task field, to mean that the VRES has
+ * been binded BUT the binding has been deferred. Note that only VRES
+ * which are inactive/freezed may have this value */
+#define EE_TID_DEFERRED ((EE_TID)EE_MAX_TASK)
+
+/* invalid VRES, used for tasks without vres binded to them*/
+#define EE_VRES_NIL ((EE_TYPECONTRACT)-1)
+
+/* placeholder to say that the deferred VRES attached to a task has
+ * been unbound when a task is safely unbound, its vres is
+ * EE_VRES_NIL. We need this value when deferring the bind at the end
+ * of a critical section. This enable to distinguish when there is
+ * nothing to do (EE_VRES_NIL), the VRES have to be unbound
+ * (EE_VRES_UNBOUND), or if there is a new VRES (one of the valid
+ * values)
+ */
+#define EE_VRES_UNBOUND ((EE_TYPECONTRACT)EE_MAX_CONTRACT)
+
+
+/* VRES statuses */
+
+#define EE_VRES_FREEZED 0
+#define EE_VRES_INACTIVE 1
+#define EE_VRES_ACTIVE 2
+#define EE_VRES_RECHARGING 4
+
+
+/* TASK statuses */
+
+#define EE_TASK_SUSPENDED 0
+#define EE_TASK_READY 1
+#define EE_TASK_STACKED 2
+#define EE_TASK_BLOCKED 4
+#define EE_TASK_EXEC 8
+
+/* flag used to know if a task has some space allocated on its stack */
+/* WHEN CHANGING THIS WE WILL HAVE TO CHANGE THE ORTI FILE! */
+#define EE_TASK_WASSTACKED 128
+
+/*************************************************************************
+* Kernel Types
+*************************************************************************/
+
+/* priority type, used for system ceiling and preemption level */
+#ifndef EE_TYPEPRIO
+#define EE_TYPEPRIO EE_UREG
+#endif
+
+/* status type */
+#ifndef EE_TYPESTATUS
+#define EE_TYPESTATUS EE_UREG
+#endif
+
+/* relative deadline type */
+#ifndef EE_TYPERELDLINE
+#define EE_TYPERELDLINE EE_TIME
+#endif
+
+/* absolute deadline type */
+#ifndef EE_TYPEABSDLINE
+#define EE_TYPEABSDLINE EE_TIME
+#endif
+
+/* capacity type */
+#ifndef EE_TYPEBUDGET
+#define EE_TYPEBUDGET EE_STIME
+#endif
+
+/* pending activation type */
+#ifndef EE_TYPENACT
+#define EE_TYPENACT EE_UREG
+#endif
+
+/* mutex ID type */
+#ifndef EE_TYPERESOURCE
+#define EE_TYPERESOURCE EE_UREG
+#endif
+
+/* contract ID */
+#ifndef EE_TYPECONTRACT
+#define EE_TYPECONTRACT EE_SREG
+#endif
+
+/* vres ID */
+#ifndef EE_TYPEVRES
+#define EE_TYPEVRES EE_UREG
+#endif
+
+/* Contract */
+typedef struct {
+ EE_TYPEBUDGET budget;
+ EE_TYPERELDLINE period;
+ EE_TYPERELDLINE inv_proc_util;
+} EE_TYPECONTRACTSTRUCT;
+
+/* VRES */
+typedef struct {
+ EE_TYPEBUDGET budget_avail; /* available budget (initvalue 0) */
+ EE_TYPEBUDGET usage; /* overall incremental budget used by the vres (initvalue 0) */
+ EE_TYPEABSDLINE absdline; /* absolute deadline (initvalue 0) */
+ EE_TYPESTATUS status; /* status (initvalue freezing that is 0) */
+ EE_TID task; /* the task binded to the VRES */
+ EE_TYPECONTRACT next; /* next vres in the recharging queue (initvalue EE_VRES_NIL ) */
+} EE_TYPEVRESSTRUCT;
+
+/* TASK */
+typedef struct {
+ EE_TYPERELDLINE prlevel; /* task preemption level */
+ EE_TYPESTATUS status; /* task status (initvalue EE_TASK_SUSPENDED ) */
+ EE_TID next; /* next task in the queue (initvalue EE_NIL ) */
+ EE_TYPENACT nact; /* number of pending activations (initvalue 0) */
+ EE_UREG lockedcounter; /* number of locked resources (initvalue 0) */
+ EE_TYPECONTRACT vres; /* the vres linked to the task */
+ EE_TYPECONTRACT vres_deferred; /* when != EE_VRES_NIL stores the deferred VRES after a bind */
+ EE_UREG timedout; /* used with synchronization objects */
+} EE_TYPETASKSTRUCT;
+
+typedef EE_UREG bool;
+
+/*************************************************************************
+* Kernel Variables
+*************************************************************************/
+
+
+/*************
+* CONTRACTS
+*************/
+
+/* This structure contains the statically defined contractd defined into the OIL File */
+extern const EE_TYPECONTRACTSTRUCT EE_ct[];
+
+
+/*************
+* VRES
+*************/
+
+/* This structure contains all the VRES data. (initvalue 0) */
+extern EE_TYPEVRESSTRUCT EE_vres[EE_MAX_CONTRACT];
+
+
+/*************
+* TASKS
+*************/
+
+/* task data */
+extern EE_TYPETASKSTRUCT EE_th[EE_MAX_TASK];
+
+
+/*************
+* GLOBAL
+*************/
+
+/* a temporary value that stores the timer read that was done before
+ * executing a task. That value is useful for capacity accounting
+ * (initvalue: none)
+ */
+extern EE_TIME EE_last_time;
+
+/* system ceiling (initvalue 0) */
+extern EE_TYPEPRIO EE_sys_ceiling;
+
+
+/* The first task into the ready queue -> ready means that the task
+ * has been activated without never running or that it has been
+ * preempted by another task, in both cases without currently locking
+ * any resource
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_rqfirst;
+
+/* The first stacked task -> stacked means a preempted task that owns a mutex
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_stkfirst;
+
+/* The first vres in the recharging queue
+ */
+extern EE_TYPECONTRACT EE_rcgfirst;
+
+
+/* The running task
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_exec;
+
+
+/*************
+* MUTEXES
+*************/
+
+extern const EE_TYPEPRIO EE_resource_ceiling[EE_MAX_RESOURCE];
+
+extern EE_TYPEPRIO EE_resource_oldceiling[EE_MAX_RESOURCE];
+
+
+/*************
+* SYNCHOBJs
+*************/
+
+/* The synchobj descriptor */
+typedef struct {
+ int count;
+ EE_TID first;
+ EE_TID last;
+} SynchObjType;
+
+typedef SynchObjType *SynchObjRefType;
+typedef SynchObjRefType frsh_synchobj_handle_t;
+
+#define SYNCHOBJINIT { 0, EE_NIL, EE_NIL }
+
+#ifdef __FRSH_SYNCHOBJ__
+/* Timeouts for synchronization objects */
+typedef struct {
+ int flag; /* timeout flag */
+ EE_TYPEABSDLINE timeout; /* absolute timeout */
+ EE_TID next; /* used to queue the timeout structure */
+ frsh_synchobj_handle_t synchobj; /* the synchobj the task is waiting on,
+ * != 0 if the task is queued on a synchobj
+ * == 0 if I'm not waiting on a wait with timeout.
+ * reset to 0 when the timeout fires or by the signal */
+} EE_TYPETIMEOUTSTRUCT;
+
+/* initvalue 0 */
+extern EE_TYPETIMEOUTSTRUCT EE_frsh_timeout[];
+
+/* initvalue: EE_NIL */
+extern EE_TID EE_frsh_timeout_first;
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_internal.h
new file mode 100644
index 0000000..87f9faa
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_internal.h
@@ -0,0 +1,331 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author:2003 Paolo Gai
+ * CVS: $Id: ee_internal.h,v 1.3 2008/07/16 09:46:12 francesco Exp $
+ */
+
+#include "ee_common.h"
+#include "ee_irq.h"
+
+#ifndef __INCLUDE_FRSH_INTERNAL_H__
+#define __INCLUDE_FRSH_INTERNAL_H__
+
+
+/*************************************************************************
+* Internal data structures
+*************************************************************************/
+
+/* this array is defined in a separate file at the same level of
+ * eecfg.c because it stores the contract names in string format. If
+ * there are no functions called which needs this variable (this is
+ * usually the case) then the variable is not linked to the final
+ * executable.
+ */
+
+extern const char *EE_frsh_contract_label[EE_MAX_CONTRACT];
+
+
+/*************************************************************************
+* Internal Queue management functions
+*************************************************************************/
+
+
+#ifndef __PRIVATE_RQ_QUERYFIRST__
+/* return the first ready task without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst(void)
+{
+ return EE_rqfirst;
+}
+#endif
+
+#ifndef __PRIVATE_STK_QUERYFIRST__
+/* return the first stacked task (the running task) without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void)
+{
+ return EE_stkfirst;
+}
+#endif
+
+#ifndef __PRIVATE_RQ_GETFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_rq_getfirst(void)
+{
+ EE_rqfirst = EE_th[EE_rqfirst].next;
+}
+#endif
+
+#ifndef __PRIVATE_STK_GETFIRST__
+/* extract the running task from the stack */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_getfirst(void)
+{
+ EE_stkfirst = EE_th[EE_stkfirst].next;
+}
+#endif
+
+#ifndef __PRIVATE_STK_INSERTFIRST__
+/* insert a task into the stack data structures */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_insertfirst(EE_TID t)
+{
+ EE_th[t].next = EE_stkfirst;
+ EE_stkfirst = t;
+}
+#endif
+
+#ifndef __PRIVATE_RCG_QUERYFIRST__
+/* return the first recharging task (the running task) without extracting it */
+__INLINE__ EE_TYPECONTRACT __ALWAYS_INLINE__ EE_rcg_queryfirst(void)
+{
+ return EE_rcgfirst;
+}
+#endif
+
+#ifndef __PRIVATE_RCG_GETFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_rcg_getfirst(void)
+{
+ EE_rcgfirst = EE_vres[EE_rcgfirst].next;
+}
+#endif
+
+#ifndef __PRIVATE_RQ_INSERT__
+/* insert a task into the ready queue */
+void EE_rq_insert(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RQ_EXTRACT__
+/* extract a task from the ready queue. if not present, do nothing */
+void EE_rq_extract(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RCG_INSERT__
+/* insert a task into the recharging queue */
+void EE_rcg_insert(EE_TYPECONTRACT c);
+#endif
+
+
+#ifndef __PRIVATE_RECHARGEBUDGET__
+void EE_frsh_rechargebudget(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_UPDATECAPACITY__
+/* check the current value of a deadline and updates it following the
+ * IRIS rules */
+
+typedef enum AT {
+ EE_UC_InsertedRCGQueue, EE_UC_InsertRDQueue, EE_UC_NoVres
+} ActionType;
+
+ActionType EE_frsh_updatecapacity(EE_TID t,
+ EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_SELECTEXEC__
+void EE_frsh_select_exec(void);
+#endif
+
+#ifndef __PRIVATE_RUNEXEC__
+void EE_frsh_run_exec(EE_TID tmp_exec);
+#endif
+
+#ifndef __PRIVATE_CHECKSLICE__
+void EE_frsh_check_slice(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_ENDSLICE__
+void EE_frsh_end_slice(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_PROCESSRECHARGING__
+int EE_frsh_process_recharging(EE_TYPECONTRACT c);
+#endif
+
+#ifndef __PRIVATE_CHECKRECHARGING__
+void EE_frsh_check_recharging(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_IRQ_RECHARGING__
+void EE_frsh_IRQ_recharging(void);
+#endif
+
+#ifndef __PRIVATE_IRQ_BUDGET__
+void EE_frsh_IRQ_budget(void);
+#endif
+
+#ifndef __PRIVATE_IRQ_DLCHECK__
+void EE_frsh_IRQ_dlcheck(void);
+#endif
+
+#ifndef __PRIVATE_IRQ_SYNCHOBJ_TIMEOUT__
+void EE_frsh_IRQ_synchobj_timeout(void);
+#endif
+
+#ifdef __FRSH_SINGLEIRQ__
+void EE_frsh_timer_reprogram(void);
+void EE_frsh_timer_set(int timer,
+ EE_STIME t);
+void EE_frsh_timer_stop(int timer);
+void EE_frsh_IRQ_timer_multiplexer(void);
+#endif
+
+#ifndef __PRIVATE_BIND_DETACH_VRES__
+int EE_frsh_bind_detach_thread(EE_TID thread);
+#endif
+
+/*************************************************************************
+* Primitives
+*************************************************************************/
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+/* This call terminates a thread instance. It must be called as the
+ * LAST function call BEFORE the `}' that ends a thread. If the
+ * primitive is not inserted at the end of */
+void EE_thread_end_instance(void);
+#endif
+
+/*************************************************************************
+* Timers
+*************************************************************************/
+
+#ifdef __FRSH_SINGLEIRQ__
+/* only the budget timer is available */
+
+/* these two functions are used to set and stop the budget timer, */
+/* which is the only available when SINGLEIRQ is specified */
+/* the timer parameter is used to understand which interrupt source is called */
+/* and it is statically defined in ee_frsh_timers.c */
+
+/* TODO: we could probably do some more work to make this piece of code more */
+/* general, exporting it as a service independent from FRSH */
+
+void EE_frsh_timer_set(int timer,
+ EE_STIME t);
+void EE_frsh_timer_stop(int timer);
+
+
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_budget_timer(EE_STIME t)
+{
+ EE_frsh_timer_set(0, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_budget_timer(void)
+{
+ EE_frsh_timer_stop(0);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_recharging_timer(EE_STIME t)
+{
+ EE_frsh_timer_set(1, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_recharging_timer(void)
+{
+ EE_frsh_timer_stop(1);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_synchobj_timeout_timer(EE_STIME t)
+{
+ EE_frsh_timer_set(2, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_synchobj_timeout_timer(void)
+{
+ EE_frsh_timer_stop(2);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_dline_timer(EE_STIME t)
+{
+ EE_frsh_timer_set(3, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_dline_timer(void)
+{
+ EE_frsh_timer_stop(3);
+}
+
+
+#else
+
+/* four different hardware timers available */
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_budget_timer(EE_STIME t)
+{
+ EE_hal_set_budget_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_budget_timer(void)
+{
+ EE_hal_stop_budget_timer();
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_recharging_timer(EE_STIME t)
+{
+ EE_hal_set_recharging_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_recharging_timer(void)
+{
+ EE_hal_stop_recharging_timer();
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_synchobj_timeout_timer(EE_STIME t)
+{
+ EE_hal_set_synchobj_timeout_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_synchobj_timeout_timer(void)
+{
+ EE_hal_stop_synchobj_timeout_timer();
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_set_dline_timer(EE_STIME t)
+{
+ EE_hal_set_dline_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_frsh_stop_dline_timer(void)
+{
+ EE_hal_stop_dline_timer();
+}
+
+#endif
+
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_irq.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_irq.h
new file mode 100644
index 0000000..ebe4d0e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_irq.h
@@ -0,0 +1,63 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2012 Errico Guidieri
+ */
+
+/*************************************************************************
+* Primitives that have to be called into an IRQ
+*************************************************************************/
+
+#ifndef INCLUDE_FRSH_IRQ_H__
+#define INCLUDE_FRSH_IRQ_H__
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allow IRQ nesting the end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the stack
+ * - if there are other interrupts on the stack the IRQ end_instance should do nothing
+ */
+void EE_IRQ_end_instance(void);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_kernel.h
new file mode 100644
index 0000000..98f9504
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/ee_kernel.h
@@ -0,0 +1,316 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Paolo Gai
+ * CVS: $Id: ee_kernel.h,v 1.4 2008/07/16 09:46:12 francesco Exp $
+ */
+
+#include "kernel/frsh/inc/ee_common.h"
+
+#ifndef __INCLUDE_FRSH_KERN_H__
+#define __INCLUDE_FRSH_KERN_H__
+
+/*************************************************************************
+* Public Kernel Types and Constants
+*************************************************************************/
+
+#define INVALID_TASK EE_NIL
+
+typedef EE_TID TaskType;
+typedef EE_TYPERESOURCE ResourceType;
+typedef EE_TYPERELDLINE TimeRelType;
+typedef EE_TYPEABSDLINE TimeAbsType;
+
+
+/*************************************************************************
+* Kernel Primitives
+*************************************************************************/
+
+/* This macros are used to define a task */
+#define DeclareTask(t) void Func##t(void)
+#define TASK(t) void Func##t(void)
+
+/*************************************************************************
+* System functions
+*************************************************************************/
+
+#ifndef __PRIVATE_SYS_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_frsh_sys_gettime(void);
+#endif
+#endif
+
+
+/*************************************************************************
+* Primitives
+*************************************************************************/
+
+
+
+
+#ifndef __PRIVATE_THREAD_ACTIVATE__
+void EE_frsh_thread_activate(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_SCHEDULE__
+void EE_frsh_Schedule(void);
+#endif
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_frsh_GetResource(EE_TYPERESOURCE m);
+#endif
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_frsh_ReleaseResource(EE_TYPERESOURCE m);
+#endif
+
+
+
+/* FRESCOR API Implementation */
+
+#include "frsh_configuration_parameters.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+
+/* Basic services */
+
+#ifndef __PRIVATE_FRSH_INIT__
+int EE_frsh_init(void);
+#endif
+
+#ifndef __PRIVATE_FRSH_STRERROR__
+int EE_frsh_strerror(int error,
+ char *message,
+ size_t size);
+#endif
+
+
+
+
+/* Contract Creation and initialization */
+
+#ifndef __PRIVATE_FRSH_CONTRACT_GET_BASIC_PARAMS__
+int EE_frsh_contract_get_basic_params(const frsh_contract_t *contract,
+ frsh_rel_time_t *budget_min,
+ frsh_rel_time_t *period_max,
+ frsh_workload_t *workload,
+ frsh_contract_type_t *contract_type);
+#endif
+
+#ifndef __PRIVATE_FRSH_CONTRACT_GET_RESOURCE_AND_LABEL__
+int EE_frsh_contract_get_resource_and_label(const frsh_contract_t *contract,
+ frsh_resource_type_t *resource_type,
+ frsh_resource_id_t *resource_id,
+ char *contract_label);
+#endif
+
+#ifndef __PRIVATE_FRSH_CONTRACT_GET_TIMING_REQS__
+int EE_frsh_contract_get_timing_reqs(const frsh_contract_t *contract,
+ int *d_equals_t,
+ frsh_rel_time_t *deadline,
+ frsh_signal_t *budget_overrun_signal,
+ frsh_signal_info_t *budget_overrun_siginfo,
+ frsh_signal_t *deadline_miss_signal,
+ frsh_signal_info_t *deadline_miss_siginfo);
+#endif
+
+
+
+
+
+
+/* Negotiate Contract Functions */
+
+#ifndef __PRIVATE_BINDTASK__
+int EE_frsh_BindTask(const frsh_vres_id_t vres,
+ const frsh_thread_id_t thread);
+#endif
+
+#ifndef __PRIVATE_UNBINDTASK__
+int EE_frsh_UnbindTask(const frsh_thread_id_t thread);
+#endif
+
+#ifndef __PRIVATE_GETVRESID__
+int EE_frsh_thread_get_vres_id(const frsh_thread_id_t thread,
+ frsh_vres_id_t *vres_id);
+#endif
+
+#ifndef __PRIVATE_GETCONTRACT__
+int EE_frsh_vres_get_contract(const frsh_vres_id_t vres,
+ frsh_contract_t *contract);
+#endif
+
+
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_SIGNAL__
+int EE_frsh_synchobj_signal(const frsh_synchobj_handle_t synch_handle);
+#endif
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_WAIT__
+int EE_frsh_synchobj_wait(const frsh_synchobj_handle_t synch_handle,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+#endif
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_WAIT_TIMEOUT__
+int EE_frsh_synchobj_wait_with_timeout(const frsh_synchobj_handle_t synch_handle,
+ const frsh_abs_time_t *abs_timeout,
+ bool *timed_out,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+#endif
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_TIMEDWAIT__
+int EE_frsh_timed_wait(const frsh_abs_time_t *abs_time,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+#endif
+
+
+/*
+ * Returns true if the system is configured with the on-line admission test enabled, or false otherwise. This
+ * situation can only be changed at compile time.
+ */
+#ifdef __PRIVATE_FRSH_ISADMISSIONTESTENABLED__
+__INLINE__ bool __ALWAYS_INLINE__ EE_frsh_config_is_admission_test_enabled(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified vres.
+ *
+ * Returns:
+ *
+ * 0 if successful
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or budget is NULL
+ */
+#ifdef __PRIVATE_FRSH_GETREMAININGBUDGET__
+__INLINE__ int__ALWAYS_INLINE__ EE_frsh_vres_get_remaining_budget(const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || !budget) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+ *budget = EE_vres[vres].avail_budget;
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+}
+#endif
+
+/*
+ * This function stores the current execution time spent by the threads
+ * bound to the specified vres in the variable pointed to by cpu_time.
+ *
+ * Returns:
+ * 0 if successful
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or spent is
+ * NULL
+ */
+#ifdef __PRIVATE_FRSH_GETUSAGE__
+__INLINE__ int __ALWAYS_INLINE__ EE_frsh_vres_get_usage(const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || !spent) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+ *spent = EE_vres[vres].usage;
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+}
+#endif
+
+/*
+ * frsh_vres_get_budget_and_period()
+ *
+ * This function stores in the variables pointed to by budget and
+ * period, the execution-time budget and the period respectively
+ * associated with the specified vres. If any of these pointers is
+ * NULL, the corresponding information is not stored.
+ *
+ * Returns:
+ *
+ * 0 if successful
+ *
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in
+ * range, or budget and period are both NULL
+ */
+#ifdef __PRIVATE_FRSH_GETBUDGETANDPERIOD__
+__INLINE__ int __ALWAYS_INLINE__ frsh_vres_get_budget_and_period(const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || (!budget && !period)) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (budget) {
+ *budget = EE_ct[vres].budget;
+ if (period) {
+ *period = EE_ct[vres].period;
+
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+ }
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/frsh_types.h b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/frsh_types.h
new file mode 100644
index 0000000..51d1d46
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/inc/frsh_types.h
@@ -0,0 +1,46 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_common.h"
+
+
+typedef EE_TYPERELDLINE frsh_rel_time_t;
+typedef EE_TYPEABSDLINE frsh_abs_time_t;
+typedef char bool;
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_cap.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_cap.c
new file mode 100644
index 0000000..329a29c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_cap.c
@@ -0,0 +1,638 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+
+/* tasks are put into the recharging queue with the following status:
+ * - the budget is always greater then the minimum capacity
+ *
+ * - the period is:
+ *
+ * - if the budget was >0 when the task was interrupted, it is the
+ * former theadline of the task when it was interrupted
+ *
+ * - if the budget was <0 then the deadline is postponed and the
+ * budget incremented until it is greater than 0
+ *
+ * - a problem may occur if the budget is -really- <0 due to shared
+ * resource usage. in that case the task deadline can drift in the
+ * future way over the lifetime of the timer. This is a limitation
+ * we do not address here, because we assume taht the task
+ * parameters and the resource usages are compatible, in other words
+ * the critical sections must be short in order the system to work
+ * fine.
+ */
+
+/* This function recharges a task budget up to a point that it can be
+ * inserted into the recharging queue safely. */
+#ifndef __PRIVATE_RECHARGEBUDGET__
+void EE_frsh_rechargebudget(EE_TID t)
+{
+ EE_TYPECONTRACT c = EE_th[t].vres;
+
+ /* it can not happen that the VRES is UNBOUND because we are
+ * recharging the budget, which means that the task was
+ * executing (not possible if the vres is unbound) */
+
+ for (;; ) {
+ /* recharge the task. */
+ if (EE_vres[c].budget_avail > 0) {
+ /* the budget is positive, and we recharge to the maximum and we exit. */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ break;
+ } else {
+ /* the budget is negative. we sum it and we check if the new budget is enough */
+ EE_vres[c].budget_avail += EE_ct[c].budget;
+ if (EE_vres[c].budget_avail > EE_TIMER_MINCAPACITY) {
+ break;
+ }
+ }
+
+ /* we have to do another round! we update the period and we put the task back */
+ EE_vres[c].absdline += EE_ct[c].period;
+ }
+}
+#endif
+
+
+
+/* this function is called every time a thread is activated
+ * to update his budget available and to check if it should go
+ * recharging
+ *
+ * it is similar to checkslice but it activates a task which for sure
+ * has lockedcounter=0
+ */
+#ifndef __PRIVATE_UPDATECAPACITY__
+ActionType EE_frsh_updatecapacity(EE_TID t,
+ EE_TIME tmp_time)
+{
+ EE_TYPECONTRACT c = EE_th[t].vres;
+
+ /* check if the VRES is UNBOUND. in this case, return nothing. the
+ * capacity is not updated because there is no vres bound to the
+ * task. */
+ if (c == EE_VRES_NIL) {
+ return EE_UC_NoVres;
+ }
+
+ if (EE_vres[c].status == EE_VRES_RECHARGING) {
+ /* the VRES of a task just activated can be recharging in the following scenario:
+ * 1 a task X ends its budget and its vres V goes to recharging
+ * 2 an unbind is called on task X. the vres V remains floating and recharging
+ * 3 a SUSPENDED task Y is binded to the vres V (which is in recharging)
+ * 4 task Y is activated
+ *
+ * If the vres is recharging, we have nothing to do here.
+ */
+ return EE_UC_InsertedRCGQueue;
+ }
+
+ /* if the thread is not active or the current deadline is in the past */
+ if (EE_vres[c].status == EE_VRES_FREEZED || (EE_STIME)(EE_vres[c].absdline - tmp_time) < 0) {
+ /* task deadline is in the past, reset it to the default */
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+
+ /* In this case, we decided to put it equal to the budget because
+ * since the deadline is in the past or the task is not active it
+ * is not worth to check and use a += instead of = . also, using
+ * += does not guarantees that after the sum the capacity is
+ * greater than 0, and so we are not sure we can put the task into
+ * the ready queue! */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ return EE_UC_InsertRDQueue;
+ } else {
+ /* task deadline is in the future */
+ if (EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY) {
+ /* goes in recharging only if the remaining capacity is less than the minimum capacity */
+ EE_frsh_rechargebudget(t);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_frsh_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ return EE_UC_InsertedRCGQueue;
+ }
+ /* This is the test of CBS, saying that if the bandwith of the
+ * task considered as the remaining capacity divided buy the time
+ * left to the deadline is greater than the nominal bandwidth of
+ * the task we have to reassign the deadlines to avoid that the
+ * task executes too much. This situation typically happens when
+ * the task stays idle for a while, or if the task has been
+ * blocked for a while. */
+
+ if ((EE_STIME)(EE_vres[c].absdline - EE_vres[c].budget_avail * EE_ct[c].inv_proc_util -
+ tmp_time) <= 0) {
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+ }
+
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ return EE_UC_InsertRDQueue;
+ }
+}
+
+#endif
+
+
+
+/*
+ * input status: EE_exec is EE_NIL, ready or stacked queue may be full or empty
+ * result:
+ * EE_exec is set to the next task to schedule.
+ * the status is untouched
+ * if EE_exec is different from EE_NIL, then the task has been removed from its queue
+ *
+ * Note: WE CANNOT CHANGE THE STATUS TO EXEC HERE. The status brings
+ * also the flag wasstacked. if we set it, then nothing will work
+ * after this. A solution could be to put wasstacked in a separate
+ * status variable, but I do not want to do that for now.
+ */
+#ifndef __PRIVATE_SELECTEXEC__
+void EE_frsh_select_exec(void)
+{
+ register EE_TID tmp_rq;
+ register EE_TID tmp_stk;
+
+ tmp_rq = EE_rq_queryfirst();
+ tmp_stk = EE_stk_queryfirst();
+
+ if (tmp_rq == EE_NIL) {
+ /* either the first on the stacked queue or nil */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_stk_getfirst();
+ }
+ } else {
+ /* the ready queue is not empty */
+ if (tmp_stk == EE_NIL ||
+ ((EE_STIME)(EE_vres[EE_th[tmp_stk].vres].absdline - EE_vres[EE_th[tmp_rq].vres].absdline) > 0
+ && EE_sys_ceiling < EE_th[tmp_rq].prlevel)) {
+ EE_exec = tmp_rq;
+ EE_rq_getfirst();
+ } else {
+ /* note that if the previous exec task ahs some locked
+ * resources, then it was put into the stacked queue */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_stk_getfirst();
+ }
+ }
+ }
+}
+#endif
+
+
+/*
+ * If the tmp_exec is different from EE_exec, change context to it.
+ * We suppose that if the task has been put to exec, then it has a valid VRES
+ */
+#ifndef __PRIVATE_RUNEXEC__
+void EE_frsh_run_exec(EE_TID tmp_exec)
+{
+ register int wasstacked;
+
+ if (EE_exec == EE_NIL) {
+ /* switch to the background thread if needed */
+ if (tmp_exec != EE_exec) {
+ EE_hal_stkchange(EE_exec);
+ }
+ } else {
+ /* there is a task to schedule */
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* if different from the current running task implement the preemption */
+ if (tmp_exec != EE_exec) {
+ /* reprogram the capacity timer for the new task */
+ EE_frsh_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_stkchange(EE_exec);
+ } else {
+ EE_hal_ready2stacked(EE_exec);
+ }
+ }
+ }
+}
+#endif
+
+
+
+
+/*
+ * check_slice
+ *
+ * first considers the exec task, and accounts the elapsed time.
+ *
+ * updates the last timer read
+ *
+ * put the exec task in the right queue:
+ * - stacked if the task has locked resources, independently from the budget
+ * - ready if the task has still budget
+ * - recharging if it has no more budget
+ *
+ * puts exec to -1
+ */
+
+#ifndef __PRIVATE_CHECKSLICE__
+void EE_frsh_check_slice(EE_TIME tmp_time)
+{
+ register EE_TIME delta;
+
+ if (EE_exec != EE_NIL) {
+ EE_TYPECONTRACT c = EE_th[EE_exec].vres;
+ /* it can never happen that the vres is UNBOUND because the task
+ * cannot execute without a VRES */
+
+ /* account the capacity to the task that is currently executing */
+ delta = tmp_time - EE_last_time;
+ EE_vres[c].budget_avail -= delta;
+
+ /* account the overall usage */
+ EE_vres[c].usage += delta;
+
+ if (EE_th[EE_exec].lockedcounter) {
+ /* The task is holding a resource, put it into the stacked queue
+ * regardless of the budget it has.
+ */
+ EE_stk_insertfirst(EE_exec);
+ EE_th[EE_exec].status = EE_TASK_STACKED | EE_TASK_WASSTACKED;
+ /* VRES status unchanged */
+ } else if ((EE_STIME)EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY) {
+ /* if the budget is exhausted then insert in the recharging queue */
+ EE_frsh_rechargebudget(EE_exec);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+ EE_th[EE_exec].status = EE_TASK_READY | EE_TASK_WASSTACKED;
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_frsh_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+ } else {
+ EE_rq_insert(EE_exec);
+
+ EE_th[EE_exec].status = EE_TASK_READY | EE_TASK_WASSTACKED;
+ /* VRES status unchanged */
+ }
+
+ /* EE_exec has been inserted into a queue */
+ EE_exec = EE_NIL;
+ }
+
+ /* update the last timer read */
+ EE_last_time = tmp_time;
+}
+#endif
+
+
+
+/*
+ * end_slice
+ *
+ * This is similar to check-slice, but it is different because it is
+ * executed at the end of a task.
+ *
+ * first considers the exec task, and accounts the elapsed time.
+ *
+ * updates the last timer read
+ *
+ * put the exec task in the right queue:
+ * if nact >1 and budget>0
+ * the task is put back into the ready queue
+ * if nact =0 and budget >0
+ * the task is suspended waiting for the next activation
+ * if nact >1 and budget <0
+ * the ending task has consumed all its budget.
+ * I put the task in recharging
+ * if nact =0 and budget <0
+ * I cannot put this task in the recharging queue because it is no more active
+ * but it will go in the recharging queue when it will be activated again
+ * so in this case I do nothing
+ *
+ * puts exec to -1
+ */
+
+#ifndef __PRIVATE_ENDSLICE__
+void EE_frsh_end_slice(EE_TIME tmp_time)
+{
+ register int time_check;
+ register int nact_check;
+ register EE_TYPECONTRACT c;
+ register EE_TYPEBUDGET delta;
+
+ c = EE_th[EE_exec].vres;
+ /* it can never happen that the vres is UNBOUND because the task
+ * cannot execute without a VRES */
+
+ /* account the capacity to the task that is currently executing */
+ delta = tmp_time - EE_last_time;
+ EE_vres[c].budget_avail -= delta;
+
+ /* account the overall usage */
+ EE_vres[c].usage += delta;
+
+ time_check = (EE_STIME)EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY;
+ nact_check = EE_th[EE_exec].nact;
+
+ if (time_check) {
+ /* no budget left */
+ if (nact_check) {
+ /* nact > 1 */
+ /* the ending task has consumed all its budget. */
+ /* It has still pending activations, I put the task in recharging */
+ EE_frsh_rechargebudget(EE_exec);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+ EE_th[EE_exec].status = EE_TASK_READY;
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_frsh_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ /* WASSTACKED is not set, because the task just ended */
+ } else {
+ /* nact = 0 */
+ /* do nothing. */
+ /* the task is currently in any queue */
+ /* the task will be inserted in the recharging queue when activated again */
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ EE_th[EE_exec].status = EE_TASK_SUSPENDED;
+ }
+ } else {
+ /* there is still budget */
+ if (nact_check) {
+ /* nact > 1 */
+ /* the task is put back into the ready queue, no need to update the budget */
+ EE_rq_insert(EE_exec);
+ /* VRES status unchanged */
+ EE_th[EE_exec].status = EE_TASK_READY;
+ /* WASSTACKED is not set, because the task just ended */
+ } else {
+ /* nact = 0 - tested */
+ /* the task is suspended waiting for the next activation. */
+ /* the budget is left as it was */
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ EE_th[EE_exec].status = EE_TASK_SUSPENDED;
+ }
+ }
+
+ /* EE_exec has been inserted into a queue or is terminated */
+ EE_exec = EE_NIL;
+
+ /* update the last timer read */
+ EE_last_time = tmp_time;
+}
+#endif
+
+
+
+/* frsh_process_recharging
+ *
+ * this function is used to process a recharging VRES when the
+ * recharging time arrive or when the recharging time is reduiced due
+ * to a time-warp.
+ *
+ * The deadline and budget of the VRES is the final one and does not
+ * need any change. The budget is greater than the minimum.
+ *
+ * We have to process the task and understand if it has to be inserted
+ * in any queue
+ *
+ * the function returns 1 when the recharge processed is related to a
+ * VRES without a task binded to it. this is important in this situation:
+ * - a task is unbinded, and its VRES is put in the recharging queue
+ * - a time-warp happens, and the first VRES in the recharging queue is the VRES without tasks binded to them. In that case, we have to take another VRES from the queue, because we want to have a good "delta" value!
+ */
+#ifndef __PRIVATE_PROCESSRECHARGING__
+int EE_frsh_process_recharging(EE_TYPECONTRACT c)
+{
+ register EE_TID t;
+ register EE_TYPESTATUS status;
+
+ /* consider the task linked to the VRES */
+ t = EE_vres[c].task;
+
+ if (t != EE_NIL && t != EE_TID_DEFERRED) {
+ /* there is a task linked to the VRES.
+ * the task status can be:
+ * READY|WASSTACKED
+ * typical case
+ * --> VRES set to active, task in the ready queue
+ * READY (task ended without capacity and nact > 1)
+ * same as ready
+ * STACKED
+ * --> VRES set to active, the task is already in the stacked queue so we do nothing
+ * SUSPENDED
+ * may happen after a bind to the task of a vres in recharging
+ * --> VRES set to inactive
+ * BLOCKED
+ * may happen after a bind to the task of a vres in recharging
+ * same as SUSPENDED
+ */
+
+ status = EE_th[t].status;
+ if (status & EE_TASK_READY) {
+ /* EE_TASK_READY, independently of the WASSTACKED */
+ EE_rq_insert(t);
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ } else if (status & EE_TASK_STACKED) {
+ /* EE_TASK_STACKED */
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ } else {
+ /* EE_TASK_SUSPENDED or EE_TASK_BLOCKED */
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ }
+ return 0;
+ } else {
+ /* EE_NIL --> this is a VRES without bindings to a task. may happen after an unbind
+ * EE_TID_DEFERRED --> may happen if a task has been binded to the
+ * VRES BUT the binding was not yet done because the task is STACKED
+ */
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ return 1;
+ }
+}
+#endif
+
+
+
+
+/*
+ * check-recharging
+ *
+ * if ready and stacked queue are empty pulls from the recharging queue
+ *
+ * it reprograms the recharging IRQ
+ */
+#ifndef __PRIVATE_CHECKRECHARGING__
+void EE_frsh_check_recharging(EE_TIME tmp_time)
+{
+ register EE_TYPEBUDGET delta;
+ register EE_TYPECONTRACT c;
+
+ /* if there are not tasks in the ready and in the stacked queue,
+ * check if there are task in recharging queue and if so, immediately
+ * recharge one or more of them.
+ */
+
+ /* check if the ready and stacked queue are empty */
+ if (EE_stk_queryfirst() != EE_NIL || EE_rq_queryfirst() != EE_NIL) {
+ return;
+ }
+
+
+ /*
+ * this first cycle is used to identify a VRES inside the recharging
+ * queue which is LINKED TO A TASK. that is, since we want ti
+ * implement a recharge which brings a task in recharging into the
+ * ready queue, it must haoppen taht we really find one.
+ *
+ * In reality the cycle is needed because it may be that the first n
+ * entries in the VRES queue are related to VRES without a task
+ * attached to them due to bind/unbind. We basically have to process
+ * these VRES until either the recharging queue is empty or we find
+ * a VRES with a task attached to it.
+ */
+ do {
+ /* we take the first vres in the recharging queue.
+ * the tasks has been inserted into the queue with a reasonable budget
+ * (see EE_frsh_rechargebudget) */
+ c = EE_rcg_queryfirst();
+
+ /* exit if the recharging queue is empty */
+ if (c == EE_VRES_NIL) {
+ EE_frsh_stop_recharging_timer();
+ return;
+ }
+
+ /* remove the vres from the recharging queue */
+ EE_rcg_getfirst();
+
+ /* delta is the amount of time we have to shift all the recharging deadlines */
+ delta = EE_vres[c].absdline - tmp_time;
+
+ /* at this point t is the head of the recharging queue
+ * t has a budget which is > EE_TIMER_MINCAPACITY
+ * t has the deadline which was the one which it was inserted (or postponed) into the recharging queue
+ * c is no more inside the recharging queue
+ * t is not inserted in the ready queue
+ * delta is the shift to be applied to all the tasks remaining in the recharging queue
+ */
+
+ /* we update the deadline of the vres */
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+
+ /* we process the task pointed by the VRES */
+ } while (EE_frsh_process_recharging(c));
+
+ /* If we arrive here, it must be that we found a VRES with a task
+ * linked to it, and there are more VRES to process. */
+
+ /* we have to shift all the recharging times by delta */
+ c = EE_rcg_queryfirst();
+ while (c != EE_VRES_NIL) {
+ EE_vres[c].absdline -= delta;
+
+ /* if the deadline is (almost) 0, it means that the task's recharge IRQ once put in the ready queue
+ * will fire in a few microseconds */
+ if ((EE_STIME)(EE_vres[c].absdline - tmp_time) <= EE_TIMER_MINCAPACITY) {
+ /* we have to reassign deadline and budget */
+ /* the check with the minimum capacity is to avoid the recharging interrupt to arrive too early */
+
+ /* update the deadline. Note the deadline has been shifted by delta already */
+ /* The budget has already been set when inserting into the recharging queue */
+ EE_vres[c].absdline += EE_ct[c].period;
+
+ /* we process the task pointed by the VRES */
+ EE_frsh_process_recharging(c);
+
+ /* remove from the top of the recharging queue */
+ EE_rcg_getfirst();
+ c = EE_rcg_queryfirst();
+ } else {
+ /* the recharging queue is ordered by deadline. if one fails, */
+ /* all the rest will fail because they will come later. */
+
+ /* go to the next vres, it has to be processed by the next while */
+ c = EE_vres[c].next;
+ break;
+ }
+ }
+
+ /* do the rest of the vres */
+ while (c != EE_VRES_NIL) {
+ EE_vres[c].absdline -= delta;
+ c = EE_vres[c].next;
+ }
+
+ c = EE_rcg_queryfirst();
+
+ /* at the end of the update, we have to reprogram the recharging IRQ */
+ if (c != EE_VRES_NIL) {
+ EE_frsh_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ } else {
+ EE_frsh_stop_recharging_timer();
+ }
+}
+#endif
+
+/* #ifdef __SEM_FRSH__ */
+/* // PJ: da rivedere quando farò i semafori */
+/* // note: both recharging times and semaphore timeouts timers are on the same queue */
+/* // PJ: potremmo usare un vettore per gli accodamenti nel recharging evitando gli if... */
+/* if (EE_th_status[EE_rcg_queryfirst()] & EE_BLOCKED) { */
+/* EE_frsh_set_recharging_timer(EE_th_timeouts[EE_rcg_queryfirst()] - tmp_time); */
+/* } */
+/* else */
+/* #endif */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_dlcheck.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_dlcheck.c
new file mode 100644
index 0000000..5e80667
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_dlcheck.c
@@ -0,0 +1,80 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_dlcheck.c,v 1.7 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+/* PJ: we should initialize this function inside the frsh_init */
+/* could we put it into the recharging queue? */
+
+/* option1 --> create a task that calls this */
+/* option2 --> create an alarm with an alarm callback */
+
+#ifndef __PRIVATE_IRQ_DLCHECK__
+/* periodic check of deadline MUST be done with a rate
+ * at least equal to 1/4 of timer capacity*/
+void EE_frsh_IRQ_dlcheck(void)
+{
+ register EE_TYPECONTRACT c;
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ for (c = 0; c < EE_MAX_CONTRACT; c++) {
+ if (EE_vres[c].status != EE_VRES_FREEZED &&
+ (EE_STIME)(tmp_time - EE_vres[c].absdline) > 0) {
+ EE_vres[c].status = EE_VRES_FREEZED;
+ }
+ }
+
+ /* set this as a periodic interrupt */
+ EE_frsh_set_dline_timer(EE_TIMER_MAXFUTUREVALUE >> 2);
+
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_budget.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_budget.c
new file mode 100644
index 0000000..fc55a69
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_budget.c
@@ -0,0 +1,51 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_BUDGET__
+/*
+ * The function is empty, because check_slice is called into the end of
+ * the IRQ
+ */
+void EE_frsh_IRQ_budget(void)
+{
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_recharging.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_recharging.c
new file mode 100644
index 0000000..9f201c5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_end_recharging.c
@@ -0,0 +1,105 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_RECHARGING__
+/*
+ * This routine is called when the recharging time of a task is finished
+ * It basically takes the time, and check all the recharging times which has expired
+ *
+ * Please note that when a task is inserted into the recharging queue
+ * its budget is always greter than the minimum budget, and for this
+ * reason the task can be inserted into the ready queue without
+ * problems.
+ */
+void EE_frsh_IRQ_recharging(void)
+{
+ register EE_TIME tmp_time;
+ register EE_FREG flag;
+ register EE_TYPECONTRACT c;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time */
+ tmp_time = EE_hal_gettime();
+
+ /* Check for negative budget and in case re-insert in the rcg queue */
+ c = EE_rcg_queryfirst();
+ while (c != EE_VRES_NIL) {
+ if ((EE_STIME)(EE_vres[c].absdline - tmp_time) <= EE_TIMER_MINCAPACITY) {
+ /* remove the task from the recharging queue */
+ EE_rcg_getfirst();
+
+ /* update the absolute deadline by summing the period. doing
+ * absdeadline = tmp_time+period IS WRONG, because in that way
+ * we have a drift with respect to the recharging implemented
+ * into EE_frsh_check_recharging.
+ *
+ * Note that this function is different from
+ * EE_frsh_check_recharging, and they cannot be the -same-
+ * function, or we cannot empty this function, because the
+ * EE_frsh_check_recharging only works when ready and stacked
+ * queues are empty, whereas this function works in any case.*/
+ EE_vres[c].absdline += EE_ct[c].period;
+
+ /* we process the task pointed by the VRES */
+ EE_frsh_process_recharging(c);
+ } else {
+ /* the tasks are ordered by deadline. if one fails, the others are for sure in the future */
+ break;
+ }
+
+ c = EE_rcg_queryfirst();
+ }
+
+ /* c points to the top of the recharging queue */
+
+ /* Program the recharging timer */
+ if (c == EE_VRES_NIL) {
+ EE_frsh_stop_recharging_timer();
+ } else {
+ EE_frsh_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind.c
new file mode 100644
index 0000000..78a28bd
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind.c
@@ -0,0 +1,208 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/*
+ * frsh_thread_bind()
+ *
+ * This operation associates a thread with a vres, which means that it starts consuming the vres's budget and
+ * is executed according to the contract established for that vres. If the thread is already bound to another
+ * vres, it is effectively unbound from it and bound to the specified one.
+ *
+ * It fails if the vres's policy is different than FRSH_NONE, or if there is already a thread bound to this vres.
+ *
+ * Returns:
+ * - 0 if successful
+ * - FRSH_ERR_BAD_ARGUMENT : if the vres value does not complain with the
+ * expected format or valid range or the given thread does not exist
+ * - FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not valid
+ * - FRSH_ERR_ALREADY_BOUND : if the given vres has a thread already bound
+ */
+#ifndef __PRIVATE_BINDTASK__
+int EE_frsh_BindTask(const frsh_vres_id_t vres,
+ const frsh_thread_id_t thread)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (vres < 0 || vres >= EE_MAX_CONTRACT) {
+ return FRSH_ERR_NOT_CONTRACTED_VRES;
+ }
+
+ if (thread < 0 || thread >= EE_MAX_TASK) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+#ifdef __RN_BIND__
+ if (thread & EE_REMOTE_TID) {
+ register EE_TYPERN_PARAM par;
+ par.vres = vres;
+ /* forward the request to another CPU */
+ if (EE_rn_send(thread & ~EE_REMOTE_TID, EE_RN_BIND, par)) {
+ /* a bind or unbind operation is currently pending; maybe we should use a custom return value */
+ return FRSH_ERR_ALREADY_BOUND;
+ } else {
+ return FRSH_NO_ERROR;
+ }
+ }
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (EE_vres[vres].task != EE_NIL) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_ALREADY_BOUND;
+ }
+
+ /* this part is very similar to ActivateTask */
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the bind behavior */
+
+ /* detach the current VRES, and depending on the result do the thread handling */
+ /* works also if the thread has not a VRES attached (that is EE_VRES_NIL) */
+ if (EE_frsh_bind_detach_thread(thread)) {
+ /* The VRES has been detached
+ * - as a result of detach_vres the task is not inserted in the ready queue
+ * - we can give the task the new VRES now*/
+ EE_vres[vres].task = thread;
+ EE_th[thread].vres = vres;
+
+ /* at this point,
+ *
+ * the new VRES is linked to the task, but the task needs to be fixed.
+ *
+ * The new VRES can be in one of the following statuses
+ * FREEZED if it has never binded to anyone
+ * FREEZED, INACTIVE or RECHARGING after a bind/unbind
+ *
+ * (
+ * in fact, bind / unbind leave a VRES in one of the following statuses
+ *
+ * before bind/unbind after
+ * freezed no change
+ * inactive no change
+ * active ---->>>> inactive
+ * recharging no change
+ *
+ * That is, the new VRES can be either freezed, inactive, or recharging
+ * )
+ *
+ * The task is in a given status.
+ * Remember that the task is NOT inserted in the ready queue.
+ * If it was in the stacked queue, it remained there.
+ * Depending on the status we have to do some actions among the following (thread status
+ * uppercase, vres status lowercase):
+ *
+ * SUSPENDED
+ * freezed --> nothing
+ * inactive --> nothing
+ * recharging --> nothing. at the recharging time process_recharging will put the vres in inactive
+ * READY
+ * freezed --> updatecapacity, eventually insert into the ready queue
+ * inactive --> updatecapacity, eventually insert into the ready queue
+ * recharging --> nothing, it will be inserted in the ready queue when the recharging time will happen
+ * we ALWAYS CALL in any case updatecapacity which has a test on the recharging state.
+ * STACKED
+ * IT IS NOT POSSIBLE that we are here and the atsk is STARCKED.
+ * if it is tacked, in fact, the bind is deferred.
+ *
+ * BLOCKED
+ * freezed --> nothing
+ * inactive --> nothing
+ * recharging --> nothing. at the recharging time process_recharging will put the vres in inactive
+ */
+
+ if (EE_th[thread].status & EE_TASK_READY) {
+ if (EE_frsh_updatecapacity(thread, tmp_time) == EE_UC_InsertRDQueue) {
+ EE_rq_insert(thread);
+ }
+ }
+ } else {
+ /* The VRES has NOT been detached. Store in the detached variable
+ * that the task has to be attached to the new VRES */
+ EE_th[thread].vres_deferred = vres;
+
+ /* this value will make the test after begin_nested_primitive fail! */
+ EE_vres[vres].task = EE_TID_DEFERRED;
+ }
+
+ /* --- */
+
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+
+ return FRSH_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind_utils.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind_utils.c
new file mode 100644
index 0000000..4de4301
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_bind_utils.c
@@ -0,0 +1,125 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+/* this file contains a set of utility functions used by bind and unbind */
+
+
+/*
+ * This function detaches any VRES attached to a thread
+ * returns:
+ * - 1 if the VRES has been detached successfully
+ * - 0 if the VRES has NOT been detached successfully - the VRES has been BOOKED for detachment
+ *
+ * Returns 1 if the VRES has been detached, 0 if the VRES detachment has been postponed.
+ */
+#ifndef __PRIVATE_BIND_DETACH_VRES__
+int EE_frsh_bind_detach_thread(EE_TID thread)
+{
+ register EE_TYPESTATUS status;
+ register EE_TYPECONTRACT vres;
+
+ vres = EE_th[thread].vres;
+
+ /* check if a task has already been detached */
+ if (vres == EE_VRES_NIL) {
+ return 1;
+ }
+
+ status = EE_th[thread].status;
+
+ if (status & EE_TASK_READY) {
+ /* the states FREEZED, INACTIVE, NOT_BOUND are not possible for the VRES since the task is active.
+ */
+
+ /* detach the thread and the VRES */
+ EE_th[thread].vres = EE_VRES_NIL;
+ EE_vres[vres].task = EE_NIL;
+
+ if (EE_vres[vres].status == EE_VRES_ACTIVE) {
+ /* EE_VRES_ACTIVE
+ * We need to remove the task from the ready queue and put the VRES inactive
+ */
+ /* Put the VRES to INACTIVE */
+ EE_vres[vres].status = EE_VRES_INACTIVE;
+
+ /* remove the task from the ready queue */
+ EE_rq_extract(thread);
+ }
+
+ /* else { */
+ /* EE_VRES_RECHARGING - The vres is recharging
+ * we can detach it. at the recharging time the detached vres will be put INACTIVE
+ */
+
+ /* the vres status remains recharging */
+
+ /* we do not have to remove the thread from the ready queue
+ * because it is not there (its vres is in the recharging
+ * queue) */
+
+ /* nothing has to be done. commenting out the else. */
+ /* } */
+ } else if (status & EE_TASK_STACKED) {
+ /* EE_TASK_STACKED - defer the unbind at the end of the critical section
+ * The current VRES must stay attached to the thread,
+ * it will be detached later on.
+ */
+
+ return 0;
+ } else {
+ /* else if (status & (EE_TASK_SUSPENDED | EE_TASK_BLOCKED)) { */
+ /* detach the thread and the VRES */
+ EE_th[thread].vres = EE_VRES_NIL;
+ EE_vres[vres].task = EE_NIL;
+ }
+
+
+ /* if we return 1, the task is not on the ready queue */
+
+ return 1;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_contracts.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_contracts.c
new file mode 100644
index 0000000..9c9d3f6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_contracts.c
@@ -0,0 +1,142 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include <string.h>
+#include "ee_internal.h"
+#include "frsh_configuration_parameters.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/* These functions have been inserted for compatibility with the FRSH API */
+
+/*
+ * frsh_contract_get_basic_params()
+ *
+ * This operation obtains from the specified contract object its budget,
+ * period, and workload, and copies them to the places pointed to by the
+ * corresponding output parameters.
+ *
+ * Input Parameters:
+ * - contract the pointer to the contract object
+ *
+ * Output Parameters:
+ * - budget_min pointer to preallocated space
+ * - period_max pointer to preallocated space
+ * - workload pointer to preallocated space
+ * - contract_type pointer to preallocated space
+ *
+ * Returns:
+ * 0 if no error
+ * FRSH_ERR_BAD_ARGUMENT : if one of the contract or pointers is NULL.
+ *
+ */
+#ifndef __PRIVATE_FRSH_CONTRACT_GET_BASIC_PARAMS__
+int EE_frsh_contract_get_basic_params(const frsh_contract_t *contract,
+ frsh_rel_time_t *budget_min,
+ frsh_rel_time_t *period_max,
+ frsh_workload_t *workload,
+ frsh_contract_type_t *contract_type)
+{
+ if (!contract || !budget_min || !period_max || !workload || !contract_type) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ *budget_min = contract->budget;
+ *period_max = contract->period;
+ *workload = FRSH_WT_INDETERMINATE;
+ *contract_type = FRSH_CT_REGULAR;
+
+ return FRSH_NO_ERROR;
+}
+#endif
+
+
+
+/*
+ * frsh_contract_get_timing_reqs()
+ *
+ * The operation obtains the corresponding input parameters from the
+ * specified contract object. If d_equals_t is true, the deadline will
+ * be set to FRSH_NULL_DEADLINE.
+ *
+ * Returns:
+ * - 0 if no error
+ * - FRSH_ERR_BAD_ARGUMENT : if contract is NULL
+ */
+#ifndef __PRIVATE_FRSH_CONTRACT_GET_TIMING_REQS__
+int EE_frsh_contract_get_timing_reqs(const frsh_contract_t *contract,
+ int *d_equals_t,
+ frsh_rel_time_t *deadline,
+ frsh_signal_t *budget_overrun_signal,
+ frsh_signal_info_t *budget_overrun_siginfo,
+ frsh_signal_t *deadline_miss_signal,
+ frsh_signal_info_t *deadline_miss_siginfo)
+{
+ int i;
+
+ if (!contract) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ for (i = 0; i < EE_MAX_CONTRACT; i++) {
+ if (&EE_ct[i] == contract) {
+ break;
+ }
+ }
+
+ if (i == EE_MAX_CONTRACT) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ *d_equals_t = 1;
+ *deadline = FRSH_NULL_DEADLINE;
+ *budget_overrun_signal = 0;
+ *budget_overrun_siginfo = 0;
+ *deadline_miss_signal = 0;
+ *deadline_miss_siginfo = 0;
+
+ return FRSH_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getcontract.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getcontract.c
new file mode 100644
index 0000000..ac1f952
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getcontract.c
@@ -0,0 +1,74 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/*
+ * This operation stores the contract parameters currently associated with the specified vres in the variable
+ * pointed to by contract. It returns an error if the vres_id is not recognised.
+ * Returns:
+ * 0 if no error
+ * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value of the vres argument
+ * is not in range
+ */
+#ifndef __PRIVATE_GETCONTRACT__
+int EE_frsh_vres_get_contract(const frsh_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || contract == NULL) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ /* no need for interrupt disabling. Contracts are consts... */
+ contract->budget = EE_ct[vres].budget;
+ contract->period = EE_ct[vres].period;
+ contract->inv_proc_util = EE_ct[vres].inv_proc_util;
+
+ return 0;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getvresid.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getvresid.c
new file mode 100644
index 0000000..0692581
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_getvresid.c
@@ -0,0 +1,83 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/*
+ * This operation stores the Id of the vres associated with the specified thread in the variable pointed to by
+ * vres. It returns an error if the thread does not exist, it is not under the control of the scheduling framework,
+ * or is not bound.
+ * Returns:
+ * 0 if no error
+ * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid vres bound to it
+ * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist or the vres argument is NULL
+ */
+#ifndef __PRIVATE_GETVRESID__
+int EE_frsh_thread_get_vres_id(const frsh_thread_id_t thread,
+ frsh_vres_id_t *vres_id)
+{
+ register EE_FREG flag;
+
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (thread < 0 || thread >= EE_MAX_TASK || vres_id == NULL) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (EE_th[thread].vres == EE_VRES_NIL) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_NOT_BOUND;
+ }
+
+ *vres_id = EE_th[thread].vres;
+
+ EE_hal_end_nested_primitive(flag);
+
+ return 0;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_init.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_init.c
new file mode 100644
index 0000000..4c8e76f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_init.c
@@ -0,0 +1,70 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_frsh_init.c,v 1.4 2008/07/21 13:51:54 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_error.h"
+/* used to check if the initialization has already been done */
+int EE_frsh_init_once = 1;
+
+
+#ifndef __PRIVATE_FRSH_INIT__
+int EE_frsh_init(void)
+{
+ if (EE_frsh_init_once) {
+ /* must be done once */
+ EE_frsh_init_once = 0;
+
+#ifdef OO_CPU_HAS_STARTOS_ROUTINE
+ EE_cpu_startos();
+#endif
+ EE_time_init();
+ EE_frsh_time_init();
+
+ return FRSH_NO_ERROR;
+ } else {
+ return FRSH_ERR_SYSTEM_ALREADY_INITIALIZED;
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_strerror.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_strerror.c
new file mode 100644
index 0000000..efc8e1e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_strerror.c
@@ -0,0 +1,117 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_error.h"
+
+
+#ifndef __PRIVATE_FRSH_STRERROR__
+
+#include <string.h>
+
+static char *EE_frsh_strerror_table[] = {
+ "too many tasks",
+ "bad argument",
+ "invalid synch obj handle",
+ "no renegotiation requested",
+ "contract rejected",
+ "not scheduled calling thread",
+ "not bound",
+ "unknown scheduled thread",
+ "not contracted vres",
+ "not scheduled thread",
+ "too many service jobs",
+ "too many synch objs",
+ "too many vres in synch obj",
+ "too many events in synch obj",
+ "internal error",
+ "too many vres",
+ "invalid scheduler reply",
+ "too many pending replenishments",
+ "system already initialized",
+ "shared obj already initialized",
+ "shared obj not initialized",
+ "sched policy not compatible",
+ "vres workload not compatible",
+ "already bound",
+ "resource id invalid",
+ "too large",
+ "buffer full",
+ "no space",
+ "no messages",
+ "module not supported",
+ "not initialized",
+ "too many shared objs",
+ "contract label already exists",
+ "budget expired",
+ "shared object not protected",
+ "not implemented",
+ "contract type not compatible",
+ "capacity not decreasing",
+ "contract label unknown "
+};
+
+
+/* Converts an error code to a string */
+int EE_frsh_strerror(int error,
+ char *message,
+ size_t size)
+{
+ if (error > FRSH_ERR_LAST_VALUE || error <= FRSH_ERR_BASE_VALUE) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (message != NULL && size > 0) {
+ /* let's hope the microcontroller has strncpy */
+ strncpy(message,
+ EE_frsh_strerror_table[error - FRSH_ERR_BASE_VALUE - 1],
+ size);
+
+ message[size] = '\0';
+ }
+
+ return FRSH_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_signal.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_signal.c
new file mode 100644
index 0000000..47bea74
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_signal.c
@@ -0,0 +1,148 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_spost.c,v 1.2 2008/07/16 09:46:12 francesco Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/*
+ * This function sends a notification event to the synchronization
+ * object specified as parameter. If there is at least one vres waiting
+ * on the synchronization object, it is awaken. If more than one vres
+ * are waiting, just one of them is awaken. However, which one is
+ * awaken is implementation dependent. If no vres is waiting on the
+ * synchronization object, the notification event is queued.
+ *
+ * Parameters:
+ * synch_handle the handle of the synchronization object to notify.
+ *
+ * Returns:
+ * 0 if no error
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0
+ */
+
+
+void EE_frsh_timeout_extract(EE_TID t,
+ EE_TIME tmp_time);
+
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_SIGNAL__
+int EE_frsh_synchobj_signal(const frsh_synchobj_handle_t synch_handle)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+ register EE_TID tmp;
+
+ if (synch_handle == 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the signal behavior */
+
+ if (synch_handle->first != EE_NIL) {
+ /* wake up a blocked thread */
+ tmp = synch_handle->first;
+
+ synch_handle->first = EE_th[tmp].next;
+
+ if (synch_handle->first == EE_NIL) {
+ synch_handle->last = EE_NIL;
+ }
+
+ if (EE_frsh_updatecapacity(tmp, tmp_time) == EE_UC_InsertRDQueue) {
+ /* In this case, the budhet has been updated and the task is ready to be executed */
+ EE_rq_insert(tmp);
+ }
+
+ EE_th[tmp].status = EE_TASK_READY | EE_TASK_WASSTACKED;
+
+ /* remove the task from the timeout queue */
+ if (EE_frsh_timeout[tmp].synchobj) {
+ /* reset to say that the task is no more waiting with timeout */
+ EE_frsh_timeout[tmp].synchobj = 0;
+
+ /* extract the task from the timeout queue, and eventually reprogram the timer */
+ EE_frsh_timeout_extract(tmp, tmp_time);
+ }
+ } else {
+ synch_handle->count++;
+ }
+
+ /* --- */
+
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+
+ return 0;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_timedwait.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_timedwait.c
new file mode 100644
index 0000000..2549bdc
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_timedwait.c
@@ -0,0 +1,212 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_swait.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+
+/*
+ * From the FRESCOR documentation:
+ *
+ * frsh_timed_wait()
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and that
+ * the scheduler may reassign the unused capacity of the current job to
+ * other vres). It is also invoked when the first job of such threads
+ * has to be scheduled.
+ *
+ * As an effect, the system will make the current vres's budget zero
+ * for the remainder of the vres's period, and will not replenish the
+ * budget until the specified absolute time. At that time, all pending
+ * budget replenishments (if any) are made effective. Once the vres has
+ * a positive budget and the scheduler schedules the calling thread
+ * again, the call returns and at that time, except for those
+ * parameters equal to NULL pointers, the system reports the current
+ * period and budget for the current job, whether the deadline of the
+ * previous job was missed or not, and whether the budget of the
+ * previous job was overrun or not.
+ *
+ * Note about this implementation: The same exceptions to this
+ * description made for the synchobj_wait and timedwait applies.
+ *
+ *
+ * Parameters:
+ * abs_time absolute time at which the budget will be replenished
+ *
+ * next_budget upon return of this function, the variable pointed by this function will be equal to the
+ * current vres budget. If this parameter is set to NULL, no action is taken.
+ *
+ * next_period upon return of this function, the variable pointed by this function will be equal to the
+ * current vres period. If this parameter is set to NULL, no action is taken.
+ *
+ * was_deadline_missed upon return of this function, the variable
+ * pointed by this function will be equal to true if the previous vres
+ * deadline was missed, to false otherwise. If this parameter is set to
+ * NULL, no action is taken.
+ *
+ * was_budget_overrun upon return of this function, the variable
+ * pointed by this function will be equal to true if the previous vres
+ * budget was overrun, to false otherwise. If this parameter is set to
+ * NULL, no action is taken.
+ *
+ * Returns:
+ * 0 if the operation is successful
+ * FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification is in the past.
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH main scheduler
+ * FRSH_ERR_BAD_ARGUMENT : if abs_time is NULL
+ */
+
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+#ifndef __PRIVATE_TIMEOUT_INSERT__
+void EE_frsh_timeout_insert(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_TIMEDWAIT__
+int EE_frsh_timed_wait(const frsh_abs_time_t *abs_time,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+ register int returnvalue = 0;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ /* timeout not valid or in the past */
+ /* I compare with 0, but the IRQ could be really near < min-capacity! */
+ if (!abs_time || ((EE_STIME)(*abs_time - tmp_time)) < 0) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* we always have to exec the check_slice and all the rescheduling
+ * also when the call is non-blocking because we have to fill the
+ * next_budget values! */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the wait behavior. It is identycal to the wait with
+ * timeout operation but without synchobjects */
+
+ /* The running task blocks:
+ * - it must be removed from the ready queue
+ * - and then it must be inserted into the blocked queue */
+
+ /* the task has to be removed from the ready queue */
+
+ if (EE_th[tmp_exec].status & EE_TASK_READY) {
+ EE_rq_extract(tmp_exec);
+
+ /* The task state switch from STACKED TO BLOCKED */
+ EE_th[tmp_exec].status = EE_TASK_BLOCKED | EE_TASK_WASSTACKED;
+
+ /* The VRES becomes inactive */
+ EE_vres[EE_th[tmp_exec].vres].status = EE_VRES_INACTIVE;
+
+ /* the system ceiling is not touched because it is only modified
+ * when locking a mutex */
+
+ /* record the timeout into the data structures */
+ EE_frsh_timeout[tmp_exec].flag = 0;
+ EE_frsh_timeout[tmp_exec].timeout = *abs_time;
+ EE_frsh_timeout[tmp_exec].synchobj = 0; /* no synch objects this time */
+ EE_frsh_timeout_insert(tmp_exec);
+ if (EE_frsh_timeout_first == tmp_exec) {
+ EE_frsh_set_synchobj_timeout_timer(*abs_time - tmp_time);
+ }
+ } else {
+ returnvalue = FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ /* Fill the budget information */
+ if (next_budget) {
+ *next_budget = EE_vres[EE_th[EE_exec].vres].budget_avail;
+ }
+
+ if (next_period) {
+ *next_period = EE_ct[EE_th[EE_exec].vres].period;
+ }
+
+ if (was_deadline_missed) {
+ was_deadline_missed = 0;
+ }
+
+ if (was_budget_overran) {
+ was_budget_overran = 0;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+ return returnvalue;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait.c
new file mode 100644
index 0000000..033dad0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait.c
@@ -0,0 +1,218 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_swait.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+
+/*
+ * From the FRESCOR documentation:
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and that
+ * the scheduler may reassign the unused capacity of the current job to
+ * other vres). This implementation de facto does not void the budget,
+ * but simply does not schedule the task. In fact, the IRIS scheduler
+ * automatically reclaims uniused bandwidth.
+ *
+ * As a difference with frsh_timed_wait(), here the vres specifies to
+ * be awakened by the arrival of a signal operation instead of at a
+ * precise point of time.
+ *
+ * The vres' budget will be made zero for the remainder of the vres'
+ * period, and FRSH will not replenish it until an event has been
+ * notified to the synchronisation object by another vres. It can
+ * happen that the synchronisation object has notification events
+ * queued from the past, in this case one of the events is dequeued
+ * immediately and the vres won't have to wait for another one.
+ *
+ * At the time of reception of a notification event (wether in the
+ * future or in the past), all pending budget replenishments (if any)
+ * are made effective. Once the vres has a positive budget and the
+ * scheduler schedules the calling thread again, the call returns and
+ * the vres continues executing.
+ *
+ * Except for those parameters equal to NULL pointers, the system
+ * reports the current period and budget for the current job, it
+ * informs if the deadline of the previous job was missed or not, and
+ * whether the budget of the previous job was overrun or not. Note:
+ * this implementation using the IRIS scheduler returns the VRES period
+ * and budget (which may not be in sync with the task). For the same
+ * reason, since there is not a direct link of the budget/period of a
+ * vres with the task deadline, the deadline miss and budget overrun
+ * information are not provided (they are meaningless in this
+ * implementation).
+ *
+ *
+ * Parameters:
+ * synch_handle - Synchronisation object upon which the vres will be waiting.
+ * next_budget[out] - Upon return of this function, the variable pointed
+ * by this function will be equal to the current vres
+ * budget. If this parameter is set to NULL, no action is
+ * taken
+ * next_period[out] - The vres period upon return (ignored if NULL).
+ * was_deadline_missed - NOT IMPLEMENTED
+ * was_budget_overran - NOT IMPLEMENTED
+ *
+ * Returns:
+ * 0 if success
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0
+ * FRSH_ERR_INTERNAL_ERROR : if the task still uses a resource
+ *
+ */
+
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+
+
+
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_WAIT__
+int EE_frsh_synchobj_wait(const frsh_synchobj_handle_t synch_handle,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+ register int returnvalue = 0;
+
+ if (synch_handle == 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* we always have to exec the check_slice and all the rescheduling
+ * also when the call is non-blocking because we have to fill the
+ * next_budget values! */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the wait behavior */
+ if (synch_handle->count) {
+ synch_handle->count--;
+ } else {
+ /* The running task blocks:
+ * - it must be removed from the ready queue
+ * - and then it must be inserted into the blocked queue */
+
+ /* TODO: what if the task has still locked a resource? */
+ /* the task has to be removed from the ready queue */
+
+ if (EE_th[tmp_exec].status & EE_TASK_READY) {
+ EE_rq_extract(tmp_exec);
+
+ /* The task state switch from STACKED TO BLOCKED */
+ EE_th[tmp_exec].status = EE_TASK_BLOCKED | EE_TASK_WASSTACKED;
+
+ /* The VRES becomes inactive */
+ EE_vres[EE_th[tmp_exec].vres].status = EE_VRES_INACTIVE;
+
+ /* the system ceiling is not touched because it is only modified
+ * when locking a mutex */
+
+ if (synch_handle->first != EE_NIL) {
+ /* the synchobj queue is not empty */
+ EE_th[synch_handle->last].next = tmp_exec;
+ } else {
+ /* the synchobj queue is empty */
+ synch_handle->first = tmp_exec;
+ }
+
+ synch_handle->last = tmp_exec;
+ EE_th[tmp_exec].next = EE_NIL;
+ } else {
+ returnvalue = FRSH_ERR_INTERNAL_ERROR;
+ }
+ }
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ /* Fill the budget information */
+ if (next_budget) {
+ *next_budget = EE_vres[EE_th[EE_exec].vres].budget_avail;
+ }
+
+ if (next_period) {
+ *next_period = EE_ct[EE_th[EE_exec].vres].period;
+ }
+
+ if (was_deadline_missed) {
+ was_deadline_missed = 0;
+ }
+
+ if (was_budget_overran) {
+ was_budget_overran = 0;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+ return returnvalue;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait_utils.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait_utils.c
new file mode 100644
index 0000000..dffb20b
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_wait_utils.c
@@ -0,0 +1,219 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_swait.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/* This file contains all what is needed to handle the timeout operation */
+
+#ifndef __PRIVATE_TIMEOUT_INSERT__
+void EE_frsh_timeout_insert(EE_TID t)
+{
+ EE_TYPEABSDLINE prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_frsh_timeout_first;
+ prio = EE_frsh_timeout[t].timeout;
+
+ while ((q != EE_NIL) &&
+ (EE_STIME)(prio - EE_frsh_timeout[q].timeout) >= 0
+ ) {
+ p = q;
+ q = EE_frsh_timeout[q].next;
+ }
+
+ if (p != EE_NIL) {
+ EE_frsh_timeout[p].next = t;
+ } else {
+ EE_frsh_timeout_first = t;
+ }
+
+ EE_frsh_timeout[t].next = q;
+}
+
+#endif
+
+
+#ifndef __PRIVATE_TIMEOUT_EXTRACT__
+void EE_frsh_timeout_extract(EE_TID t,
+ EE_TIME tmp_time)
+{
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_frsh_timeout_first;
+
+ while ((q != EE_NIL) && (q != t)) {
+ p = q;
+ q = EE_frsh_timeout[q].next;
+ }
+
+ if (q == EE_NIL) {
+ /* the thread is not there ??? */
+ } else {
+ /* q == t !!! */
+ if (p == EE_NIL) {
+ /* remove the first item in the timeout queue */
+ EE_frsh_timeout_first = EE_frsh_timeout[EE_frsh_timeout_first].next;
+
+ /* reprogram the timer */
+ if (EE_frsh_timeout_first == EE_NIL) {
+ EE_frsh_stop_synchobj_timeout_timer();
+ } else {
+ EE_frsh_set_synchobj_timeout_timer(EE_frsh_timeout[EE_frsh_timeout_first].timeout - tmp_time);
+ }
+ } else {
+ /* remove an item in the middle of the timeout queue */
+ EE_frsh_timeout[p].next = EE_frsh_timeout[q].next;
+ }
+ }
+}
+
+#endif
+
+
+
+/* removes a task from the synchobj queue */
+#ifndef __PRIVATE_SYNCHOBJ_EXTRACT__
+void EE_frsh_synchobj_extract(EE_TID thread)
+{
+ EE_TID p;
+ EE_TID t;
+ frsh_synchobj_handle_t synch_handle = EE_frsh_timeout[thread].synchobj;
+
+ p = EE_NIL;
+ t = synch_handle->first;
+
+ while ((t != EE_NIL) && (t != thread)) {
+ p = t;
+ t = EE_th[t].next;
+ }
+
+ if (t == EE_NIL) {
+ /* the thread is not there ??? */
+ } else {
+ /* t == thread !!! */
+ if (p == EE_NIL) {
+ /* remove the first item in the synchronization object queue */
+ synch_handle->first = EE_th[synch_handle->first].next;
+ } else {
+ /* remove an item in the middle of the synchobject queue */
+ EE_th[p].next = EE_th[t].next;
+ }
+ }
+}
+#endif
+
+
+
+
+
+/*
+ * This routine is called when a primitiev with timeout is called
+ * The result is that one or more tasks are put back into the ready queue with the imeout set.
+ */
+#ifndef __PRIVATE_IRQ_SYNCHOBJ_TIMEOUT__
+void EE_frsh_IRQ_synchobj_timeout(void)
+{
+ register EE_TIME tmp_time;
+ register EE_FREG flag;
+ register EE_TID t;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time */
+ tmp_time = EE_hal_gettime();
+
+ /* Check for expired timeouts */
+ t = EE_frsh_timeout_first;
+ while (t != EE_NIL) {
+ if ((EE_STIME)(EE_frsh_timeout[t].timeout - tmp_time) <= EE_TIMER_MINCAPACITY) {
+ /* remove the task from the timeout queue */
+ EE_frsh_timeout_first = EE_frsh_timeout[t].next;
+
+ /* it could be queued because of the frsh_timed_wait */
+ if (EE_frsh_timeout[t].synchobj) {
+ /* remove the task from the synchobj queue */
+ EE_frsh_synchobj_extract(t);
+
+ /* reset the synchobj value, to say that the task is no more waiting on a synchobject, useful for the signal */
+ EE_frsh_timeout[t].synchobj = 0;
+ }
+
+ /* set the timeout flag */
+ EE_frsh_timeout[t].flag = 1;
+
+ /* wakeup the task pointed by EE_frsh_timeout_first */
+ if (EE_frsh_updatecapacity(t, tmp_time) == EE_UC_InsertRDQueue) {
+ /* In this case, the budhet has been updated and the task is ready to be executed */
+ EE_rq_insert(t);
+ }
+
+ EE_th[t].status = EE_TASK_READY | EE_TASK_WASSTACKED;
+ } else {
+ /* the tasks are ordered by deadline. if one fails, the others are for sure in the future */
+ break;
+ }
+
+ t = EE_frsh_timeout_first;
+ }
+
+ /* t points to the top of the recharging queue */
+
+ /* Program the recharging timer */
+ if (t == EE_NIL) {
+ EE_frsh_stop_synchobj_timeout_timer();
+ } else {
+ EE_frsh_set_synchobj_timeout_timer(EE_frsh_timeout[t].timeout - tmp_time);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_waittimeout.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_waittimeout.c
new file mode 100644
index 0000000..dbd8195
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_syncobj_waittimeout.c
@@ -0,0 +1,203 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_swait.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+
+/*
+ * From the FRESCOR documentation:
+ *
+ * frsh_synchobj_wait_with_timeout()
+ *
+ * This call is the same as frsh_synchobj_wait() but with an extra absolute timeout. The timed_out argument,
+ * indicates whether the function returned because of the expiration of the timeout or not.
+ *
+ * Returns:
+ * 0 if success
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 or the abs_timeout argument is NULL or its value is in the past
+ * FRSH_ERR_INTERNAL_ERROR : if the task still uses a resource
+ *
+ */
+
+
+#ifndef __PRIVATE_TIMEOUT_INSERT__
+void EE_frsh_timeout_insert(EE_TID t);
+#endif
+
+
+
+#ifndef __PRIVATE_FRSH_SYNCOBJ_WAIT_TIMEOUT__
+int EE_frsh_synchobj_wait_with_timeout(const frsh_synchobj_handle_t synch_handle,
+ const frsh_abs_time_t *abs_timeout,
+ bool *timed_out,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+ register int returnvalue = 0;
+
+ if (synch_handle == 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ /* timeout not valid or in the past */
+ /* I compare with 0, but the IRQ could be really near < min-capacity! */
+ if (!abs_timeout || ((EE_STIME)(*abs_timeout - tmp_time)) < 0) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* we always have to exec the check_slice and all the rescheduling
+ * also when the call is non-blocking because we have to fill the
+ * next_budget values! */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the wait behavior */
+ if (synch_handle->count) {
+ synch_handle->count--;
+ } else {
+ /* The running task blocks:
+ * - it must be removed from the ready queue
+ * - and then it must be inserted into the blocked queue */
+
+ /* the task has to be removed from the ready queue */
+
+ if (EE_th[tmp_exec].status & EE_TASK_READY) {
+ EE_rq_extract(tmp_exec);
+
+ /* The task state switch from STACKED TO BLOCKED */
+ EE_th[tmp_exec].status = EE_TASK_BLOCKED | EE_TASK_WASSTACKED;
+
+ /* The VRES becomes inactive */
+ EE_vres[EE_th[tmp_exec].vres].status = EE_VRES_INACTIVE;
+
+ /* the system ceiling is not touched because it is only modified
+ * when locking a mutex */
+
+ if (synch_handle->first != EE_NIL) {
+ /* the synchobj queue is not empty */
+ EE_th[synch_handle->last].next = tmp_exec;
+ } else {
+ /* the synchobj queue is empty */
+ synch_handle->first = tmp_exec;
+ }
+
+ synch_handle->last = tmp_exec;
+ EE_th[tmp_exec].next = EE_NIL;
+
+ /* record the timeout into the data structures */
+ EE_frsh_timeout[tmp_exec].flag = 0;
+ EE_frsh_timeout[tmp_exec].timeout = *abs_timeout;
+ EE_frsh_timeout[tmp_exec].synchobj = synch_handle;
+ EE_frsh_timeout_insert(tmp_exec);
+ if (EE_frsh_timeout_first == tmp_exec) {
+ EE_frsh_set_synchobj_timeout_timer(*abs_timeout - tmp_time);
+ }
+ } else {
+ returnvalue = FRSH_ERR_INTERNAL_ERROR;
+ }
+ }
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ /* Fill the timeout information */
+ if (timed_out) {
+ *timed_out = EE_frsh_timeout[EE_exec].flag;
+ }
+
+ /* Fill the budget information */
+ if (next_budget) {
+ *next_budget = EE_vres[EE_th[EE_exec].vres].budget_avail;
+ }
+
+ if (next_period) {
+ *next_period = EE_ct[EE_th[EE_exec].vres].period;
+ }
+
+ if (was_deadline_missed) {
+ was_deadline_missed = 0;
+ }
+
+ if (was_budget_overran) {
+ was_budget_overran = 0;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+ return returnvalue;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_timers.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_timers.c
new file mode 100644
index 0000000..7c84427
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_timers.c
@@ -0,0 +1,239 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author:2003 Paolo Gai
+ * CVS: $Id: ee_internal.h,v 1.3 2008/07/16 09:46:12 francesco Exp $
+ */
+
+#include "ee_internal.h"
+
+/*
+ * The idea of this file is the following:
+ *
+ * - on some architectures there is just the possibility to have two
+ * timers, one to export a timing reference (basically a free running
+ * timer) and one to export an interrupt source.
+ *
+ * - we need to export a way to treat this single interrupt source as
+ * a set of "virtual" timers, which will expire after some time.
+ *
+ * - we specify the functions which are called after an interrupt in a
+ * static way as consts
+ *
+ * - we program the single interrupt source as the
+ * union of the four timers
+ *
+ * - it must be possible for one IRQ function to reprogram its timer
+ * source without interfering with the others
+ *
+ * - although this can give some precision errors, timer expiration
+ * values are given as relative values. Every time we need to program
+ * the timer, the current time is taken again and an absolute value is
+ * computed. the absolute value is then stored in the data structure to
+ * compute the timer expiration.
+ */
+
+
+/* this is the array of pointers to functions that are called by the
+ * multiplexer */
+
+typedef void (*voidfpointer)(void);
+
+
+const voidfpointer EE_frsh_timer_functions[4] = {
+ EE_frsh_IRQ_budget,
+ EE_frsh_IRQ_recharging,
+ EE_frsh_IRQ_synchobj_timeout,
+ EE_frsh_IRQ_dlcheck
+};
+
+/* This is in the BSS - everything initialized to 0 */
+struct {
+ EE_STIME t;
+ int next;
+ int used;
+} EE_frsh_timer_data[4];
+
+int EE_frsh_timer_first = -1;
+
+void EE_frsh_timer_reprogram(void)
+{
+ EE_STIME tmp;
+
+ /* reprogram the timer */
+ if (EE_frsh_timer_first == -1) {
+ /* nobody is there */
+ EE_hal_stop_budget_timer();
+ } else {
+ /* reprogram the timer */
+ tmp = EE_frsh_timer_data[EE_frsh_timer_first].t - EE_hal_gettime();
+ if (tmp < EE_TIMER_MINCAPACITY) {
+ EE_hal_set_budget_timer(EE_TIMER_MINCAPACITY);
+ } else {
+ EE_hal_set_budget_timer(tmp);
+ }
+ }
+}
+
+
+/* Set timer source "timer" to fire at time t */
+void EE_frsh_timer_set(int timer,
+ EE_STIME t)
+{
+ register EE_STIME cur_time, abs_time;
+ int p, q;
+
+ /* take the absolute time */
+ cur_time = EE_hal_gettime();
+ abs_time = cur_time + t;
+
+ /* cancel the timer if it is running */
+ if (EE_frsh_timer_data[timer].used) {
+ /* This part is similar to stop_timer, but without timer reprogramming */
+ p = -1;
+ q = EE_frsh_timer_first;
+
+ while ((q != -1) && (q != timer)) {
+ p = q;
+ q = EE_frsh_timer_data[q].next;
+ }
+
+ if (q == -1) {
+ /* the timer is not there, something wrong? */
+ } else {
+ /* q == timer !!! */
+ if (p == -1) {
+ /* remove the first item in the timer queue */
+ EE_frsh_timer_first = EE_frsh_timer_data[EE_frsh_timer_first].next;
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_frsh_timer_data[p].next = EE_frsh_timer_data[q].next;
+ }
+ }
+ }
+
+ /* set the value inside the data structure */
+ EE_frsh_timer_data[timer].t = abs_time;
+ EE_frsh_timer_data[timer].used = 1;
+
+ /* insert the timer in the queue */
+ p = -1;
+ q = EE_frsh_timer_first;
+
+ while ((q != -1) &&
+ (EE_STIME)(abs_time - EE_frsh_timer_data[q].t) >= 0
+ ) {
+ p = q;
+ q = EE_frsh_timer_data[q].next;
+ }
+
+ if (p != -1) {
+ EE_frsh_timer_data[p].next = timer;
+ } else {
+ EE_frsh_timer_first = timer;
+
+ /* reprogram the timer */
+ EE_hal_set_budget_timer(t);
+ }
+
+ EE_frsh_timer_data[timer].next = q;
+}
+
+/* Stops timer source "timer" */
+void EE_frsh_timer_stop(int timer)
+{
+ int p;
+ int q;
+
+ p = -1;
+ q = EE_frsh_timer_first;
+
+ while ((q != -1) && (q != timer)) {
+ p = q;
+ q = EE_frsh_timer_data[q].next;
+ }
+
+ if (q == -1) {
+ /* the timer is not there */
+ } else {
+ /* q == timer !!! */
+ if (p == -1) {
+ /* remove the first item in the timer queue */
+ EE_frsh_timer_first = EE_frsh_timer_data[EE_frsh_timer_first].next;
+
+ EE_frsh_timer_reprogram();
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_frsh_timer_data[p].next = EE_frsh_timer_data[q].next;
+ }
+ EE_frsh_timer_data[timer].used = 0;
+ }
+}
+
+/* IRQ handler for the single IRQ */
+void EE_frsh_IRQ_timer_multiplexer(void)
+{
+ register EE_STIME curtime;
+ register EE_FREG flag;
+ register int tmp;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time */
+ curtime = EE_hal_gettime();
+
+ /* loop until there are expired things to do */
+ while (EE_frsh_timer_first != -1 &&
+ (EE_STIME)(EE_frsh_timer_data[EE_frsh_timer_first].t - curtime) < EE_TIMER_MINCAPACITY) {
+ /* update the data structures */
+ EE_frsh_timer_data[EE_frsh_timer_first].used = 0;
+ tmp = EE_frsh_timer_first;
+ EE_frsh_timer_first = EE_frsh_timer_data[EE_frsh_timer_first].next;
+
+ /* call the function */
+ /* note that this function may call EE_frsh_set_timer and EE_frsh_timer_stop */
+ EE_frsh_timer_functions[tmp]();
+ }
+
+ EE_frsh_timer_reprogram();
+
+ EE_hal_end_nested_primitive(flag);
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_unbind.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_unbind.c
new file mode 100644
index 0000000..e26ed5c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_frsh_unbind.c
@@ -0,0 +1,170 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "frsh_core_types.h"
+#include "frsh_error.h"
+
+/*
+ * frsh_thread_unbind()
+ * This operation unbinds a thread from a vres. Since threads with no vres associated are not allowed to
+ * execute, they remain in a dormant state until they are either eliminated or bound again.
+ *
+ * If the thread is inside a critical section the effects of this call are deferred until the critical section is ended
+ *
+ * Returns:
+ * 0 if successful
+ * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist
+ * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid vres bound to it
+ */
+#ifndef __PRIVATE_UNBINDTASK__
+int EE_frsh_UnbindTask(const frsh_thread_id_t thread)
+{
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+ register EE_TID tmp_exec;
+
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (thread < 0 || thread >= EE_MAX_TASK) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+#ifdef __RN_UNBIND__
+ if (thread & EE_REMOTE_TID) {
+ /* forward the request to another CPU */
+ if (EE_rn_send(thread & ~EE_REMOTE_TID, EE_RN_UNBIND, (EE_TYPERN_PARAM)(EE_UREG)0)) {
+ /* a bind or unbind operation is currently pending; maybe we should use a custom return value */
+ return FRSH_ERR_NOT_BOUND;
+ } else {
+ return FRSH_NO_ERROR;
+ }
+ }
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (EE_th[thread].vres == EE_VRES_NIL) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_NOT_BOUND;
+ }
+
+ if (EE_th[thread].vres_deferred != EE_VRES_NIL) {
+ EE_hal_end_nested_primitive(flag);
+ return FRSH_ERR_NOT_BOUND;
+ }
+
+ /* this part is very similar to ActivateTask */
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* implement the bind behavior */
+
+ /* detach the current VRES, and depending on the result do the thread handling */
+
+ if (EE_frsh_bind_detach_thread(thread)) {
+ /* The VRES has been detached
+ * - as a result of detach_vres the task is not inserted in the ready queue
+ *
+ * at this point,
+ *
+ * the task needs to be fixed.
+ */
+
+ /* detach the VRES */
+ EE_th[thread].vres = EE_VRES_NIL;
+
+ /*
+ * The task is in a given status.
+ * Remember that the task is NOT inserted in the ready queue.
+ * If it was in the stacked queue, it remained there.
+ * Depending on the status we have to do some actions among the following (thread status
+ * uppercase, vres status lowercase):
+ *
+ * SUSPENDED
+ * do nothing
+ * READY
+ * the task has already been removed from the ready queue. do nothing
+ * STACKED
+ * the unbind is deferred later, see the else part
+ * BLOCKED
+ * the task is not in the ready queue. do nothing.
+ */
+ } else {
+ /* The VRES has NOT been detached. Store in the detached variable
+ * that the task has to be attached to the new VRES */
+ EE_th[thread].vres_deferred = EE_VRES_UNBOUND;
+ }
+
+ /* --- */
+
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+
+ return FRSH_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_gettime.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_gettime.c
new file mode 100644
index 0000000..c83162f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_gettime.c
@@ -0,0 +1,61 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_gettime.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SYS_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_frsh_sys_gettime()
+{
+ EE_TIME t;
+ register EE_FREG flags;
+
+ flags = EE_hal_begin_nested_primitive();
+ t = EE_hal_gettime();
+ EE_hal_end_nested_primitive(flags);
+ return t;
+}
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_irq_sc.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_irq_sc.c
new file mode 100644
index 0000000..626d20b
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_irq_sc.c
@@ -0,0 +1,95 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_irq_sc.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This function is called at the end of any IRQ Handler.
+ * If the interrupt was not generated by budget timer or
+ * recharging timer (flag EE_served), check whether there is
+ * preemption
+ */
+void EE_IRQ_end_instance(void)
+{
+ register EE_TIME tmp_time;
+ register int wasstacked;
+
+ tmp_time = EE_hal_gettime();
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+ EE_frsh_select_exec();
+ /* --- */
+
+ if (EE_exec != EE_NIL) {
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* reprogram the capacity timer for the new task */
+ EE_frsh_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_IRQ_stacked(EE_exec);
+ } else {
+ EE_hal_IRQ_ready(EE_exec);
+ }
+ } else {
+ /* no task to execute. stop the capacity IRQ */
+ EE_frsh_stop_budget_timer();
+ EE_hal_IRQ_stacked(EE_exec);
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_mutex.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_mutex.c
new file mode 100644
index 0000000..855cbf7
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_mutex.c
@@ -0,0 +1,167 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci, 2009 Paolo Gai
+ * CVS: $Id: ee_mutex.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_frsh_GetResource(EE_TYPERESOURCE m)
+{
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ register EE_FREG flag;
+ flag = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ /* mask off the MSB, that indicates whether this is a global or a
+ * local resource */
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ EE_resource_oldceiling[tmp] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[tmp];
+
+ /* if this is a global resource, lock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_in(tmp);
+ }
+#else
+ EE_resource_oldceiling[m] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[m];
+#endif
+
+ EE_th[EE_exec].lockedcounter++;
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif /* __PRIVATE_MUTEX_LOCK__ */
+
+
+
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_frsh_ReleaseResource(EE_TYPERESOURCE m)
+{
+ register EE_FREG flag;
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+
+#ifdef __MSRP__
+ register EE_TYPERESOURCE tmp;
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ tmp = m & ~EE_GLOBAL_MUTEX;
+
+ /* if this is a global resource, unlock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_out(tmp);
+ }
+
+ EE_sys_ceiling = EE_resource_oldceiling[tmp];
+#else
+ EE_sys_ceiling = EE_resource_oldceiling[m];
+#endif
+
+ EE_th[EE_exec].lockedcounter--;
+
+ /* this part is very similar to ActivateTask */
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* check for deferred unbinds */
+ if (!EE_th[tmp_exec].lockedcounter) {
+ register EE_TYPECONTRACT vres = EE_th[tmp_exec].vres_deferred;
+ EE_th[tmp_exec].vres_deferred = EE_VRES_NIL;
+
+ if (vres == EE_VRES_UNBOUND) {
+ /* The task was unbound but when unbinding it it was into a
+ * resource. We implement the same as an unbind. */
+ EE_frsh_bind_detach_thread(tmp_exec);
+ EE_th[tmp_exec].vres = EE_VRES_NIL;
+ } else if (vres != EE_VRES_NIL) {
+ /* the task has been bound to another VRES. unbind it from the current VRES,
+ * and bind it to the right VRES */
+ EE_frsh_bind_detach_thread(tmp_exec);
+ EE_vres[vres].task = tmp_exec;
+ EE_th[tmp_exec].vres = vres;
+ if (EE_th[tmp_exec].status & EE_TASK_READY) {
+ if (EE_frsh_updatecapacity(tmp_exec, tmp_time) == EE_UC_InsertRDQueue) {
+ EE_rq_insert(tmp_exec);
+ }
+ }
+ }
+ }
+
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif /* __PRIVATE_MUTEX_UNLOCK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rcg_inser.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rcg_inser.c
new file mode 100644
index 0000000..e9cebee
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rcg_inser.c
@@ -0,0 +1,75 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author 2008 Paolo Tiberi & Francesco Focacci
+ * Author 2009 Paolo Gai
+ * CVS: $Id: ee_rcg_inser.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RCG_INSERT__
+void EE_rcg_insert(EE_TYPECONTRACT v)
+{
+ EE_TYPEABSDLINE prio;
+ EE_TYPECONTRACT p, q;
+
+ p = EE_VRES_NIL;
+ q = EE_rcg_queryfirst();
+ prio = EE_vres[v].absdline;
+
+ while ((q != EE_VRES_NIL) &&
+ (EE_STIME)(prio - EE_vres[q].absdline) >= 0
+ ) {
+ p = q;
+ q = EE_vres[q].next;
+ }
+
+ if (p != EE_VRES_NIL) {
+ EE_vres[p].next = v;
+ } else {
+ EE_rcgfirst = v;
+ }
+
+ EE_vres[v].next = q;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_extract.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_extract.c
new file mode 100644
index 0000000..4e9b355
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_extract.c
@@ -0,0 +1,75 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_rq_inser.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_EXTRACT__
+void EE_rq_extract(EE_TID thread)
+{
+ EE_TID p;
+ EE_TID t;
+
+ p = EE_NIL;
+ t = EE_rq_queryfirst();
+
+ while ((t != EE_NIL) && (t != thread)) {
+ p = t;
+ t = EE_th[t].next;
+ }
+
+ if (t == EE_NIL) {
+ /* the thread is not there */
+ } else {
+ /* t == thread !!! */
+ if (p == EE_NIL) {
+ /* remove the first item in the ready queue */
+ EE_rq_getfirst();
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_th[p].next = EE_th[t].next;
+ }
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_inser.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_inser.c
new file mode 100644
index 0000000..d9fa03e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_rq_inser.c
@@ -0,0 +1,76 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_rq_inser.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_INSERT__
+
+/* this function inserts a task into the ready queue */
+void EE_rq_insert(EE_TID t)
+{
+ EE_UINT32 prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_rq_queryfirst();
+ prio = EE_vres[EE_th[t].vres].absdline;
+
+ while ((q != EE_NIL) &&
+ (EE_STIME)(prio - EE_vres[EE_th[q].vres].absdline) >= 0
+ ) {
+ p = q;
+ q = EE_th[q].next;
+ }
+
+ if (p != EE_NIL) {
+ EE_th[p].next = t;
+ } else {
+ EE_rqfirst = t;
+ }
+
+ EE_th[t].next = q;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_schedule.c
new file mode 100644
index 0000000..37869b8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_schedule.c
@@ -0,0 +1,67 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_schedule.c,v 1.6 2006/12/03 22:04:56 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* Inspired to EE_frsh_thread_activate */
+#ifndef __PRIVATE_SCHEDULE__
+void EE_frsh_Schedule(void)
+{
+ register EE_FREG flag;
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+ tmp_exec = EE_exec;
+ EE_frsh_check_slice(tmp_time);
+ EE_frsh_check_recharging(tmp_time);
+ EE_frsh_select_exec();
+ EE_frsh_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thact.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thact.c
new file mode 100644
index 0000000..b4963c2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thact.c
@@ -0,0 +1,130 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_thact.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+
+
+
+#ifndef __PRIVATE_THREAD_ACTIVATE__
+
+void EE_frsh_thread_activate(EE_TID t)
+{
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+ register EE_FREG flag;
+ int rn_ret_val;
+
+#ifdef __RN_TASK__
+ if (t & EE_REMOTE_TID) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1;
+ /* forward the request to another CPU */
+ rn_ret_val = EE_rn_send(t & ~EE_REMOTE_TID, EE_RN_TASK, par);
+ return;
+ }
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time; this will be used later to compute task's
+ * deadlines */
+
+ tmp_time = EE_hal_gettime();
+
+ /* --- */
+
+ /* We activate the task and we put it into the right queue
+ * we also set the scheduling parameters */
+
+ if (EE_th[t].nact == 0) {
+ /* since nact==0, the task has not been stacked before, and so it
+ * is safe to put it in the READY state */
+
+ if (EE_frsh_updatecapacity(t, tmp_time) == EE_UC_InsertRDQueue) {
+ /* In this case, the budhet has been updated and the task is ready to be executed */
+ EE_rq_insert(t);
+ }
+ /* otherwise, the task's VRES has been inserted in the recharging queue! */
+
+ /* EE_frsh_updatecapacity updates the VRES status to either active or recharging */
+ EE_th[t].status = EE_TASK_READY;
+ }
+
+ EE_th[t].nact++;
+ /* --- */
+
+ /* check if in an ISR context
+ * if we are in an ISR context the slice and recharging will be done at the end of the interrupt
+ */
+ if (!EE_hal_get_IRQ_nesting_level()) {
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_frsh_check_slice(tmp_time);
+ /* --- */
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_frsh_select_exec();
+ /* --- */
+
+ EE_frsh_run_exec(tmp_exec);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thendin.c
new file mode 100644
index 0000000..e24f94f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/frsh/src/ee_thendin.c
@@ -0,0 +1,114 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_thendin.c,v 1.7 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+
+int EE_frsh_recharge(EE_TIME);
+
+/* this function MUST NOT BE CALLED BY THE USER!!! */
+void EE_thread_end_instance(void)
+{
+ register EE_TIME tmp_time;
+ register int wasstacked;
+
+ tmp_time = EE_hal_gettime();
+
+ /* decrease the pending activations... ready or stacked => (nact>0) */
+ EE_th[EE_exec].nact--;
+
+ /* this should never happen ... */
+#ifdef DEBUG
+ if (EE_th[EE_exec].lockedcounter) {
+ for (;; ) {
+ ;
+ }
+ }
+#endif
+
+ /* end_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging, ready, or simply put the task suspended). at the end EE_exec is EE_NIL */
+ EE_frsh_end_slice(tmp_time);
+ /* --- */
+
+
+ /* check if the queues are empty and if there is someone in the recharging queue
+ * to activate
+ */
+ EE_frsh_check_recharging(tmp_time);
+ /* --- */
+
+
+ /* the exec task is now EE_NIL.
+ * the next task to execute is either in the stacked or in the ready queue
+ *
+ * we have now to choose between the tasks pointed by stkfirst and
+ * by rqfirst
+ */
+ EE_frsh_select_exec();
+ /* --- */
+
+
+ if (EE_exec == EE_NIL) {
+ /* no task to schedule, go to the main */
+ EE_frsh_stop_budget_timer();
+ EE_hal_endcycle_stacked(EE_exec);
+ } else {
+ /* there is a task to schedule */
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* reprogram the capacity timer for the new task */
+ EE_frsh_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_endcycle_stacked(EE_exec);
+ } else {
+ EE_hal_endcycle_ready(EE_exec);
+ }
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/inc/ee_hard_alarms.h b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/inc/ee_hard_alarms.h
new file mode 100644
index 0000000..246b71d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/inc/ee_hard_alarms.h
@@ -0,0 +1,183 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002,2003 Paolo Gai, Bertozzi Francesco
+ */
+
+
+#ifndef __INCLUDE_ALARMS_ALARMS_H__
+#define __INCLUDE_ALARMS_ALARMS_H__
+
+
+/*************************************************************************
+* Alarm Types
+*************************************************************************/
+
+
+/* alarm id type (signed!) */
+#ifndef EE_TYPEALARM
+#define EE_TYPEALARM EE_SREG
+#endif
+
+/* If you change this definition, you must change the
+ * EE_hal_read_timer, EE_hal_set_timer and
+ * EE_hal_stop_timer too.
+ * You are working on hardware alarm !
+ */
+#define EE_TYPECOUNTER EE_SREG
+
+/* counter tick type */
+#ifndef EE_TYPETICK
+#define EE_TYPETICK EE_UREG
+#endif
+
+/* notification type */
+#ifndef EE_TYPENOTIFY
+#define EE_TYPENOTIFY EE_UINT8
+#endif
+
+/* Interrupt callout */
+#ifndef EE_N_HARD_ALARMS
+#define EE_N_HARD_ALARMS 255
+#endif
+
+#if (0 < EE_N_HARD_ALARMS)
+void EE_altimer0(void);
+#endif
+
+#if (1 < EE_N_HARD_ALARMS)
+void EE_altimer1(void);
+#endif
+
+#if (2 < EE_N_HARD_ALARMS)
+void EE_altimer2(void);
+#endif
+
+/*************************************************************************
+* Variables defined by the application
+*************************************************************************/
+
+typedef EE_TYPEALARM EE_counter_RAM_type; /* first alarm queued on the counter, initvalue: -1 */
+
+/* these are the different types of alarm notifications... */
+#define EE_ALARM_ACTION_TASK 0
+#define EE_ALARM_ACTION_CALLBACK 1
+
+/* initvalue: {a_valid_counter, a_valid_action, then you must put the correct
+ * parameters depending on the action } */
+typedef struct {
+ EE_TYPECOUNTER c; /* the counter linked to the alarm */
+
+ EE_TYPENOTIFY action;
+
+ EE_TID TaskID;
+
+ EE_VOID_CALLBACK f;
+} EE_alarm_ROM_type;
+
+/* initvalue: all zeroes --> no initialization! */
+typedef struct {
+ EE_TYPETICK cycle; /* cycle for periodic alarms */
+ EE_TYPETICK value; /* expiration time (into a queue!) */
+ EE_TYPEALARM next; /* next alarm in the delta queue */
+} EE_alarm_RAM_type;
+
+/* this is the RAM part of a counter.
+ * Initvalue = an array of {0,-1} elements */
+extern EE_counter_RAM_type EE_counter_RAM[];
+
+/* this is the fixed part of the configuration of an alarm
+ * Initvalue= depends on how the alarm notification have to be configured */
+extern const EE_alarm_ROM_type EE_alarm_ROM[];
+
+/* this part is the variable part of an alarm.
+ * Initvalue: an array of {0,0,0,-1} */
+extern EE_alarm_RAM_type EE_alarm_RAM[];
+
+/***************************************************************************
+* Implementation defined functions
+***************************************************************************/
+
+/* This function notifies a tick to a counter. That is, the counter is
+ * incremented by 1. It must be called into an ISR or into a
+ * thread notify that the event linked to the counter occurred.
+ *
+ * The function will also implement the notification of expired alarms
+ * (calling an alarm callback or activating a thread).
+ *
+ * The function is NOT atomic, and NO RESCHEDULING will take place
+ * after the execution of this function. To implement the
+ * rescheduling at task level, you can use the Schedule() function
+ * just after this notification.
+ *
+ * These functions can be called both into a thread and into an ISR.
+ */
+#ifndef __PRIVATE_TIMERALARM__
+void EE_alarm_timer(EE_TYPECOUNTER c);
+#endif
+
+#ifndef __PRIVATE_INSERTALARM__
+void EE_alarm_insert(EE_TYPEALARM AlarmID,
+ EE_TYPETICK value);
+#endif
+
+#ifndef __PRIVATE_GETALARM__
+void EE_alarm_get(EE_TYPEALARM AlarmID,
+ EE_TYPETICK *Tick);
+#endif
+
+#ifndef __PRIVATE_SETRELALARM__
+void EE_alarm_setrel(EE_TYPEALARM AlarmID,
+ EE_TYPETICK increment,
+ EE_TYPETICK cycle);
+#endif
+
+#ifndef __PRIVATE_SETABSALARM__
+void EE_alarm_setabs(EE_TYPEALARM AlarmID,
+ EE_TYPETICK start,
+ EE_TYPETICK cycle);
+#endif
+
+#ifndef __PRIVATE_CANCELALARM__
+void EE_alarm_cancel(EE_TYPEALARM AlarmID);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alcancel.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alcancel.c
new file mode 100644
index 0000000..201b7f2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alcancel.c
@@ -0,0 +1,89 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author:2003 Bertozzi Francesco
+ * CVS: $Id: ee_alcancel.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+#ifndef __PRIVATE_CANCELALARM__
+void EE_alarm_cancel(EE_TYPEALARM AlarmID)
+{
+ register EE_TYPEALARM current, previous;
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c];
+
+ if (current == AlarmID) {
+ /* the alarm is the first one in the delta queue */
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c] =
+ EE_alarm_RAM[AlarmID].next;
+ } else {
+ /* the alarm is not the first one in the delta queue */
+ while (current != AlarmID) {
+ previous = current;
+ current = EE_alarm_RAM[current].next;
+ if (current == -1) {
+ /* alarm not present */
+ EE_hal_end_nested_primitive(flag);
+ return;
+ }
+ }
+ EE_alarm_RAM[previous].next = EE_alarm_RAM[AlarmID].next;
+ }
+
+ if (EE_alarm_RAM[AlarmID].next != -1) {
+ EE_alarm_RAM[EE_alarm_RAM[AlarmID].next].value +=
+ EE_alarm_RAM[AlarmID].value;
+ }
+
+ if (EE_counter_RAM[EE_alarm_ROM[AlarmID].c] == -1) {
+ /* Empty queue */
+ EE_hal_stop_timer(EE_alarm_ROM[AlarmID].c);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alget.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alget.c
new file mode 100644
index 0000000..57b7542
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alget.c
@@ -0,0 +1,72 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Bertozzi Francesco
+ * CVS: $Id: ee_alget.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+#ifndef __PRIVATE_GETALARM__
+void EE_alarm_get(EE_TYPEALARM AlarmID,
+ EE_TYPETICK *Tick)
+{
+ register EE_TYPEALARM current;
+ register EE_FREG flag;
+ register EE_UREG timer_value;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ timer_value = EE_hal_read_timer(EE_alarm_ROM[AlarmID].c);
+
+ /* to compute the relative value in ticks, we have to follow the counter
+ * delay chain */
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c];
+ *Tick = EE_alarm_RAM[current].value - timer_value;
+ while (current != AlarmID) {
+ current = EE_alarm_RAM[current].next;
+ *Tick += EE_alarm_RAM[current].value;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alinsert.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alinsert.c
new file mode 100644
index 0000000..508c75f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alinsert.c
@@ -0,0 +1,100 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Bertozzi Francesco
+ * CVS: $Id: ee_alinsert.c,v 1.2 2005/07/18 14:00:04 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+#ifndef __PRIVATE_INSERTALARM__
+void EE_alarm_insert
+ (EE_TYPEALARM AlarmID,
+ EE_TYPETICK value)
+{
+ register EE_TYPEALARM current, previous;
+ register EE_UREG inf;
+ register EE_SREG res;
+
+ current = EE_counter_RAM[EE_alarm_ROM[AlarmID].c];
+
+ if (current == -1) {
+ /* the alarm becomes the first into the delta queue */
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c] = AlarmID;
+
+ EE_hal_set_timer(EE_alarm_ROM[AlarmID].c, value);
+ } else {
+ inf = EE_alarm_RAM[current].value;
+
+ res = value - inf;
+
+ /* Now I have the delta value from the first element */
+
+ if (res < 0) {
+ /* the alarm becomes however the first into the delta queue */
+ EE_counter_RAM[EE_alarm_ROM[AlarmID].c] = AlarmID;
+ EE_alarm_RAM[current].value -= value;
+
+ EE_hal_set_timer(EE_alarm_ROM[AlarmID].c, value);
+ } else {
+ /* the alarm is not the first into the delta queue */
+
+ /* follow the delta chain until I reach the right place */
+ do {
+ value -= EE_alarm_RAM[current].value;
+ previous = current;
+ current = EE_alarm_RAM[current].next;
+ } while (current != -1 && EE_alarm_RAM[current].value <= value);
+
+ /* insert the alarm between previous and current */
+ if (current != -1) {
+ EE_alarm_RAM[current].value -= value;
+ }
+ EE_alarm_RAM[previous].next = AlarmID;
+ }
+ }
+
+ EE_alarm_RAM[AlarmID].value = value;
+ EE_alarm_RAM[AlarmID].next = current;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetabs.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetabs.c
new file mode 100644
index 0000000..7df242c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetabs.c
@@ -0,0 +1,67 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Bertozzi Francesco
+ * CVS: $Id: ee_alsetabs.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+void EE_alarm_insert(EE_TYPEALARM AlarmID,
+ EE_TYPETICK value);
+
+#ifndef __PRIVATE_SETABSALARM__
+void EE_alarm_setabs(EE_TYPEALARM AlarmID,
+ EE_TYPETICK start,
+ EE_TYPETICK cycle)
+{
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ EE_alarm_RAM[AlarmID].cycle = cycle;
+
+ EE_alarm_insert(AlarmID, start);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetrel.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetrel.c
new file mode 100644
index 0000000..fc6165f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_alsetrel.c
@@ -0,0 +1,69 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Bertozzi Francesco
+ * CVS: $Id: ee_alsetrel.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+void EE_alarm_insert(EE_TYPEALARM AlarmID,
+ EE_TYPETICK value);
+
+#ifndef __PRIVATE_SETRELALARM__
+void EE_alarm_setrel(EE_TYPEALARM AlarmID,
+ EE_TYPETICK increment,
+ EE_TYPETICK cycle)
+{
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ increment += EE_hal_read_timer(EE_alarm_ROM[AlarmID].c);
+ EE_alarm_RAM[AlarmID].cycle = cycle;
+
+ /* then, insert the task into the delta queue with a value = interval */
+ EE_alarm_insert(AlarmID, increment);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_altimer.c b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_altimer.c
new file mode 100644
index 0000000..3f4a3e0
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hard_alarms/src/ee_altimer.c
@@ -0,0 +1,174 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Bertozzi Francesco
+ * CVS: $Id: ee_altimer.c,v 1.6 2007/06/01 09:00:21 pj Exp $
+ */
+
+#include "ee.h"
+#include "hard_alarms/hard_alarms.h"
+
+#ifndef EE_N_HARD_ALARMS
+#define EE_N_HARD_ALARMS 255
+#endif
+
+#if (0 < EE_N_HARD_ALARMS)
+void EE_altimer0(void)
+{
+ EE_alarm_timer(0);
+}
+#endif
+
+#if (1 < EE_N_HARD_ALARMS)
+void EE_altimer1(void)
+{
+ EE_alarm_timer(1);
+}
+#endif
+
+#if (2 < EE_N_HARD_ALARMS)
+void EE_altimer2(void)
+{
+ EE_alarm_timer(2);
+}
+#endif
+
+#ifndef __PRIVATE_TIMERALARM__
+
+void EE_alarm_timer(EE_TYPECOUNTER c)
+{
+ register EE_TYPEALARM current;
+ register EE_TID t;
+ register EE_FREG flag;
+ register EE_SREG res;
+ register EE_UREG inf;
+ int rn_return_val;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ current = EE_counter_RAM[c];
+ inf = EE_hal_read_timer(EE_alarm_ROM[current].c);
+
+ res = EE_alarm_RAM[current].value - inf;
+
+ while (res < 0) {
+ switch (EE_alarm_ROM[current].action) {
+ case EE_ALARM_ACTION_TASK:
+ /* activate the task; NOTE: no preemption at all...
+ * This code was directly copied from ActivateTask
+ */
+ t = EE_alarm_ROM[current].TaskID;
+
+ /* this code is similar to the first part of thread_activate */
+#ifdef __RN_TASK__
+ if (EE_IS_TID_REMOTE(t)) {
+ /* forward the request to another CPU whether the thread do
+ * not become to the current CPU
+ */
+ EE_TYPERN_PARAM par;
+ par.pending = 1;
+ rn_return_val = EE_rn_send((EE_SREG)EE_MARK_REMOTE_TID(t),
+ EE_RN_TASK, par);
+ } else {
+#endif
+ if (EE_th_nact[t] == 0) {
+ /* IDLE
+ * no preemption --> the thread goes into the ready
+ * queue The preemption test will be done into
+ * sys_scheduler()
+ */
+#ifdef __EDF__
+ /* compute the deadline */
+ EE_th_absdline[t] = EE_hal_gettime() + EE_th_reldline[t];
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[t] = EE_READY;
+#endif
+ EE_rq_insert(t);
+ }
+ EE_th_nact[t]++;
+#ifdef __RN_TASK__
+ }
+#endif
+
+ break;
+
+ case EE_ALARM_ACTION_CALLBACK:
+ (EE_alarm_ROM[current].f)();
+ break;
+ };
+
+ /* remove the current entry */
+ EE_counter_RAM[c] = EE_alarm_RAM[current].next;
+
+ /* Update the queue head */
+ if (EE_alarm_RAM[current].next != -1) {
+ EE_alarm_RAM[EE_alarm_RAM[current].next].value +=
+ EE_alarm_RAM[current].value;
+ }
+
+ /* the alarm is cyclic? */
+ if (EE_alarm_RAM[current].cycle) {
+ /* enqueue it again
+ * note: this can modify EE_counter_RAM[c].first!!! see (*)
+ */
+ EE_alarm_insert(current,
+ EE_alarm_RAM[current].value +
+ EE_alarm_RAM[current].cycle);
+ }
+
+ if ((current = EE_counter_RAM[c]) == -1) {
+ EE_hal_stop_timer(c);
+ EE_hal_end_nested_primitive(flag);
+ return;
+ }
+
+ inf = EE_hal_read_timer(EE_alarm_ROM[current].c);
+
+ res = EE_alarm_RAM[current].value - inf;
+ }
+
+ EE_hal_set_timer(EE_alarm_ROM[current].c, EE_alarm_RAM[current].value);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/hr/cfg/cfg.mk
new file mode 100644
index 0000000..1957a4c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/cfg/cfg.mk
@@ -0,0 +1,72 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2013 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2013 Alessandro Biondi
+
+
+ifeq ($(findstring __HR__,$(EEOPT)) , __HR__)
+
+EE_SRCS += pkg/kernel/hr/src/ee_cap.c
+EE_SRCS += pkg/kernel/hr/src/ee_dlcheck.c
+EE_SRCS += pkg/kernel/hr/src/ee_end_budget.c
+EE_SRCS += pkg/kernel/hr/src/ee_end_recharging.c
+EE_SRCS += pkg/kernel/hr/src/ee_hr_contracts.c
+EE_SRCS += pkg/kernel/hr/src/ee_hr_getvresid.c
+EE_SRCS += pkg/kernel/hr/src/ee_hr_getcontract.c
+EE_SRCS += pkg/kernel/hr/src/ee_hr_init.c
+EE_SRCS += pkg/kernel/hr/src/ee_hr_strerror.c
+EE_SRCS += pkg/kernel/hr/src/ee_gettime.c
+EE_SRCS += pkg/kernel/hr/src/ee_irq_sc.c
+EE_SRCS += pkg/kernel/hr/src/ee_mutex.c
+EE_SRCS += pkg/kernel/hr/src/ee_rcg_inser.c
+EE_SRCS += pkg/kernel/hr/src/ee_rq_extract.c
+EE_SRCS += pkg/kernel/hr/src/ee_rq_inser.c
+EE_SRCS += pkg/kernel/hr/src/ee_schedule.c
+EE_SRCS += pkg/kernel/hr/src/ee_thact.c
+EE_SRCS += pkg/kernel/hr/src/ee_thendin.c
+
+
+ifeq ($(findstring __HR_SINGLEIRQ__,$(EEOPT)) , __HR_SINGLEIRQ__)
+EE_SRCS += pkg/kernel/hr/src/ee_hr_timers.c
+endif
+
+endif
+
+
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_api.h
new file mode 100644
index 0000000..96c4bb8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_api.h
@@ -0,0 +1,122 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ * Based on ee_api.h in FRSH, by Paolo Gai (2009)
+ */
+
+
+#ifndef __INCLUDE_KERNEL_HR_EE_API__
+#define __INCLUDE_KERNEL_HR_EE_API__
+
+#if defined(__HR__)
+
+#ifndef Schedule
+#define Schedule EE_hr_Schedule
+#endif
+
+#ifndef ActivateTask
+#define ActivateTask EE_hr_thread_activate
+#endif
+
+#ifndef GetResource
+#define GetResource EE_hr_GetResource
+#endif
+
+#ifndef ReleaseResource
+#define ReleaseResource EE_hr_ReleaseResource
+#endif
+
+#ifndef EE_sys_gettime
+#ifdef __TIME_SUPPORT__
+#define EE_sys_gettime EE_hr_sys_gettime
+#endif
+#endif
+
+/* HR specific API */
+
+#ifndef hr_init
+#define hr_init EE_hr_init
+#endif
+
+#ifndef hr_strerror
+#define hr_strerror EE_hr_strerror
+#endif
+
+/* HR specific API inherited from FRSH */
+
+#ifndef hr_contract_get_basic_params
+#define hr_contract_get_basic_params EE_hr_contract_get_basic_params
+#endif
+
+#ifndef hr_contract_get_timing_reqs
+#define hr_contract_get_timing_reqs EE_hr_contract_get_timing_reqs
+#endif
+
+
+#ifndef hr_thread_get_vres_id
+#define hr_thread_get_vres_id EE_hr_thread_get_vres_id
+#endif
+
+#ifndef hr_vres_get_contract
+#define hr_vres_get_contract EE_hr_vres_get_contract
+#endif
+
+
+#ifndef hr_config_is_admission_test_enabled
+#define hr_config_is_admission_test_enabled EE_hr_config_is_admission_test_enabled
+#endif
+
+#ifndef hr_vres_get_remaining_budget
+#define hr_vres_get_remaining_budget EE_hr_vres_get_remaining_budget
+#endif
+
+#ifndef hr_vres_get_usage
+#define hr_vres_get_usage EE_hr_vres_get_usage
+#endif
+
+#ifndef hr_vres_get_budget_and_period
+#define hr_vres_get_budget_and_period EE_hr_vres_get_budget_and_period
+#endif
+
+
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_common.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_common.h
new file mode 100644
index 0000000..62d35b9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_common.h
@@ -0,0 +1,315 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ *
+ */
+
+#ifndef __INCLUDE_HR_COMMON_H__
+#define __INCLUDE_HR_COMMON_H__
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* invalid TID */
+#define EE_NIL ((EE_TID)-1)
+
+/* invalid TID, used in the VRES task field, to mean that the VRES has
+ * been binded BUT the binding has been deferred. Note that only VRES
+ * which are inactive/freezed may have this value */
+#define EE_TID_DEFERRED ((EE_TID)EE_MAX_TASK)
+
+/* invalid VRES, used for tasks without vres binded to them*/
+#define EE_VRES_NIL ((EE_TYPECONTRACT)-1)
+
+/* placeholder to say that the deferred VRES attached to a task has
+ * been unbound when a task is safely unbound, its vres is
+ * EE_VRES_NIL. We need this value when deferring the bind at the end
+ * of a critical section. This enable to distinguish when there is
+ * nothing to do (EE_VRES_NIL), the VRES have to be unbound
+ * (EE_VRES_UNBOUND), or if there is a new VRES (one of the valid
+ * values)
+ */
+#define EE_VRES_UNBOUND ((EE_TYPECONTRACT)EE_MAX_CONTRACT)
+
+
+/* VRES statuses */
+
+#define EE_VRES_FREEZED 0
+#define EE_VRES_INACTIVE 1
+#define EE_VRES_ACTIVE 2
+#define EE_VRES_RECHARGING 4
+
+
+/* Additional VRES statuses */
+
+#define EE_VRES_INRQ 1
+#define EE_VRES_ALTCEIL 2
+
+
+/* TASK statuses */
+
+#define EE_TASK_SUSPENDED 0
+#define EE_TASK_READY 1
+#define EE_TASK_STACKED 2
+#define EE_TASK_BLOCKED 4
+#define EE_TASK_EXEC 8
+
+/* SCHED ALGO types */
+
+#define EE_SCHED_EDF 0
+#define EE_SCHED_FP 1
+
+
+/* flag used to know if a task has some space allocated on its stack */
+/* WHEN CHANGING THIS WE WILL HAVE TO CHANGE THE ORTI FILE! */
+#define EE_TASK_WASSTACKED 128
+
+#ifndef EE_SYSTEM_MUTEX
+/* the 2nd MSB of MUTEX type indicates if a resource is a system resource (1)
+ * local to a processor or a resource local to a vres (0) */
+#define EE_SYSTEM_MUTEX 0x40000000
+#endif
+
+#ifndef EE_MUTEX_MASK
+/* mask useful for remove the flag that indicates the type of resource (global, system, local) */
+#define EE_MUTEX_MASK 0xC0000000
+#endif
+
+#ifndef EE_MAX_PRIO
+#define EE_MAX_PRIO 0xFF
+#endif
+
+#ifndef EE_NULL_WCRHT
+#define EE_NULL_WCRHT 0
+#endif
+
+#ifndef EE_ZERO_BUDGET
+#define EE_ZERO_BUDGET 0
+#endif
+
+
+/*************************************************************************
+* Kernel Types
+*************************************************************************/
+
+/* priority type, used for system ceiling and preemption level */
+#ifndef EE_TYPEPRIO
+#define EE_TYPEPRIO EE_UREG
+#endif
+
+/* scheduler algo type */
+#ifndef EE_TYPESCHED
+#define EE_TYPESCHED EE_UREG
+#endif
+
+/* status type */
+#ifndef EE_TYPESTATUS
+#define EE_TYPESTATUS EE_UREG
+#endif
+
+/* relative deadline type */
+#ifndef EE_TYPERELDLINE
+#define EE_TYPERELDLINE EE_TIME
+#endif
+
+/* absolute deadline type */
+#ifndef EE_TYPEABSDLINE
+#define EE_TYPEABSDLINE EE_TIME
+#endif
+
+/* capacity type */
+#ifndef EE_TYPEBUDGET
+#define EE_TYPEBUDGET EE_STIME
+#endif
+
+/* pending activation type */
+#ifndef EE_TYPENACT
+#define EE_TYPENACT EE_UREG
+#endif
+
+/* mutex ID type */
+#ifndef EE_TYPERESOURCE
+#define EE_TYPERESOURCE EE_UREG
+#endif
+
+/* contract ID */
+#ifndef EE_TYPECONTRACT
+#define EE_TYPECONTRACT EE_SREG
+#endif
+
+/* vres ID */
+#ifndef EE_TYPEVRES
+#define EE_TYPEVRES EE_UREG
+#endif
+
+/* system resource local ceiling ID */
+#ifndef EE_TYPESYSRESLOCCEIL
+#define EE_TYPESYSRESLOCCEIL EE_UREG
+#endif
+
+/* Contract */
+typedef struct {
+ EE_TYPEBUDGET budget;
+ EE_TYPERELDLINE period;
+ EE_UINT16 inv_proc_util_top;
+ EE_UINT16 inv_proc_util_bot;
+ EE_TYPESCHED sched_algo;
+} EE_TYPECONTRACTSTRUCT;
+
+/* VRES */
+typedef struct {
+ EE_TYPEBUDGET budget_avail; /* available budget (initvalue 0) */
+ EE_TYPEBUDGET usage; /* overall incremental budget used by the vres (initvalue 0) */
+ EE_TYPEABSDLINE absdline; /* absolute deadline (initvalue 0) */
+ EE_TYPESTATUS status; /* status (initvalue freezing that is 0) */
+ EE_TYPESTATUS status2; /* additional non-exclusive status information */
+ EE_TID task; /* head of VRES's ready queue */
+ EE_TYPECONTRACT prev; /* previous vres in the ready queue (initvalue EE_VRES_NIL ) */
+ EE_TYPECONTRACT next; /* next vres in the recharging or ready queue (initvalue EE_VRES_NIL ) */
+ EE_UREG act_tasks; /* number of activated tasks (initvalue 0) */
+ EE_TID stkfirst; /* head of local stacked queue */
+ EE_TYPEPRIO sys_ceiling; /* local system ceiling */
+ EE_TYPEPRIO old_sys_ceiling; /* old local system ceiling */
+ EE_TYPERELDLINE prlevel; /* server preemption level */
+} EE_TYPEVRESSTRUCT;
+
+/* TASK */
+typedef struct {
+ EE_TYPERELDLINE prlevel; /* task preemption level */
+ EE_TYPERELDLINE reldline; /* task relative deadline (EE_SCHED_EDF) or priority (EE_SCHED_FP)*/
+ EE_TYPEABSDLINE absdline; /* absolute deadline (initvalue 0)*/
+ EE_TYPESTATUS status; /* task status (initvalue EE_TASK_SUSPENDED ) */
+ EE_TID next; /* next task in the queue (initvalue EE_NIL ) */
+ EE_TYPENACT nact; /* number of pending activations (initvalue 0) */
+ EE_UREG lockedcounter; /* number of locked resources (initvalue 0) */
+ EE_UREG sys_lockedcounter; /* number of locked system resources (initvalue 0) */
+ EE_TYPECONTRACT vres; /* the vres linked to the task */
+ EE_TYPEBUDGET wc_rht; /* maximum resource holding time for critical sections in the task */
+} EE_TYPETASKSTRUCT;
+
+typedef EE_UREG bool;
+
+/*************************************************************************
+* Kernel Variables
+*************************************************************************/
+
+
+/*************
+* CONTRACTS
+*************/
+
+/* This structure contains the statically defined contract defined into the OIL File */
+extern const EE_TYPECONTRACTSTRUCT EE_ct[];
+
+
+/*************
+* VRES
+*************/
+
+/* This structure contains all the VRES data. (initvalue 0) */
+extern EE_TYPEVRESSTRUCT EE_vres[EE_MAX_CONTRACT];
+
+
+/*************
+* TASKS
+*************/
+
+/* task data */
+extern EE_TYPETASKSTRUCT EE_th[EE_MAX_TASK];
+
+
+/*************
+* GLOBAL
+*************/
+
+/* a temporary value that stores the timer read that was done before
+ * executing a task. That value is useful for capacity accounting
+ * (initvalue: none)
+ */
+extern EE_TIME EE_last_time;
+
+/* system ceiling (initvalue 0) */
+extern EE_TYPEPRIO EE_sys_ceiling;
+
+
+/* The first task into the ready queue -> ready means that the task
+ * has been activated without never running or that it has been
+ * preempted by another task, in both cases without currently locking
+ * any resource
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_rqfirst;
+
+/* The first vres into the ready queue
+ * (initvalue: EE_NIL)
+ */
+extern EE_TYPECONTRACT EE_rqfirst_vres;
+
+/* The first stacked task -> stacked means a preempted task that owns a mutex
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_stkfirst;
+
+/* The first vres in the recharging queue
+ */
+extern EE_TYPECONTRACT EE_rcgfirst;
+
+
+/* The running task
+ * (initvalue: EE_NIL)
+ */
+extern EE_TID EE_exec;
+
+/*************
+* MUTEXES
+*************/
+
+extern const EE_TYPEPRIO EE_local_resource_ceiling[EE_MAX_LOCAL_RESOURCE];
+
+extern EE_TYPEPRIO EE_local_resource_oldceiling[EE_MAX_LOCAL_RESOURCE];
+
+extern const EE_TYPEPRIO EE_sys_resource_ceiling[EE_MAX_SYS_RESOURCE];
+
+extern EE_TYPEPRIO EE_sys_resource_oldceiling[EE_MAX_SYS_RESOURCE];
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_internal.h
new file mode 100644
index 0000000..5182607
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_internal.h
@@ -0,0 +1,423 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ *
+ */
+
+#include "ee_common.h"
+
+#ifndef __INCLUDE_HR_INTERNAL_H__
+#define __INCLUDE_HR_INTERNAL_H__
+
+
+/*************************************************************************
+* Internal data structures
+*************************************************************************/
+
+/* this array is defined in a separate file at the same level of
+ * eecfg.c because it stores the contract names in string format. If
+ * there are no functions called which needs this variable (this is
+ * usually the case) then the variable is not linked to the final
+ * executable.
+ */
+
+extern const char *EE_hr_contract_label[EE_MAX_CONTRACT];
+
+
+/*************************************************************************
+* Internal Queue management functions
+*************************************************************************/
+
+
+#ifndef __PRIVATE_RQ_QUERYFIRST__
+/* return the first ready task without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst(void)
+{
+ return EE_rqfirst;
+}
+#endif
+
+#ifndef __PRIVATE_RQ_QUERYFIRST_VRES__
+/* return the first vres in ready queue without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst_vres(void)
+{
+ return EE_rqfirst_vres;
+}
+#endif
+
+#ifndef __PRIVATE_STK_QUERYFIRST__
+/* return the first stacked task (the running task) without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void)
+{
+ return EE_stkfirst;
+}
+#endif
+
+#ifndef __PRIVATE_LOC_STK_QUERYFIRST__
+/* return the first local stacked task of one vres without extracting it */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_loc_stk_queryfirst(EE_TYPECONTRACT vres)
+{
+ return EE_vres[vres].stkfirst;
+}
+#endif
+
+#ifndef __PRIVATE_RQ_GETFIRST_VRES__
+__INLINE__ void __ALWAYS_INLINE__ EE_rq_getfirst_vres(void)
+{
+ EE_vres[EE_rqfirst_vres].status2 &= ~EE_VRES_INRQ; /* inRQ=0 */
+ EE_rqfirst_vres = EE_vres[EE_rqfirst_vres].next;
+ if (EE_rqfirst_vres != EE_NIL) {
+ EE_vres[EE_rqfirst_vres].prev = EE_NIL;
+ EE_rqfirst = EE_vres[EE_rqfirst_vres].task;
+ } else {
+ EE_rqfirst = EE_NIL;
+ }
+}
+#endif
+
+#ifndef __PRIVATE_RQ_GETFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_rq_getfirst(void)
+{
+ EE_rqfirst = EE_th[EE_rqfirst].next;
+ EE_vres[EE_rqfirst_vres].task = EE_rqfirst;
+ /* if(EE_rqfirst==EE_NIL && EE_vres[EE_rqfirst_vres].stkfirst==EE_NIL) EE_rq_getfirst_vres(); */
+}
+#endif
+
+#ifndef __PRIVATE_STK_GETFIRST__
+/* extract the running task from the stack */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_getfirst(void)
+{
+ EE_stkfirst = EE_th[EE_stkfirst].next;
+}
+#endif
+
+#ifndef __PRIVATE_STK_INSERTFIRST__
+/* insert a task into the stack data structures */
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_insertfirst(EE_TID t)
+{
+ EE_th[t].next = EE_stkfirst;
+ EE_stkfirst = t;
+}
+#endif
+
+#ifndef __PRIVATE_LOC_STK_GETFIRST__
+/* extract the running task from the local stack */
+__INLINE__ void __ALWAYS_INLINE__ EE_loc_stk_getfirst(EE_TYPECONTRACT vres)
+{
+ EE_vres[vres].stkfirst = EE_th[EE_vres[vres].stkfirst].next;
+}
+#endif
+
+#ifndef __PRIVATE_LOC_STK_INSERTFIRST__
+/* insert a task into the local stack data structures */
+__INLINE__ void __ALWAYS_INLINE__ EE_loc_stk_insertfirst(EE_TID t,
+ EE_TYPECONTRACT vres)
+{
+ EE_th[t].next = EE_vres[vres].stkfirst;
+ EE_vres[vres].stkfirst = t;
+}
+#endif
+
+#ifndef __PRIVATE_RCG_QUERYFIRST__
+/* return the first recharging task (the running task) without extracting it */
+__INLINE__ EE_TYPECONTRACT __ALWAYS_INLINE__ EE_rcg_queryfirst(void)
+{
+ return EE_rcgfirst;
+}
+#endif
+
+#ifndef __PRIVATE_RCG_GETFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_rcg_getfirst(void)
+{
+ EE_rcgfirst = EE_vres[EE_rcgfirst].next;
+}
+#endif
+
+/* ------------------------------------- */
+
+#ifndef __PRIVATE_RQ_INSERT__
+/* insert a task into the ready queue */
+void EE_rq_insert(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RQ_INSERT_VRES__
+/* insert a vres into the ready queue */
+void EE_rq_insert_vres(EE_TYPECONTRACT v);
+#endif
+
+#ifndef __PRIVATE_INSERT_IN_VRES__
+/* insert a task into its vres's ready queue */
+void EE_insert_in_vres(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RQ_EXTRACT__
+/* extract a task from the ready queue. if not present, do nothing */
+void EE_rq_extract(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_RQ_EXTRACT_VRES__
+/* extract a vres from the ready queue. if not present, do nothing */
+void EE_rq_extract_vres(EE_TYPECONTRACT v);
+#endif
+
+#ifndef __PRIVATE_RCG_INSERT__
+/* insert a task into the recharging queue */
+void EE_rcg_insert(EE_TYPECONTRACT c);
+#endif
+
+
+#ifndef __PRIVATE_RECHARGEBUDGET__
+void EE_hr_rechargebudget(EE_TYPECONTRACT c);
+#endif
+
+#ifndef __PRIVATE_UPDATECAPACITY__
+/* check the current value of a deadline and updates it following the
+ * IRIS rules */
+
+typedef enum AT {
+ EE_UC_InsertedRCGQueue, EE_UC_InsertRDQueue, EE_UC_NoVres
+} ActionType;
+
+ActionType EE_hr_updatecapacity(EE_TID t,
+ EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_LOCAL_SELECTEXEC__
+void EE_hr_local_select_exec(void);
+#endif
+
+#ifndef __PRIVATE_SELECTEXEC__
+void EE_hr_select_exec(void);
+#endif
+
+#ifndef __PRIVATE_RUNEXEC__
+void EE_hr_run_exec(EE_TID tmp_exec);
+#endif
+
+#ifndef __PRIVATE_CHECKSLICE__
+void EE_hr_check_slice(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_ENDSLICE__
+void EE_hr_end_slice(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_PROCESSRECHARGING__
+int EE_hr_process_recharging(EE_TYPECONTRACT c);
+#endif
+
+#ifndef __PRIVATE_CHECKRECHARGING__
+void EE_hr_check_recharging(EE_TIME tmp_time);
+#endif
+
+#ifndef __PRIVATE_IRQ_RECHARGING__
+void EE_hr_IRQ_recharging(void);
+#endif
+
+#ifndef __PRIVATE_IRQ_BUDGET__
+void EE_hr_IRQ_budget(void);
+#endif
+
+#ifndef __PRIVATE_IRQ_DLCHECK__
+void EE_hr_IRQ_dlcheck(void);
+#endif
+
+#ifdef __HR_SINGLEIRQ__
+void EE_hr_timer_reprogram(void);
+void EE_hr_timer_set(int timer,
+ EE_STIME t);
+void EE_hr_timer_stop(int timer);
+void EE_hr_IRQ_timer_multiplexer(void);
+#endif
+
+
+
+/*************************************************************************
+* Primitives
+*************************************************************************/
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+/* This call terminates a thread instance. It must be called as the
+ * LAST function call BEFORE the `}' that ends a thread. If the
+ * primitive is not inserted at the end of */
+void EE_thread_end_instance(void);
+#endif
+
+
+/*************************************************************************
+* Primitives that have to be called into an IRQ
+*************************************************************************/
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allow IRQ nesting the end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the stack
+ * - if there are other interrupts on the stack the IRQ end_instance should do nothing
+ */
+void EE_IRQ_end_instance(void);
+#endif
+
+
+
+
+/*************************************************************************
+* Timers
+*************************************************************************/
+
+#ifdef __HR_SINGLEIRQ__
+/* only the budget timer is available */
+
+/* these two functions are used to set and stop the budget timer, */
+/* which is the only available when SINGLEIRQ is specified */
+/* the timer parameter is used to understand which interrupt source is called */
+/* and it is statically defined in ee_hr_timers.c */
+
+/* TODO: we could probably do some more work to make this piece of code more */
+/* general, exporting it as a service independent from HR */
+
+void EE_hr_timer_set(int timer,
+ EE_STIME t);
+void EE_hr_timer_stop(int timer);
+
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_budget_timer(EE_STIME t)
+{
+ EE_hr_timer_set(0, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_budget_timer(void)
+{
+ EE_hr_timer_stop(0);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_recharging_timer(EE_STIME t)
+{
+ EE_hr_timer_set(1, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_recharging_timer(void)
+{
+ EE_hr_timer_stop(1);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_dline_timer(EE_STIME t)
+{
+ EE_hr_timer_set(2, t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_dline_timer(void)
+{
+ EE_hr_timer_stop(2);
+}
+
+
+#else
+
+/* Three different hardware timers available */
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_budget_timer(EE_STIME t)
+{
+ EE_hal_set_budget_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_budget_timer(void)
+{
+ EE_hal_stop_budget_timer();
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_recharging_timer(EE_STIME t)
+{
+ EE_hal_set_recharging_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_recharging_timer(void)
+{
+ EE_hal_stop_recharging_timer();
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_set_dline_timer(EE_STIME t)
+{
+ EE_hal_set_dline_timer(t);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_hr_stop_dline_timer(void)
+{
+ EE_hal_stop_dline_timer();
+}
+
+#endif
+
+/*************************************************************************
+* Bandwidth operations
+*************************************************************************/
+/*
+ *
+ * This function computes the multiplication budget_avail*(1/alpha), where
+ * alpha is the bandwidth of a reservation. (1/alpha) is a floating
+ * point value and is stored in the contract struct as follows:
+ * inv_proc_util = ceil((1/alpha)*(2^25))
+ * EE_ct[c].inv_proc_util_top = (inv_proc_util>>16)
+ * EE_ct[c].inv_proc_util_bot = (inv_proc_util&0x0000FFFF)
+ *
+ * In order to avoid constraints on the maximum budget for a reservation
+ * server, the quantity budget_avail*(1/alpha) is calculated using a
+ * result on 64 bits.
+ */
+__INLINE__ EE_TIME __ALWAYS_INLINE__ EE_hr_budget_times_inv_proc_util(EE_TYPECONTRACT c)
+{
+ register EE_UINT32 budget_top = (EE_vres[c].budget_avail >> 16);
+ register EE_UINT32 budget_bot = (EE_vres[c].budget_avail & 0x0000FFFF);
+ register EE_UINT32 res_M, res_H, res_L;
+
+ res_M = (budget_top * EE_ct[c].inv_proc_util_bot + EE_ct[c].inv_proc_util_top * budget_bot);
+ res_H = budget_top * EE_ct[c].inv_proc_util_top + (res_M >> 16);
+ res_L = ((res_M << 16) + budget_bot * EE_ct[c].inv_proc_util_bot);
+
+ res_H = res_H << 7;
+ res_L = res_L >> 25;
+ res_H |= res_L;
+
+ return res_H;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_kernel.h
new file mode 100644
index 0000000..1064a08
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/ee_kernel.h
@@ -0,0 +1,257 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003 Paolo Gai
+ * Edited for HR by Alessandro Biondi (2013)
+ */
+
+#include "kernel/hr/inc/ee_common.h"
+
+#ifndef __INCLUDE_HR_KERN_H__
+#define __INCLUDE_HR_KERN_H__
+
+/* This macros are used to define a task */
+#define DeclareTask(t) void Func##t(void)
+#define TASK(t) void Func##t(void)
+
+/*************************************************************************
+* System functions
+*************************************************************************/
+
+#ifndef __PRIVATE_SYS_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_hr_sys_gettime(void);
+#endif
+#endif
+
+
+/*************************************************************************
+* Primitives
+*************************************************************************/
+
+
+
+
+#ifndef __PRIVATE_THREAD_ACTIVATE__
+void EE_hr_thread_activate(EE_TID t);
+#endif
+
+#ifndef __PRIVATE_SCHEDULE__
+void EE_hr_Schedule(void);
+#endif
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_hr_GetResource(EE_TYPERESOURCE m);
+#endif
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_hr_ReleaseResource(EE_TYPERESOURCE m);
+#endif
+
+
+
+/* FRESCOR API Implementation - inherited from FRSH */
+
+#include "hr_frescor.h"
+
+/* Basic services */
+
+#ifndef __PRIVATE_HR_INIT__
+int EE_hr_init(void);
+#endif
+
+#ifndef __PRIVATE_HR_STRERROR__
+int EE_hr_strerror(int error,
+ char *message,
+ size_t size);
+#endif
+
+
+
+
+/* Contract Creation and initialization */
+
+#ifndef __PRIVATE_HR_CONTRACT_GET_BASIC_PARAMS__
+int EE_hr_contract_get_basic_params(const hr_contract_t *contract,
+ hr_rel_time_t *budget_min,
+ hr_rel_time_t *period_max,
+ hr_workload_t *workload,
+ hr_contract_type_t *contract_type);
+#endif
+
+#ifndef __PRIVATE_HR_CONTRACT_GET_RESOURCE_AND_LABEL__
+int EE_hr_contract_get_resource_and_label(const hr_contract_t *contract,
+ hr_resource_type_t *resource_type,
+ hr_resource_id_t *resource_id,
+ char *contract_label);
+#endif
+
+#ifndef __PRIVATE_HR_CONTRACT_GET_TIMING_REQS__
+int EE_hr_contract_get_timing_reqs(const hr_contract_t *contract,
+ int *d_equals_t,
+ hr_rel_time_t *deadline,
+ hr_signal_t *budget_overrun_signal,
+ hr_signal_info_t *budget_overrun_siginfo,
+ hr_signal_t *deadline_miss_signal,
+ hr_signal_info_t *deadline_miss_siginfo);
+#endif
+
+
+
+
+
+
+/* Negotiate Contract Functions */
+
+
+#ifndef __PRIVATE_GETVRESID__
+int EE_hr_thread_get_vres_id(const hr_thread_id_t thread,
+ hr_vres_id_t *vres_id);
+#endif
+
+#ifndef __PRIVATE_GETCONTRACT__
+int EE_hr_vres_get_contract(const hr_vres_id_t vres,
+ hr_contract_t *contract);
+#endif
+
+
+/*
+ * Returns true if the system is configured with the on-line admission test enabled, or false otherwise. This
+ * situation can only be changed at compile time.
+ */
+#ifdef __PRIVATE_HR_ISADMISSIONTESTENABLED__
+__INLINE__ bool __ALWAYS_INLINE__ EE_hr_config_is_admission_test_enabled(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified vres.
+ *
+ * Returns:
+ *
+ * 0 if successful
+ * HR_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or budget is NULL
+ */
+#ifdef __PRIVATE_HR_GETREMAININGBUDGET__
+int EE_hr_vres_get_remaining_budget(const hr_vres_id_t vres,
+ hr_rel_time_t *budget)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || !budget) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+ *budget = EE_vres[vres].avail_budget;
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+}
+#endif
+
+/*
+ * This function stores the current execution time spent by the threads
+ * bound to the specified vres in the variable pointed to by cpu_time.
+ *
+ * Returns:
+ * 0 if successful
+ * HR_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or spent is
+ * NULL
+ */
+#ifdef __PRIVATE_HR_GETUSAGE__
+int EE_hr_vres_get_usage(const hr_vres_id_t vres,
+ hr_rel_time_t *spent)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || !spent) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+ *spent = EE_vres[vres].usage;
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+}
+#endif
+
+/*
+ * hr_vres_get_budget_and_period()
+ *
+ * This function stores in the variables pointed to by budget and
+ * period, the execution-time budget and the period respectively
+ * associated with the specified vres. If any of these pointers is
+ * NULL, the corresponding information is not stored.
+ *
+ * Returns:
+ *
+ * 0 if successful
+ *
+ * HR_ERR_BAD_ARGUMENT : if the value of the vres argument is not in
+ * range, or budget and period are both NULL
+ */
+#ifdef __PRIVATE_HR_GETBUDGETANDPERIOD__
+int hr_vres_get_budget_and_period(const hr_vres_id_t vres,
+ hr_rel_time_t *budget,
+ hr_rel_time_t *period)
+{
+ register EE_FREG flag;
+
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || (!budget && !period)) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (budget) {
+ *budget = EE_ct[vres].budget;
+ if (period) {
+ *period = EE_ct[vres].period;
+
+ EE_hal_end_nested_primitive(flag);
+ return 0;
+ }
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_frescor.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_frescor.h
new file mode 100644
index 0000000..c466b6b
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_frescor.h
@@ -0,0 +1,191 @@
+/* ----------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* based on previous work (FSF) done in the FIRST project */
+/* */
+/* Copyright (C) 2005 Mälardalen University, SWEDEN */
+/* Scuola Superiore S.Anna, ITALY */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* */
+/* FSF API web pages: http://marte.unican.es/fsf/docs */
+/* http://shark.sssup.it/contrib/first/docs/ */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/* ----------------------------------------------------------------------- */
+/* frsh_error.h */
+/* ============================================== */
+/* ******** ******* ******** ** ** */
+/* ** ///// / ** //// ** ** ////// / ** / ** */
+/* ** / ** / ** / ** / ** / ** */
+/* ******* / ******* / ********* / ********** */
+/* ** //// / ** /// ** //////// ** / ** ////// ** */
+/* ** / ** // ** / ** / ** / ** */
+/* ** / ** // ** ******** / ** / ** */
+/* // // // //////// // // */
+/* */
+/* FRSH(FRescor ScHeduler), pronounced "fresh" */
+/* ============================================== */
+
+
+/* Note for ERIKA Enterprise users: This is a reduced version of the FRESCOR
+ * includes for the HR kernel.*/
+
+
+#ifndef HR_FRESCOR_H_
+#define HR_FRESCOR_H_
+
+
+
+/* ---------------- Error codes ----------------*/
+#define HR_NO_ERROR 0
+
+#define HR_ERR_BASE_VALUE 0x4000
+
+#define HR_ERR_TOO_MANY_TASKS 0x4001
+#define HR_ERR_BAD_ARGUMENT 0x4002
+#define HR_ERR_CONTRACT_REJECTED 0x4005
+#define HR_ERR_NOT_SCHEDULED_CALLING_THREAD 0x4006
+#define HR_ERR_NOT_BOUND 0x4007
+#define HR_ERR_NOT_CONTRACTED_VRES 0x4009
+#define HR_ERR_NOT_SCHEDULED_THREAD 0x400A
+#define HR_ERR_TOO_MANY_SERVICE_JOBS 0x400B
+#define HR_ERR_INTERNAL_ERROR 0x400F
+#define HR_ERR_TOO_MANY_VRES 0x4010
+#define HR_ERR_INVALID_SCHEDULER_REPLY 0x4011
+#define HR_ERR_TOO_MANY_PENDING_REPLENISHMENTS 0x4012
+#define HR_ERR_SYSTEM_ALREADY_INITIALIZED 0x4013
+#define HR_ERR_SCHED_POLICY_NOT_COMPATIBLE 0x4016
+#define HR_ERR_VRES_WORKLOAD_NOT_COMPATIBLE 0x4017
+#define HR_ERR_RESOURCE_ID_INVALID 0x4019
+#define HR_ERR_TOO_LARGE 0x401A
+#define HR_ERR_BUFFER_FULL 0x401B
+#define HR_ERR_NO_SPACE 0x401C
+#define HR_ERR_NO_MESSAGES 0x401D
+#define HR_WRN_MODULE_NOT_SUPPORTED 0x401E
+#define HR_ERR_NOT_INITIALIZED 0x401F
+#define HR_ERR_CONTRACT_LABEL_ALREADY_EXISTS 0x4021
+#define HR_ERR_BUDGET_EXPIRED 0x4022
+#define HR_ERR_NOT_IMPLEMENTED 0x4024
+#define HR_ERR_CONTRACT_TYPE_NOT_COMPATIBLE 0x4025
+#define HR_ERR_CAPACITY_NOT_DECREASING 0x4026
+#define HR_ERR_CONTRACT_LABEL_UNKNOWN 0x4027
+#define HR_ERR_OUT_OF_BUDGET 0x4028
+#define HR_ERR_ALREADY_IN_HR 0x4029
+
+#define HR_ERR_LAST_VALUE 0x4030
+
+/* for size_t */
+#include <string.h>
+
+int hr_strerror(int error,
+ char *message,
+ size_t size);
+
+/* ----------------------------------------------------------*/
+
+/* ---------------- Configuration parameters ----------------*/
+
+#define FRSH_CONTRACT_LABEL_MAXLENGTH 15
+
+/* ----------------------------------------------------------*/
+/* ------------------------ Time types ----------------------*/
+
+#define hr_abs_time_t EE_TYPEABSDLINE
+#define hr_rel_time_t EE_TYPERELDLINE
+
+/* ----------------------------------------------------------*/
+/* ------------------------ Core types ----------------------*/
+
+
+/** identifier of a frsh thread **/
+#define hr_thread_id_t EE_TID
+
+#define hr_signal_t EE_UREG
+#define hr_signal_info_t EE_UREG
+
+
+/** Kind of workload expected in vres: bounded or indeterminate **/
+typedef enum {
+ HR_WT_BOUNDED = 0,
+ HR_WT_INDETERMINATE = 1,
+ HR_WT_SYNCHRONIZED = 2
+} hr_workload_t;
+
+
+#define HR_NULL_DEADLINE 0
+
+#define hr_vres_id_t EE_TYPECONTRACT
+
+/** Contract ressource type: processor, network, memory **/
+typedef enum {
+ HR_RT_PROCESSOR = 0,
+ HR_RT_NETWORK = 1,
+ HR_RT_MEMORY = 2,
+ HR_RT_DISK = 3,
+ HR_RT_FPGA = 4
+} hr_resource_type_t;
+
+/** Ressource Id: processor_id or network_id **/
+/**********************************************/
+#define hr_resource_id_t EE_UREG
+
+/** Kind of contract: regular, background or dummy **/
+typedef enum {
+ HR_CT_REGULAR = 0,
+ HR_CT_BACKGROUND = 1,
+ HR_CT_DUMMY = 2
+} hr_contract_type_t;
+
+/**
+ * Contract parameters type; it is an opaque type (i.e. the internal
+ * structure of this data type is implementation dependent). The user
+ * can access and modify the parameters of a contract only with the
+ * proper functions, and should never access the data directly.
+ **/
+#define hr_contract_t EE_TYPECONTRACTSTRUCT
+
+/* ----------------------------------------------------------*/
+
+
+
+#endif /* !HR_FRESCOR_H_ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_types.h b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_types.h
new file mode 100644
index 0000000..39dd393
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/inc/hr_types.h
@@ -0,0 +1,46 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_common.h"
+
+
+typedef EE_TYPERELDLINE hr_rel_time_t;
+typedef EE_TYPEABSDLINE hr_abs_time_t;
+typedef char bool;
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_cap.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_cap.c
new file mode 100644
index 0000000..4357079
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_cap.c
@@ -0,0 +1,736 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ * Based on ee_cap.c in FRSH, by Paolo Gai (2009)
+ */
+
+#include "ee_internal.h"
+
+
+/* tasks are put into the recharging queue with the following status:
+ * - the budget is always greater then the minimum capacity
+ *
+ * - the period is:
+ *
+ * - if the budget was >0 when the task was interrupted, it is the
+ * former theadline of the task when it was interrupted
+ *
+ * - if the budget was <0 then the deadline is postponed and the
+ * budget incremented until it is greater than 0
+ *
+ * - a problem may occur if the budget is -really- <0 due to shared
+ * resource usage. in that case the task deadline can drift in the
+ * future way over the lifetime of the timer. This is a limitation
+ * we do not address here, because we assume taht the task
+ * parameters and the resource usages are compatible, in other words
+ * the critical sections must be short in order the system to work
+ * fine.
+ */
+
+/* This function recharges a task budget up to a point that it can be
+ * inserted into the recharging queue safely. */
+#ifndef __PRIVATE_RECHARGEBUDGET__
+void EE_hr_rechargebudget(EE_TYPECONTRACT c)
+{
+ for (;; ) {
+ /* recharge the task. */
+ if (EE_vres[c].budget_avail > 0) {
+ /* the budget is positive, and we recharge to the maximum and we exit. */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ break;
+ } else {
+ /* the budget is negative. we sum it and we check if the new budget is enough */
+ EE_vres[c].budget_avail += EE_ct[c].budget;
+ if (EE_vres[c].budget_avail > EE_TIMER_MINCAPACITY) {
+ break;
+ }
+ }
+
+ /* we have to do another round! we update the period and we put the task back */
+ EE_vres[c].absdline += EE_ct[c].period;
+ }
+}
+#endif
+
+
+
+/* this function is called every time a thread is activated
+ * to update his budget available and to check if it should go
+ * recharging
+ *
+ * it is similar to checkslice but it activates a task which for sure
+ * has lockedcounter=0
+ */
+#ifndef __PRIVATE_UPDATECAPACITY__
+ActionType EE_hr_updatecapacity(EE_TID t,
+ EE_TIME tmp_time)
+{
+ EE_TYPECONTRACT c = EE_th[t].vres;
+ EE_TIME t_r;
+
+ /* check if the VRES is UNBOUND. in this case, return nothing. the
+ * capacity is not updated because there is no vres bound to the
+ * task. */
+ if (c == EE_VRES_NIL) {
+ return EE_UC_NoVres;
+ }
+
+ if (EE_vres[c].status == EE_VRES_RECHARGING) {
+ /* the VRES of a task just activated can be recharging in the following scenario:
+ * 1 a task X ends its budget and its vres V goes to recharging
+ * 2 an unbind is called on task X. the vres V remains floating and recharging
+ * 3 a SUSPENDED task Y is binded to the vres V (which is in recharging)
+ * 4 task Y is activated
+ *
+ * If the vres is recharging, we have nothing to do here.
+ */
+ return EE_UC_InsertedRCGQueue;
+ }
+
+ /* if the vres is not active or the current deadline is in the past */
+ if (EE_vres[c].status == EE_VRES_FREEZED || (EE_STIME)(EE_vres[c].absdline - tmp_time) < 0) {
+ /* task deadline is in the past, reset it to the default */
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+
+ /* In this case, we decided to put it equal to the budget because
+ * since the deadline is in the past or the task is not active it
+ * is not worth to check and use a += instead of = . also, using
+ * += does not guarantees that after the sum the capacity is
+ * greater than 0, and so we are not sure we can put the task into
+ * the ready queue! */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ return EE_UC_InsertRDQueue;
+ }
+
+
+ /* Task deadline is in the future */
+
+
+ if (EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY) {
+ /* goes in recharging only if the remaining capacity is less than the minimum capacity
+ */
+
+ if ((EE_exec != EE_NIL) && (c == EE_th[EE_exec].vres)) {
+ EE_rq_insert(EE_exec);
+ }
+ EE_rq_extract_vres(c);
+ EE_hr_rechargebudget(c);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ return EE_UC_InsertedRCGQueue;
+ }
+
+
+
+ /* This is the test of CBS, saying that if the bandwith of the
+ * task considered as the remaining capacity divided by the time
+ * left to the deadline is greater than the nominal bandwidth of
+ * the task we have to reassign the deadlines to avoid that the
+ * task executes too much.*/
+ if (EE_vres[c].status == EE_VRES_INACTIVE) {
+ t_r = EE_vres[c].absdline - (EE_TIME)(EE_hr_budget_times_inv_proc_util(c));
+
+ if ((EE_STIME)(t_r - tmp_time) <= 0) {
+ /* Immediate replenishment */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+ } else {
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ EE_vres[c].absdline = t_r;
+ EE_vres[c].status = EE_VRES_RECHARGING;
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ return EE_UC_InsertedRCGQueue;
+ }
+
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ }
+
+ return EE_UC_InsertRDQueue;
+}
+
+#endif
+
+
+/*
+ * this function select the next task to schedule inside the vres that is on top of ready queue
+ * input status: EE_exec is EE_NIL
+ * result :
+ * EE_exec is set to the next task to schedule
+ * if EE_exec remains EE_NIL, there are no executable tasks inside the considered vres
+ *
+ */
+#ifndef __PRIVATE_LOCAL_SELECTEXEC__
+void EE_hr_local_select_exec(void)
+{
+ register EE_TID tmp_rq;
+ register EE_TID tmp_stk;
+ register EE_TYPECONTRACT tmp_rq_vres;
+ register EE_UREG stk_check = 0;
+
+ tmp_rq = EE_rq_queryfirst();
+ tmp_rq_vres = EE_rq_queryfirst_vres();
+ tmp_stk = EE_loc_stk_queryfirst(tmp_rq_vres);
+
+ /* If the system ceiling of the considered vres was altered using a local ceiling of a system resource,
+ * the local stk queue isn't consistent with the local system ceiling */
+ /*if( (tmp_stk!=EE_NIL)
+ * && (EE_vres[tmp_rq_vres].status2 & EE_VRES_ALTCEIL)
+ * && (EE_th[tmp_stk].prlevel < EE_vres[tmp_rq_vres].sys_ceiling))
+ * {
+ * tmp_stk = EE_NIL;
+ * } */
+
+ if (tmp_rq == EE_NIL) {
+ /* either the first on the stacked queue or nil */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_loc_stk_getfirst(tmp_rq_vres);
+ }
+ } else {
+ switch (EE_ct[EE_th[tmp_rq].vres].sched_algo) {
+ case EE_SCHED_EDF:
+ stk_check = (tmp_stk == EE_NIL) || ((EE_STIME)(EE_th[tmp_stk].absdline - EE_th[tmp_rq].absdline) > 0);
+ break;
+
+ case EE_SCHED_FP:
+ stk_check = (tmp_stk == EE_NIL) || ((EE_th[tmp_rq].reldline - EE_th[tmp_stk].reldline) > 0);
+ break;
+ }
+
+ /* the ready queue is not empty */
+ if (stk_check && (EE_vres[tmp_rq_vres].sys_ceiling < EE_th[tmp_rq].prlevel)) {
+ EE_exec = tmp_rq;
+ EE_rq_getfirst();
+ } else {
+ /* note that if the previous exec task has some locked
+ * resources, then it was put into the stacked queue */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_loc_stk_getfirst(tmp_rq_vres);
+ }
+ }
+ }
+}
+#endif
+
+
+/*
+ * input status: EE_exec is EE_NIL, ready or stacked queue may be full or empty
+ * result:
+ * EE_exec is set to the next task to schedule.
+ * the status is untouched
+ * if EE_exec is different from EE_NIL, then the task has been removed from its queue
+ *
+ * Note: WE CANNOT CHANGE THE STATUS TO EXEC HERE. The status brings
+ * also the flag wasstacked. if we set it, then nothing will work
+ * after this. A solution could be to put wasstacked in a separate
+ * status variable, but I do not want to do that for now.
+ */
+#ifndef __PRIVATE_SELECTEXEC__
+void EE_hr_select_exec(void)
+{
+ register EE_TYPECONTRACT tmp_rq;
+ register EE_TID tmp_stk;
+ register EE_TYPEPRIO prlevel;
+
+ tmp_rq = EE_rq_queryfirst_vres();
+ tmp_stk = EE_stk_queryfirst();
+
+ if (tmp_rq == EE_NIL) {
+ /* either the first on the stacked queue or nil */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_stk_getfirst();
+ }
+ } else {
+ prlevel = (EE_TYPEPRIO)EE_vres[tmp_rq].prlevel;
+
+ /* The ready queue is not empty */
+
+ /* Preemption rule for reservation servers */
+ if (tmp_stk == EE_NIL ||
+ (((EE_STIME)(EE_vres[EE_th[tmp_stk].vres].absdline - EE_vres[tmp_rq].absdline) > 0)
+ && (prlevel > EE_sys_ceiling))) {
+ EE_hr_local_select_exec();
+ }
+
+ if (EE_exec == EE_NIL) {
+ /* note that if the previous exec task has some locked
+ * resources, then it was put into the stacked queue */
+ EE_exec = tmp_stk;
+ if (tmp_stk != EE_NIL) {
+ EE_stk_getfirst();
+ }
+ }
+ }
+}
+#endif
+
+
+/*
+ * If the tmp_exec is different from EE_exec, change context to it.
+ * We suppose that if the task has been put to exec, then it has a valid VRES
+ */
+#ifndef __PRIVATE_RUNEXEC__
+void EE_hr_run_exec(EE_TID tmp_exec)
+{
+ register int wasstacked;
+
+ if (EE_exec == EE_NIL) {
+ /* switch to the background thread if needed */
+ if (tmp_exec != EE_exec) {
+ EE_hal_stkchange(EE_exec);
+ }
+ } else {
+ /* there is a task to schedule */
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* if different from the current running task implement the preemption */
+ if (tmp_exec != EE_exec) {
+ /* reprogram the capacity timer for the new task */
+ EE_hr_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_stkchange(EE_exec);
+ } else {
+ EE_hal_ready2stacked(EE_exec);
+ }
+ }
+ }
+}
+#endif
+
+
+
+
+/*
+ * check_slice
+ *
+ * first considers the exec task, and accounts the elapsed time.
+ *
+ * updates the last timer read
+ *
+ * put the exec task in the right queue:
+ * - stacked if the task has locked resources, independently from the budget
+ * - ready if the task has still budget
+ * - recharging if it has no more budget
+ *
+ * puts exec to EE_NIL
+ */
+
+#ifndef __PRIVATE_CHECKSLICE__
+void EE_hr_check_slice(EE_TIME tmp_time)
+{
+ register EE_TIME delta;
+
+ if (EE_exec != EE_NIL) {
+ EE_TYPECONTRACT c = EE_th[EE_exec].vres;
+
+ /* account the capacity to the task that is currently executing */
+ delta = tmp_time - EE_last_time;
+ EE_vres[c].budget_avail -= delta;
+
+ /* account the overall usage */
+ EE_vres[c].usage += delta;
+
+ if (EE_th[EE_exec].sys_lockedcounter) {
+ /* The task is holding a resource, put it into the stacked queue
+ * regardless of the budget it has.
+ */
+ EE_stk_insertfirst(EE_exec);
+ EE_th[EE_exec].status = EE_TASK_STACKED | EE_TASK_WASSTACKED;
+ /* VRES status unchanged */
+ } else {
+ if (EE_th[EE_exec].lockedcounter) {
+ /* The task is holding a local resource, put it into the local stacked queue */
+
+ EE_loc_stk_insertfirst(EE_exec, EE_th[EE_exec].vres);
+ EE_th[EE_exec].status = EE_TASK_STACKED | EE_TASK_WASSTACKED;
+
+ if (!(EE_vres[EE_th[EE_exec].vres].status2 & EE_VRES_INRQ)) {
+ EE_rq_insert_vres(EE_th[EE_exec].vres);
+ }
+ } else {
+ /* Re-insert the task in ready queue */
+ EE_rq_insert(EE_exec);
+ EE_th[EE_exec].status = EE_TASK_READY | EE_TASK_WASSTACKED;
+ }
+
+ if ((EE_STIME)EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY) {
+ /* if the budget is exhausted then insert in the recharging queue */
+ EE_hr_rechargebudget(c);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+
+ EE_rq_extract_vres(c);
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+ }
+ }
+ }
+
+ /* EE_exec has been inserted into a queue */
+ EE_exec = EE_NIL;
+
+ /* update the last timer read */
+ EE_last_time = tmp_time;
+}
+#endif
+
+
+
+/*
+ * end_slice
+ *
+ * This is similar to check-slice, but it is different because it is
+ * executed at the end of a task.
+ *
+ * first considers the exec task, and accounts the elapsed time.
+ *
+ * updates the last timer read
+ *
+ * put the exec task in the right queue:
+ * if nact >1 and budget>0
+ * the task is put back into the ready queue
+ * if nact =0 and budget >0
+ * the task is suspended waiting for the next activation
+ * if nact >1 and budget <0
+ * the ending task has consumed all its budget.
+ * I put the task in recharging
+ * if nact =0 and budget <0
+ * I cannot put this task in the recharging queue because it is no more active
+ * but it will go in the recharging queue when it will be activated again
+ * so in this case I do nothing
+ *
+ * puts exec to -1
+ */
+
+#ifndef __PRIVATE_ENDSLICE__
+void EE_hr_end_slice(EE_TIME tmp_time)
+{
+ register int time_check;
+ register int nact_check;
+ register EE_TYPECONTRACT c;
+ register EE_TYPEBUDGET delta;
+
+ c = EE_th[EE_exec].vres;
+ /* it can never happen that the vres is UNBOUND because the task
+ * cannot execute without a VRES */
+
+ /* account the capacity to the task that is currently executing */
+ delta = tmp_time - EE_last_time;
+ EE_vres[c].budget_avail -= delta;
+
+ /* account the overall usage */
+ EE_vres[c].usage += delta;
+
+ time_check = (EE_STIME)EE_vres[c].budget_avail < EE_TIMER_MINCAPACITY;
+ nact_check = EE_th[EE_exec].nact;
+
+ if (time_check) {
+ /* nact >= 1 */
+ /* no budget left */
+ if (nact_check) {
+ /* the ending task has consumed all its budget. */
+ /* It has still pending activations */
+
+ /* Update deadline in case of EDF local scheduler */
+ if (EE_ct[EE_th[EE_exec].vres].sched_algo == EE_SCHED_EDF) {
+ EE_th[EE_exec].absdline = tmp_time + EE_th[EE_exec].reldline;
+ }
+
+ EE_th[EE_exec].status = EE_TASK_READY;
+ /* Re-insert task in RQ */
+ EE_rq_insert(EE_exec);
+ } else {
+ EE_th[EE_exec].status = EE_TASK_SUSPENDED;
+ EE_vres[EE_th[EE_exec].vres].act_tasks--;
+ }
+
+ /* If there are active tasks */
+ if (EE_vres[EE_th[EE_exec].vres].act_tasks) {
+ EE_hr_rechargebudget(c);
+ EE_vres[c].status = EE_VRES_RECHARGING;
+
+ /* Extract vres from RQ */
+ EE_rq_extract_vres(c);
+ /* Insert vres in recharging queue */
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+ } else {
+ /* No active tasks */
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ EE_rq_extract_vres(c);
+ }
+
+
+ /* WASSTACKED is not set, because the task just ended */
+ } /* end if(time_check) */
+ else {
+ /* there is still budget */
+ if (nact_check) {
+ /* nact > 1 */
+ /* the task is put back into the ready queue, no need to update the budget */
+
+ /* Update deadline in case of EDF local scheduler */
+ if (EE_ct[EE_th[EE_exec].vres].sched_algo == EE_SCHED_EDF) {
+ EE_th[EE_exec].absdline = tmp_time + EE_th[EE_exec].reldline;
+ }
+
+ EE_rq_insert(EE_exec);
+ /* VRES status unchanged */
+ EE_th[EE_exec].status = EE_TASK_READY;
+ /* WASSTACKED is not set, because the task just ended */
+ } else {
+ /* nact = 0 - tested */
+ /* the task is suspended waiting for the next activation. */
+ /* the budget is left as it was */
+
+ EE_th[EE_exec].status = EE_TASK_SUSPENDED;
+ EE_vres[EE_th[EE_exec].vres].act_tasks--;
+
+ if (!EE_vres[EE_th[EE_exec].vres].act_tasks) {
+ /* if other tasks are READY or STACKED we can't set the vres as INACTIVE */
+
+ /* Extract vres from RQ */
+ EE_rq_extract_vres(c);
+
+
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ }
+ }
+ }
+
+ /* EE_exec has been inserted into a queue or is terminated */
+ EE_exec = EE_NIL;
+
+ /* update the last timer read */
+ EE_last_time = tmp_time;
+}
+#endif
+
+
+
+/* hr_process_recharging
+ *
+ * this function is used to process a recharging VRES when the
+ * recharging time arrive or when the recharging time is reduiced due
+ * to a time-warp.
+ *
+ * The deadline and budget of the VRES is the final one and does not
+ * need any change. The budget is greater than the minimum.
+ *
+ * We have to process the task served by the VRE and understand if
+ * it has to be inserted in any queue
+ *
+ * The function returns 1 when the recharge processed is related to a
+ * VRES without actived tasks. This is important when a time-warp happens,
+ * and the first VRES in the recharging queue is the VRES without
+ * actived tasks. In that case, we have to take another VRES from the queue.
+ */
+#ifndef __PRIVATE_PROCESSRECHARGING__
+int EE_hr_process_recharging(EE_TYPECONTRACT c)
+{
+ /*
+ * VRES status can be:
+ * - one or more actived tasks, at least one active task (in local RQ or stk)
+ * -> VRES set to active and re-inserted in RQ
+ * - no actived tasks (no ready, no stacked tasks)
+ * -> VRES set to inactive
+ */
+
+ if (EE_vres[c].act_tasks) {
+ EE_rq_insert_vres(c);
+
+ EE_vres[c].status = EE_VRES_ACTIVE;
+ return 0;
+ } else {
+ EE_vres[c].status = EE_VRES_INACTIVE;
+ }
+
+ return 1;
+}
+#endif
+
+
+
+
+/*
+ * check-recharging
+ *
+ * if ready and stacked queue are empty pulls from the recharging queue
+ *
+ * it reprograms the recharging IRQ
+ */
+#ifndef __PRIVATE_CHECKRECHARGING__
+void EE_hr_check_recharging(EE_TIME tmp_time)
+{
+ register EE_TYPEBUDGET delta;
+ register EE_TYPECONTRACT c;
+
+ /* if there are not tasks in the ready and in the stacked queue,
+ * check if there are vres in recharging queue and if so, immediately
+ * recharge one or more of them.
+ */
+
+ /* check if the ready and stacked queue are empty */
+ if (EE_stk_queryfirst() != EE_NIL || EE_rq_queryfirst() != EE_NIL || EE_rq_queryfirst_vres() != EE_NIL) {
+ return;
+ }
+
+
+ /*
+ * this first cycle is used to identify a VRES inside the recharging
+ * queue.
+ *
+ * In reality the cycle is needed because it may be that the first n
+ * entries in the VRES queue are related to VRES without a task
+ * attached to them due to bind/unbind. We basically have to process
+ * these VRES until either the recharging queue is empty or we find
+ * a VRES with a task attached to it.
+ */
+ do {
+ /* we take the first vres in the recharging queue.
+ * the tasks has been inserted into the queue with a reasonable budget
+ * (see EE_hr_rechargebudget) */
+ c = EE_rcg_queryfirst();
+
+ /* exit if the recharging queue is empty */
+ if (c == EE_VRES_NIL) {
+ EE_hr_stop_recharging_timer();
+ return;
+ }
+
+ /* remove the vres from the recharging queue */
+ EE_rcg_getfirst();
+
+ /* delta is the amount of time we have to shift all the recharging deadlines */
+ delta = EE_vres[c].absdline - tmp_time;
+
+ /* at this point t is the head of the recharging queue
+ * t has a budget which is > EE_TIMER_MINCAPACITY
+ * t has the deadline which was the one which it was inserted (or postponed) into the recharging queue
+ * c is no more inside the recharging queue
+ * t is not inserted in the ready queue
+ * delta is the shift to be applied to all the tasks remaining in the recharging queue
+ */
+
+ /* we update the deadline of the vres */
+ EE_vres[c].absdline = tmp_time + EE_ct[c].period;
+
+ /* we process the task pointed by the VRES */
+ } while (EE_hr_process_recharging(c));
+
+ /* If we arrive here, it must be that we found a VRES with a task
+ * linked to it, and there are more VRES to process. */
+
+ /* we have to shift all the recharging times by delta */
+ c = EE_rcg_queryfirst();
+ while (c != EE_VRES_NIL) {
+ EE_vres[c].absdline -= delta;
+
+ /* if the deadline is (almost) 0, it means that the task's recharge IRQ once put in the ready queue
+ * will fire in a few microseconds */
+ if ((EE_STIME)(EE_vres[c].absdline - tmp_time) <= EE_TIMER_MINCAPACITY) {
+ /* we have to reassign deadline and budget */
+ /* the check with the minimum capacity is to avoid the recharging interrupt to arrive too early */
+
+ /* update the deadline. Note the deadline has been shifted by delta already */
+ /* The budget has already been set when inserting into the recharging queue */
+ EE_vres[c].absdline += EE_ct[c].period;
+
+
+ /* remove from the top of the recharging queue */
+ EE_rcg_getfirst();
+
+ /* we process the task pointed by the VRES */
+ EE_hr_process_recharging(c);
+
+ c = EE_rcg_queryfirst();
+ } else {
+ /* the recharging queue is ordered by deadline. if one fails, */
+ /* all the rest will fail because they will come later. */
+
+ /* go to the next vres, it has to be processed by the next while */
+ c = EE_vres[c].next;
+ break;
+ }
+ }
+
+ /* do the rest of the vres */
+ while (c != EE_VRES_NIL) {
+ EE_vres[c].absdline -= delta;
+ c = EE_vres[c].next;
+ }
+
+ c = EE_rcg_queryfirst();
+
+ /* at the end of the update, we have to reprogram the recharging IRQ */
+ if (c != EE_VRES_NIL) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ } else {
+ EE_hr_stop_recharging_timer();
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_dlcheck.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_dlcheck.c
new file mode 100644
index 0000000..8c55cf8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_dlcheck.c
@@ -0,0 +1,80 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_dlcheck.c,v 1.7 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+/* PJ: we should initialize this function inside the hr_init */
+/* could we put it into the recharging queue? */
+
+/* option1 --> create a task that calls this */
+/* option2 --> create an alarm with an alarm callback */
+
+#ifndef __PRIVATE_IRQ_DLCHECK__
+/* periodic check of deadline MUST be done with a rate
+ * at least equal to 1/4 of timer capacity*/
+void EE_hr_IRQ_dlcheck(void)
+{
+ register EE_TYPECONTRACT c;
+ register EE_FREG flag;
+ register EE_TIME tmp_time;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+
+ for (c = 0; c < EE_MAX_CONTRACT; c++) {
+ if (EE_vres[c].status != EE_VRES_FREEZED &&
+ (EE_STIME)(tmp_time - EE_vres[c].absdline) > 0) {
+ EE_vres[c].status = EE_VRES_FREEZED;
+ }
+ }
+
+ /* set this as a periodic interrupt */
+ EE_hr_set_dline_timer(EE_TIMER_MAXFUTUREVALUE >> 2);
+
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_budget.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_budget.c
new file mode 100644
index 0000000..d64cb7d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_budget.c
@@ -0,0 +1,51 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_BUDGET__
+/*
+ * The function is empty, because check_slice is called into the end of
+ * the IRQ
+ */
+void EE_hr_IRQ_budget(void)
+{
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_recharging.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_recharging.c
new file mode 100644
index 0000000..348a67d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_end_recharging.c
@@ -0,0 +1,105 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_RECHARGING__
+/*
+ * This routine is called when the recharging time of a task is finished
+ * It basically takes the time, and check all the recharging times which has expired
+ *
+ * Please note that when a server is inserted into the recharging queue
+ * its budget is always greter than the minimum budget, and for this
+ * reason the server (and then its served tasks) can be inserted into the ready queue without
+ * problems.
+ */
+void EE_hr_IRQ_recharging(void)
+{
+ register EE_TIME tmp_time;
+ register EE_FREG flag;
+ register EE_TYPECONTRACT c;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time */
+ tmp_time = EE_hal_gettime();
+
+ /* Check for negative budget and in case re-insert in the rcg queue */
+ c = EE_rcg_queryfirst();
+ while (c != EE_VRES_NIL) {
+ if ((EE_STIME)(EE_vres[c].absdline - tmp_time) <= EE_TIMER_MINCAPACITY) {
+ /* remove the task from the recharging queue */
+ EE_rcg_getfirst();
+
+ /* update the absolute deadline by summing the period. doing
+ * absdeadline = tmp_time+period IS WRONG, because in that way
+ * we have a drift with respect to the recharging implemented
+ * into EE_hr_check_recharging.
+ *
+ * Note that this function is different from
+ * EE_hr_check_recharging, and they cannot be the -same-
+ * function, or we cannot empty this function, because the
+ * EE_hr_check_recharging only works when ready and stacked
+ * queues are empty, whereas this function works in any case.*/
+ EE_vres[c].absdline += EE_ct[c].period;
+
+ /* we process the task pointed by the VRES */
+ EE_hr_process_recharging(c);
+ } else {
+ /* the tasks are ordered by deadline. if one fails, the others are for sure in the future */
+ break;
+ }
+
+ c = EE_rcg_queryfirst();
+ }
+
+ /* c points to the top of the recharging queue */
+
+ /* Program the recharging timer */
+ if (c == EE_VRES_NIL) {
+ EE_hr_stop_recharging_timer();
+ } else {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_gettime.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_gettime.c
new file mode 100644
index 0000000..82bc89a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_gettime.c
@@ -0,0 +1,60 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_gettime.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SYS_GETTIME__
+#ifdef __TIME_SUPPORT__
+EE_TIME EE_hr_sys_gettime()
+{
+ EE_TIME t;
+
+ EE_hal_begin_primitive();
+ t = EE_hal_gettime();
+ EE_hal_end_primitive();
+ return t;
+}
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_contracts.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_contracts.c
new file mode 100644
index 0000000..d1281f5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_contracts.c
@@ -0,0 +1,142 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include <string.h>
+#include "ee_internal.h"
+#include "../inc/hr_frescor.h"
+
+/* ----- Inherited from the FRSH kernel ----- */
+
+/* These functions have been inserted for compatibility with the FRSH API */
+
+/*
+ * hr_contract_get_basic_params()
+ *
+ * This operation obtains from the specified contract object its budget,
+ * period, and workload, and copies them to the places pointed to by the
+ * corresponding output parameters.
+ *
+ * Input Parameters:
+ * - contract the pointer to the contract object
+ *
+ * Output Parameters:
+ * - budget_min pointer to preallocated space
+ * - period_max pointer to preallocated space
+ * - workload pointer to preallocated space
+ * - contract_type pointer to preallocated space
+ *
+ * Returns:
+ * 0 if no error
+ * HR_ERR_BAD_ARGUMENT : if one of the contract or pointers is NULL.
+ *
+ */
+#ifndef __PRIVATE_HR_CONTRACT_GET_BASIC_PARAMS__
+int EE_hr_contract_get_basic_params(const hr_contract_t *contract,
+ hr_rel_time_t *budget_min,
+ hr_rel_time_t *period_max,
+ hr_workload_t *workload,
+ hr_contract_type_t *contract_type)
+{
+ if (!contract || !budget_min || !period_max || !workload || !contract_type) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ *budget_min = contract->budget;
+ *period_max = contract->period;
+ *workload = HR_WT_INDETERMINATE;
+ *contract_type = HR_CT_REGULAR;
+
+ return HR_NO_ERROR;
+}
+#endif
+
+
+
+/*
+ * hr_contract_get_timing_reqs()
+ *
+ * The operation obtains the corresponding input parameters from the
+ * specified contract object. If d_equals_t is true, the deadline will
+ * be set to HR_NULL_DEADLINE.
+ *
+ * Returns:
+ * - 0 if no error
+ * - HR_ERR_BAD_ARGUMENT : if contract is NULL
+ */
+#ifndef __PRIVATE_HR_CONTRACT_GET_TIMING_REQS__
+int EE_hr_contract_get_timing_reqs(const hr_contract_t *contract,
+ int *d_equals_t,
+ hr_rel_time_t *deadline,
+ hr_signal_t *budget_overrun_signal,
+ hr_signal_info_t *budget_overrun_siginfo,
+ hr_signal_t *deadline_miss_signal,
+ hr_signal_info_t *deadline_miss_siginfo)
+{
+ int i;
+
+ if (!contract) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ for (i = 0; i < EE_MAX_CONTRACT; i++) {
+ if (&EE_ct[i] == contract) {
+ break;
+ }
+ }
+
+ if (i == EE_MAX_CONTRACT) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ *d_equals_t = 1;
+ *deadline = HR_NULL_DEADLINE;
+ *budget_overrun_signal = 0;
+ *budget_overrun_siginfo = 0;
+ *deadline_miss_signal = 0;
+ *deadline_miss_siginfo = 0;
+
+ return HR_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getcontract.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getcontract.c
new file mode 100644
index 0000000..d8b298f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getcontract.c
@@ -0,0 +1,74 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * 2013 Alessandro Biondi
+ */
+
+#include "ee_internal.h"
+#include "../inc/hr_frescor.h"
+
+/*
+ * This operation stores the contract parameters currently associated with the specified vres in the variable
+ * pointed to by contract. It returns an error if the vres_id is not recognised.
+ * Returns:
+ * 0 if no error
+ * HR_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value of the vres argument
+ * is not in range
+ */
+#ifndef __PRIVATE_GETCONTRACT__
+int EE_hr_vres_get_contract(const hr_vres_id_t vres,
+ hr_contract_t *contract)
+{
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (vres < 0 || vres >= EE_MAX_CONTRACT || contract == NULL) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ /* no need for interrupt disabling. Contracts are consts... */
+ contract->budget = EE_ct[vres].budget;
+ contract->period = EE_ct[vres].period;
+ contract->inv_proc_util_top = EE_ct[vres].inv_proc_util_top;
+ contract->inv_proc_util_bot = EE_ct[vres].inv_proc_util_bot;
+
+ return 0;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getvresid.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getvresid.c
new file mode 100644
index 0000000..ac3229e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_getvresid.c
@@ -0,0 +1,82 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * Edited for HR by Alessandro Biondi (2013)
+ */
+
+#include "ee_internal.h"
+#include "../inc/hr_frescor.h"
+
+/*
+ * This operation stores the Id of the vres associated with the specified thread in the variable pointed to by
+ * vres. It returns an error if the thread does not exist, it is not under the control of the scheduling framework,
+ * or is not bound.
+ * Returns:
+ * 0 if no error
+ * HR_ERR_NOT_BOUND : if the given thread does not have a valid vres bound to it
+ * HR_ERR_BAD_ARGUMENT : if the given thread does not exist or the vres argument is NULL
+ */
+#ifndef __PRIVATE_GETVRESID__
+int EE_hr_thread_get_vres_id(const hr_thread_id_t thread,
+ hr_vres_id_t *vres_id)
+{
+ register EE_FREG flag;
+
+ /* consistency check on the parameters. these checks does not require interrupt disabling */
+ if (thread < 0 || thread >= EE_MAX_TASK || vres_id == NULL) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (EE_th[thread].vres == EE_VRES_NIL) {
+ EE_hal_end_nested_primitive(flag);
+ return HR_ERR_NOT_BOUND;
+ }
+
+ *vres_id = EE_th[thread].vres;
+
+ EE_hal_end_nested_primitive(flag);
+
+ return 0;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_init.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_init.c
new file mode 100644
index 0000000..9b9f2be
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_init.c
@@ -0,0 +1,70 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ *
+ */
+
+#include "ee_internal.h"
+#include "../inc/hr_frescor.h"
+/* used to check if the initialization has already been done */
+int EE_hr_init_once = 1;
+
+
+#ifndef __PRIVATE_HR_INIT__
+int EE_hr_init(void)
+{
+ if (EE_hr_init_once) {
+ /* must be done once */
+ EE_hr_init_once = 0;
+
+#ifdef OO_CPU_HAS_STARTOS_ROUTINE
+ EE_cpu_startos();
+#endif
+ EE_time_init();
+ EE_hr_time_init();
+
+ return HR_NO_ERROR;
+ } else {
+ return HR_ERR_SYSTEM_ALREADY_INITIALIZED;
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_strerror.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_strerror.c
new file mode 100644
index 0000000..f5ff07a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_strerror.c
@@ -0,0 +1,105 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2009 Paolo Gai
+ * CVS: $Id: ee_cap.c,v 1.6 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+#include "../inc/hr_frescor.h"
+
+
+#ifndef __PRIVATE_HR_STRERROR__
+
+#include <string.h>
+
+static char *EE_hr_strerror_table[] = {
+ "too many tasks",
+ "bad argument",
+ "contract rejected",
+ "not scheduled calling thread",
+ "not bounded vres",
+ "not contracted vres",
+ "not scheduled thread",
+ "internal error",
+ "too many vres",
+ "invalid scheduler reply",
+ "too many pending replenishments",
+ "system already initialized",
+ "sched policy not compatible",
+ "vres workload not compatible",
+ "resource id invalid",
+ "too large",
+ "buffer full",
+ "no space",
+ "no messages",
+ "module not supported",
+ "not initialized",
+ "contract label already exists",
+ "budget expired",
+ "not implemented",
+ "contract type not compatible",
+ "capacity not decreasing",
+ "contract label unknown "
+};
+
+
+/* Converts an error code to a string */
+int EE_hr_strerror(int error,
+ char *message,
+ size_t size)
+{
+ if (error > HR_ERR_LAST_VALUE || error <= HR_ERR_BASE_VALUE) {
+ return HR_ERR_BAD_ARGUMENT;
+ }
+
+ if (message != NULL && size > 0) {
+ /* let's hope the microcontroller has strncpy */
+ strncpy(message,
+ EE_hr_strerror_table[error - HR_ERR_BASE_VALUE - 1],
+ size);
+
+ message[size] = '\0';
+ }
+
+ return HR_NO_ERROR;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_timers.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_timers.c
new file mode 100644
index 0000000..ea24a46
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_hr_timers.c
@@ -0,0 +1,238 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author:2003 Paolo Gai
+ * Edited for HR by Alessandro Biondi (2013)
+ */
+
+#include "ee_internal.h"
+
+/*
+ * The idea of this file is the following:
+ *
+ * - on some architectures there is just the possibility to have two
+ * timers, one to export a timing reference (basically a free running
+ * timer) and one to export an interrupt source.
+ *
+ * - we need to export a way to treat this single interrupt source as
+ * a set of "virtual" timers, which will expire after some time.
+ *
+ * - we specify the functions which are called after an interrupt in a
+ * static way as consts
+ *
+ * - we program the single interrupt source as the
+ * union of the four timers
+ *
+ * - it must be possible for one IRQ function to reprogram its timer
+ * source without interfering with the others
+ *
+ * - although this can give some precision errors, timer expiration
+ * values are given as relative values. Every time we need to program
+ * the timer, the current time is taken again and an absolute value is
+ * computed. the absolute value is then stored in the data structure to
+ * compute the timer expiration.
+ */
+
+
+/* this is the array of pointers to functions that are called by the
+ * multiplexer */
+
+typedef void (*voidfpointer)(void);
+
+
+const voidfpointer EE_hr_timer_functions[3] = {
+ EE_hr_IRQ_budget,
+ EE_hr_IRQ_recharging,
+ EE_hr_IRQ_dlcheck
+};
+
+/* This is in the BSS - everything initialized to 0 */
+struct {
+ EE_STIME t;
+ int next;
+ int used;
+} EE_hr_timer_data[3];
+
+int EE_hr_timer_first = -1;
+
+void EE_hr_timer_reprogram(void)
+{
+ EE_STIME tmp;
+
+ /* reprogram the timer */
+ if (EE_hr_timer_first == -1) {
+ /* nobody is there */
+ EE_hal_stop_budget_timer();
+ } else {
+ /* reprogram the timer */
+ tmp = EE_hr_timer_data[EE_hr_timer_first].t - EE_hal_gettime();
+ if (tmp < EE_TIMER_MINCAPACITY) {
+ EE_hal_set_budget_timer(EE_TIMER_MINCAPACITY);
+ } else {
+ EE_hal_set_budget_timer(tmp);
+ }
+ }
+}
+
+
+/* Set timer source "timer" to fire at time t */
+void EE_hr_timer_set(int timer,
+ EE_STIME t)
+{
+ register EE_STIME cur_time, abs_time;
+ int p, q;
+
+ /* take the absolute time */
+ cur_time = EE_hal_gettime();
+ abs_time = cur_time + t;
+
+ /* cancel the timer if it is running */
+ if (EE_hr_timer_data[timer].used) {
+ /* This part is similar to stop_timer, but without timer reprogramming */
+ p = -1;
+ q = EE_hr_timer_first;
+
+ while ((q != -1) && (q != timer)) {
+ p = q;
+ q = EE_hr_timer_data[q].next;
+ }
+
+ if (q == -1) {
+ /* the timer is not there, something wrong? */
+ } else {
+ /* q == timer !!! */
+ if (p == -1) {
+ /* remove the first item in the timer queue */
+ EE_hr_timer_first = EE_hr_timer_data[EE_hr_timer_first].next;
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_hr_timer_data[p].next = EE_hr_timer_data[q].next;
+ }
+ }
+ }
+
+ /* set the value inside the data structure */
+ EE_hr_timer_data[timer].t = abs_time;
+ EE_hr_timer_data[timer].used = 1;
+
+ /* insert the timer in the queue */
+ p = -1;
+ q = EE_hr_timer_first;
+
+ while ((q != -1) &&
+ (EE_STIME)(abs_time - EE_hr_timer_data[q].t) >= 0
+ ) {
+ p = q;
+ q = EE_hr_timer_data[q].next;
+ }
+
+ if (p != -1) {
+ EE_hr_timer_data[p].next = timer;
+ } else {
+ EE_hr_timer_first = timer;
+
+ /* reprogram the timer */
+ EE_hal_set_budget_timer(t);
+ }
+
+ EE_hr_timer_data[timer].next = q;
+}
+
+/* Stops timer source "timer" */
+void EE_hr_timer_stop(int timer)
+{
+ int p;
+ int q;
+
+ p = -1;
+ q = EE_hr_timer_first;
+
+ while ((q != -1) && (q != timer)) {
+ p = q;
+ q = EE_hr_timer_data[q].next;
+ }
+
+ if (q == -1) {
+ /* the timer is not there */
+ } else {
+ /* q == timer !!! */
+ if (p == -1) {
+ /* remove the first item in the timer queue */
+ EE_hr_timer_first = EE_hr_timer_data[EE_hr_timer_first].next;
+
+ EE_hr_timer_reprogram();
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_hr_timer_data[p].next = EE_hr_timer_data[q].next;
+ }
+ EE_hr_timer_data[timer].used = 0;
+ }
+}
+
+/* IRQ handler for the single IRQ */
+void EE_hr_IRQ_timer_multiplexer(void)
+{
+ register EE_STIME curtime;
+ register EE_FREG flag;
+ register int tmp;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time */
+ curtime = EE_hal_gettime();
+
+ /* loop until there are expired things to do */
+ while (EE_hr_timer_first != -1 &&
+ (EE_STIME)(EE_hr_timer_data[EE_hr_timer_first].t - curtime) < EE_TIMER_MINCAPACITY) {
+ /* update the data structures */
+ EE_hr_timer_data[EE_hr_timer_first].used = 0;
+ tmp = EE_hr_timer_first;
+ EE_hr_timer_first = EE_hr_timer_data[EE_hr_timer_first].next;
+
+ /* call the function */
+ /* note that this function may call EE_hr_set_timer and EE_hr_timer_stop */
+ EE_hr_timer_functions[tmp]();
+ }
+
+ EE_hr_timer_reprogram();
+
+ EE_hal_end_nested_primitive(flag);
+}
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_irq_sc.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_irq_sc.c
new file mode 100644
index 0000000..e8dcb95
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_irq_sc.c
@@ -0,0 +1,95 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_irq_sc.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This function is called at the end of any IRQ Handler.
+ * If the interrupt was not generated by budget timer or
+ * recharging timer (flag EE_served), check whether there is
+ * preemption
+ */
+void EE_IRQ_end_instance(void)
+{
+ register EE_TIME tmp_time;
+ register int wasstacked;
+
+ tmp_time = EE_hal_gettime();
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_hr_check_slice(tmp_time);
+ /* --- */
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_hr_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+ EE_hr_select_exec();
+ /* --- */
+
+ if (EE_exec != EE_NIL) {
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* reprogram the capacity timer for the new task */
+ EE_hr_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_IRQ_stacked(EE_exec);
+ } else {
+ EE_hal_IRQ_ready(EE_exec);
+ }
+ } else {
+ /* no task to execute. stop the capacity IRQ */
+ EE_hr_stop_budget_timer();
+ EE_hal_IRQ_stacked(EE_exec);
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_mutex.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_mutex.c
new file mode 100644
index 0000000..e6630ee
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_mutex.c
@@ -0,0 +1,233 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ *
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_GETRESOURCE__
+void EE_hr_GetResource(EE_TYPERESOURCE m)
+{
+ register EE_TYPERESOURCE tmp;
+ register EE_FREG flag;
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time, delta, t_r;
+ register EE_TYPECONTRACT c;
+
+
+ flag = EE_hal_begin_nested_primitive();
+
+ c = EE_th[EE_exec].vres;
+
+ /* remove the resource type flag */
+ tmp = m & ~EE_MUTEX_MASK;
+
+ if (!(m & EE_SYSTEM_MUTEX)) {
+ /* vres local resource */
+ EE_local_resource_oldceiling[tmp] = EE_vres[c].sys_ceiling;
+ EE_vres[c].sys_ceiling |= EE_local_resource_ceiling[tmp];
+ EE_th[EE_exec].lockedcounter++;
+ } else {
+ /* System or global resource */
+
+ EE_th[EE_exec].sys_lockedcounter++;
+
+ /* update vres local ceiling to maximum value in order to avoid local preemption */
+ EE_vres[c].old_sys_ceiling = EE_vres[c].sys_ceiling;
+ EE_vres[c].sys_ceiling = EE_MAX_PRIO;
+
+ tmp_time = EE_hal_gettime();
+
+ /* account the capacity to the task that is currently executing */
+ delta = tmp_time - EE_last_time;
+ EE_vres[c].budget_avail -= delta;
+
+ /* account the overall usage */
+ EE_vres[c].usage += delta;
+
+ /* update the last timer read */
+ EE_last_time = tmp_time;
+
+ /* A full budget recharge is performed if the available budget is not sufficient to complete the critical section */
+ /* This is an implementation of the BROE protocol */
+ if (EE_th[EE_exec].wc_rht != EE_NULL_WCRHT
+ && EE_th[EE_exec].wc_rht > EE_vres[c].budget_avail) {
+ t_r = EE_vres[c].absdline - (EE_TIME)(EE_hr_budget_times_inv_proc_util(c));
+
+ if (t_r - tmp_time > 0) {
+ /* To not violate the maximum service delay of the reservation, the server is blocked until t_r */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+ EE_vres[c].absdline = t_r;
+ EE_vres[c].status = EE_VRES_RECHARGING;
+
+
+ /* Extract vres from RQ */
+ EE_rq_extract_vres(c);
+ /* Insert vres in recharging queue */
+ EE_rcg_insert(c);
+
+ /* update the recharging IRQ if the activated task becomes the first */
+ if (EE_rcg_queryfirst() == c) {
+ EE_hr_set_recharging_timer(EE_vres[c].absdline - tmp_time);
+ }
+ } else {
+ /* Total budget recharge */
+ EE_vres[c].budget_avail = EE_ct[c].budget;
+
+ /* Deadline shift */
+ EE_vres[c].absdline = t_r + EE_ct[c].period;
+
+ /* Reorder ready queue*/
+ EE_rq_extract_vres(c);
+ EE_rq_insert_vres(c);
+ }
+
+ /* Schedule */
+
+ /* Since the global system ceiling will be incremented when the task grabs the lock,
+ * we have to insert EE_exec in the local stacked queue */
+ EE_loc_stk_insertfirst(EE_exec, c);
+ EE_th[EE_exec].status = EE_TASK_STACKED | EE_TASK_WASSTACKED;
+ /* --- */
+
+ tmp_exec = EE_exec;
+ EE_exec = EE_NIL;
+
+ EE_hr_check_recharging(tmp_time);
+ EE_hr_select_exec();
+
+ EE_hr_run_exec(tmp_exec);
+ }
+
+ /* Here we (should) have sufficient budget to execute the critical section */
+
+ /* update system ceiling and old system ceiling */
+ EE_sys_resource_oldceiling[tmp] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_sys_resource_ceiling[tmp];
+
+
+#ifdef __MSRP__
+ /* if this is a global resource, lock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_in(tmp);
+ }
+#endif
+ } /* End if for *non* local resources */
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif /* __PRIVATE_MUTEX_LOCK__ */
+
+
+/* ----------------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------------------- */
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+void EE_hr_ReleaseResource(EE_TYPERESOURCE m)
+{
+ register EE_FREG flag;
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+
+ register EE_TYPERESOURCE tmp;
+
+ flag = EE_hal_begin_nested_primitive();
+
+#ifdef __MSRP__
+ /* if this is a global resource, unlock the others CPUs */
+ if (m & EE_GLOBAL_MUTEX) {
+ EE_hal_spin_out(tmp);
+ }
+#endif
+
+ tmp = m & ~EE_MUTEX_MASK;
+
+
+ if (!(m & EE_SYSTEM_MUTEX)) {
+ /* vres local resource */
+ EE_vres[EE_th[EE_exec].vres].sys_ceiling = EE_local_resource_oldceiling[tmp];
+ EE_th[EE_exec].lockedcounter--;
+ } else {
+ /* System or global resource */
+
+ /* restore vres local ceiling in order to re-enable local preemption */
+ EE_vres[EE_th[EE_exec].vres].sys_ceiling = EE_vres[EE_th[EE_exec].vres].old_sys_ceiling;
+
+ /* restore system ceiling*/
+ EE_sys_ceiling = EE_sys_resource_oldceiling[tmp];
+
+ EE_th[EE_exec].sys_lockedcounter--;
+ }
+
+
+ /* this part is very similar to ActivateTask */
+
+ tmp_time = EE_hal_gettime();
+
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_hr_check_slice(tmp_time);
+ /* --- */
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_hr_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_hr_select_exec();
+ /* --- */
+
+ EE_hr_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif /* __PRIVATE_MUTEX_UNLOCK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rcg_inser.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rcg_inser.c
new file mode 100644
index 0000000..e9cebee
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rcg_inser.c
@@ -0,0 +1,75 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author 2008 Paolo Tiberi & Francesco Focacci
+ * Author 2009 Paolo Gai
+ * CVS: $Id: ee_rcg_inser.c,v 1.3 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RCG_INSERT__
+void EE_rcg_insert(EE_TYPECONTRACT v)
+{
+ EE_TYPEABSDLINE prio;
+ EE_TYPECONTRACT p, q;
+
+ p = EE_VRES_NIL;
+ q = EE_rcg_queryfirst();
+ prio = EE_vres[v].absdline;
+
+ while ((q != EE_VRES_NIL) &&
+ (EE_STIME)(prio - EE_vres[q].absdline) >= 0
+ ) {
+ p = q;
+ q = EE_vres[q].next;
+ }
+
+ if (p != EE_VRES_NIL) {
+ EE_vres[p].next = v;
+ } else {
+ EE_rcgfirst = v;
+ }
+
+ EE_vres[v].next = q;
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_extract.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_extract.c
new file mode 100644
index 0000000..347868a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_extract.c
@@ -0,0 +1,131 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ *
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_EXTRACT__
+
+void EE_rq_extract_vres(EE_TYPECONTRACT v)
+{
+ /* check for empty RQ */
+ if (EE_rq_queryfirst_vres() == EE_NIL) {
+ return;
+ }
+ if (!(EE_vres[v].status2 & EE_VRES_INRQ)) {
+ return;
+ }
+
+ if (EE_vres[v].prev == EE_NIL) {
+ /* v is the head element */
+ EE_rqfirst_vres = EE_vres[v].next;
+ if (EE_rqfirst_vres != EE_NIL) {
+ EE_rqfirst = EE_vres[EE_rqfirst_vres].task;
+ } else {
+ EE_rqfirst = EE_NIL;
+ }
+ } else {
+ EE_vres[EE_vres[v].prev].next = EE_vres[v].next;
+ }
+
+ if (EE_vres[v].next != EE_NIL) {
+ EE_vres[EE_vres[v].next].prev = EE_vres[v].prev;
+ }
+
+
+ EE_vres[v].status2 &= ~EE_VRES_INRQ; /* inRQ=0 */
+}
+
+/* -------------------------------------------------------------------- */
+
+void EE_rq_extract(EE_TID thread)
+{
+ EE_TID p, t;
+
+#ifdef DEBUG
+ /* check for incorrect parameters */
+ if ((thread == EE_NIL) || (thread >= EE_MAX_TASK)) {
+ return;
+ }
+ if ((EE_th[thread].vres == EE_NIL) || (EE_th[thread].vres >= EE_MAX_CONTRACT)) {
+ return;
+ }
+ if (!(EE_vres[EE_th[thread].vres].status2 & EE_VRES_INRQ)) {
+ return;
+ }
+#endif
+
+ p = EE_NIL;
+ t = EE_vres[EE_th[thread].vres].task;
+
+ while ((t != EE_NIL) && (t != thread)) {
+ p = t;
+ t = EE_th[t].next;
+ }
+
+ if (t == EE_NIL) {
+ /* the thread is not there */
+ return;
+ }
+
+ /* t == thread !!! */
+ if (p == EE_NIL) {
+ /* thread is the first in its queue */
+
+ if (EE_th[thread].vres == EE_rqfirst_vres) {
+ EE_rq_getfirst(); /* remove the first item in RQ */
+ } else {
+ EE_vres[EE_th[thread].vres].task = EE_th[thread].next;
+
+ /* remove vres from RQ if its queues become empty */
+ /* if(EE_vres[EE_th[thread].vres].task==EE_NIL && EE_vres[EE_th[thread].vres].stkfirst==EE_NIL) */
+ /* EE_rq_extract_vres(EE_th[thread].vres); */
+ }
+ } else {
+ /* remove an item in the middle of the ready queue */
+ EE_th[p].next = EE_th[t].next;
+ }
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_inser.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_inser.c
new file mode 100644
index 0000000..e5e0969
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_rq_inser.c
@@ -0,0 +1,169 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ *
+ */
+
+
+/*
+ * The ready queue is structured as a multi-level queue. The first level is for the vres; for
+ * each vres we have the queue of the served tasks. The queues of tasks are ordered in function
+ * of the scheduling algorithm used upon the vres.
+ *
+ * | VRES_1 | --> (Task1_1)-->(Task2_1)...
+ * | VRES_2 | --> (Task1_2)-->(Task2_2)...
+ * ...
+ * | VRES_n | --> (Task1_n)-->(Task2_n)...
+ *
+ *
+ * When a task is executing it is not in the ready queue, whereas its vres remains in the ready queue.
+ * This is to simplify the operations on the global stacked queue.
+ *
+ * The first level (queue of vres) is implemented with a double-linked list.
+ *
+ * EE_rqfirst is the first task of the first vres;
+ * EE_rqfirst_vres is the first vres.
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_INSERT_VRES__
+
+void EE_rq_insert_vres(EE_TYPECONTRACT v)
+{
+ int prio;
+ EE_TYPECONTRACT p, q;
+
+ p = EE_NIL;
+ q = EE_rq_queryfirst_vres();
+ prio = EE_vres[v].absdline;
+
+ while ((q != EE_NIL) &&
+ (EE_STIME)(prio - EE_vres[q].absdline) >= 0
+ ) {
+ p = q;
+ q = EE_vres[q].next;
+ }
+
+ EE_vres[v].prev = p;
+
+ if (p != EE_NIL) {
+ EE_vres[p].next = v;
+ } else {
+ EE_rqfirst_vres = v;
+ EE_rqfirst = EE_vres[v].task;
+ }
+
+ EE_vres[v].next = q;
+ if (q != EE_NIL) {
+ EE_vres[q].prev = v;
+ }
+
+ EE_vres[v].status2 |= EE_VRES_INRQ; /* set flag */
+}
+
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#ifndef __PRIVATE_INSERT_IN_VRES__
+
+void EE_insert_in_vres(EE_TID t)
+{
+ int prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_vres[EE_th[t].vres].task;/* first in VRES's RQ */
+
+ switch (EE_ct[EE_th[t].vres].sched_algo) {
+ case EE_SCHED_EDF:
+ prio = EE_th[t].absdline;
+
+ while ((q != EE_NIL) &&
+ (EE_STIME)(prio - EE_th[q].absdline) >= 0
+ ) {
+ p = q;
+ q = EE_th[q].next;
+ }
+ break;
+
+ case EE_SCHED_FP:
+ prio = EE_th[t].reldline;
+
+ while ((q != EE_NIL) && (prio <= EE_th[q].reldline)) {
+ p = q;
+ q = EE_th[q].next;
+ }
+
+ break;
+ }
+
+ if (p != EE_NIL) {
+ EE_th[p].next = t;
+ } else {
+ EE_vres[EE_th[t].vres].task = t;
+ if (EE_th[t].vres == EE_rqfirst_vres) {
+ EE_rqfirst = t;
+ }
+ }
+
+ EE_th[t].next = q;
+}
+
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#ifndef __PRIVATE_RQ_INSERT__
+
+void EE_rq_insert(EE_TID t)
+{
+ if (!(EE_vres[EE_th[t].vres].status2 & EE_VRES_INRQ)) {
+ EE_rq_insert_vres(EE_th[t].vres);
+ }
+
+ /* insert task into VRES's RQ */
+ EE_insert_in_vres(t);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_schedule.c
new file mode 100644
index 0000000..e13195a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_schedule.c
@@ -0,0 +1,67 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2009 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001 Paolo Gai
+ * CVS: $Id: ee_schedule.c,v 1.6 2006/12/03 22:04:56 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* Inspired to EE_hr_thread_activate */
+#ifndef __PRIVATE_SCHEDULE__
+void EE_hr_Schedule(void)
+{
+ register EE_FREG flag;
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ tmp_time = EE_hal_gettime();
+ tmp_exec = EE_exec;
+ EE_hr_check_slice(tmp_time);
+ EE_hr_check_recharging(tmp_time);
+ EE_hr_select_exec();
+ EE_hr_run_exec(tmp_exec);
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thact.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thact.c
new file mode 100644
index 0000000..6538da8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thact.c
@@ -0,0 +1,140 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2013 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2013 Alessandro Biondi
+ * Based on ee_thact.c in FRSH, by Paolo Gai (2009)
+ */
+
+#include "ee_internal.h"
+
+
+#ifndef __PRIVATE_THREAD_ACTIVATE__
+
+void EE_hr_thread_activate(EE_TID t)
+{
+ register EE_TID tmp_exec;
+ register EE_TIME tmp_time;
+ register EE_FREG flag;
+
+#ifdef __RN_TASK__
+ if (t & EE_REMOTE_TID) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1;
+ /* forward the request to another CPU */
+ EE_rn_send(t & ~EE_REMOTE_TID, EE_RN_TASK, par);
+ return;
+ }
+#endif
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* read the current time; this will be used later to compute task's
+ * deadlines */
+
+ tmp_time = EE_hal_gettime();
+
+ /* --- */
+
+ /* We activate the task and we put it into the right queue
+ * we also set the scheduling parameters */
+
+ if (EE_th[t].nact == 0) {
+ /* since nact==0, the task has not been stacked before, and so it
+ * is safe to put it in the READY state */
+
+ /* Update deadline in case of EDF local scheduler */
+ if (EE_ct[EE_th[t].vres].sched_algo == EE_SCHED_EDF) {
+ EE_th[t].absdline = tmp_time + EE_th[t].reldline;
+ }
+
+
+ if (EE_hr_updatecapacity(t, tmp_time) == EE_UC_InsertRDQueue) {
+ /* In this case, the budget has been updated and the task is ready to be executed */
+ EE_rq_insert(t);
+ } else {
+ /* EE_UC_InsertedRCGQueue */
+ /* otherwise, the task's VRES has been inserted in the recharging queue! */
+ /* we have to insert the task (READY) in its vres */
+ EE_insert_in_vres(t);
+ }
+
+ /* EE_hr_updatecapacity updates the VRES status to either active or recharging */
+ EE_th[t].status = EE_TASK_READY;
+
+ /* Increment number of activated tasks */
+ EE_vres[EE_th[t].vres].act_tasks++;
+ }
+
+ EE_th[t].nact++;
+ /* --- */
+
+ /* check if in an ISR context
+ * if we are in an ISR context the slice and recharging will be done at the end of the interrupt
+ */
+ if (!EE_hal_get_IRQ_nesting_level()) {
+ /* save the current running task into a temporary variable */
+ tmp_exec = EE_exec;
+ /* --- */
+
+ /* check_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging or ready). at the end EE_exec is EE_NIL */
+ EE_hr_check_slice(tmp_time);
+ /* --- */
+
+ /* check_recharging: if ready and stacked queue are empty pulls from the recharging queue */
+ EE_hr_check_recharging(tmp_time);
+ /* --- */
+
+ /* at this point, exec is for sure EE_NIL (it is set by check_slice) */
+ /* select the first task from the ready or stacked queue */
+ /* the function set the EE_exec value, removing the task from the queue
+ * the status is untouched */
+
+ EE_hr_select_exec();
+ /* --- */
+
+ EE_hr_run_exec(tmp_exec);
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thendin.c
new file mode 100644
index 0000000..ecc8e4a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/hr/src/ee_thendin.c
@@ -0,0 +1,114 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2008 Paolo Tiberi & Francesco Focacci
+ * CVS: $Id: ee_thendin.c,v 1.7 2008/07/18 09:53:55 tiberipa Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+
+int EE_hr_recharge(EE_TIME);
+
+/* this function MUST NOT BE CALLED BY THE USER!!! */
+void EE_thread_end_instance(void)
+{
+ register EE_TIME tmp_time;
+ register int wasstacked;
+
+ tmp_time = EE_hal_gettime();
+
+ /* decrease the pending activations... ready or stacked => (nact>0) */
+ EE_th[EE_exec].nact--;
+
+ /* this should never happen ... */
+#ifdef DEBUG
+ if (EE_th[EE_exec].lockedcounter || EE_th[EE_exec].sys_lockedcounter) {
+ for (;; ) {
+ ;
+ }
+ }
+#endif
+
+ /* end_slice: checks the elapsed time on the exec task, putting it into the right
+ * queue (recharging, ready, or simply put the task suspended). at the end EE_exec is EE_NIL */
+ EE_hr_end_slice(tmp_time);
+ /* --- */
+
+
+ /* check if the queues are empty and if there is someone in the recharging queue
+ * to activate
+ */
+ EE_hr_check_recharging(tmp_time);
+ /* --- */
+
+
+ /* the exec task is now EE_NIL.
+ * the next task to execute is either in the stacked or in the ready queue
+ *
+ * we have now to choose between the tasks pointed by stkfirst and
+ * by rqfirst
+ */
+ EE_hr_select_exec();
+ /* --- */
+
+
+ if (EE_exec == EE_NIL) {
+ /* no task to schedule, go to the main */
+ EE_hr_stop_budget_timer();
+ EE_hal_endcycle_stacked(EE_exec);
+ } else {
+ /* there is a task to schedule */
+ wasstacked = EE_th[EE_exec].status & EE_TASK_WASSTACKED;
+ EE_th[EE_exec].status = EE_TASK_EXEC;
+
+ /* reprogram the capacity timer for the new task */
+ EE_hr_set_budget_timer(EE_vres[EE_th[EE_exec].vres].budget_avail);
+
+ if (wasstacked) {
+ EE_hal_endcycle_stacked(EE_exec);
+ } else {
+ EE_hal_endcycle_ready(EE_exec);
+ }
+ }
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/oo/cfg/cfg.mk
new file mode 100644
index 0000000..37f74b8
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/cfg/cfg.mk
@@ -0,0 +1,129 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.4 2006/12/03 22:07:50 pj Exp $
+
+ifeq ($(call iseeopt, __OO_BCC1__), yes)
+OO=YES
+endif
+ifeq ($(call iseeopt, __OO_BCC2__), yes)
+OO=YES
+OO2=YES
+endif
+ifeq ($(call iseeopt, __OO_ECC1__), yes)
+OO=YES
+ifeq ($(call iseeopt, __MULTI__), yes)
+OO_ECC=YES
+endif
+endif
+ifeq ($(call iseeopt, __OO_ECC2__), yes)
+OO=YES
+OO2=YES
+ifeq ($(call iseeopt, __MULTI__), yes)
+OO_ECC=YES
+endif
+endif
+
+ifeq ($(OO), YES)
+EE_SRCS += pkg/kernel/oo/src/ee_activate.c
+EE_SRCS += pkg/kernel/oo/src/ee_schedule.c
+EE_SRCS += pkg/kernel/oo/src/ee_force_schedule.c
+EE_SRCS += pkg/kernel/oo/src/ee_gettaskstate.c
+EE_SRCS += pkg/kernel/oo/src/ee_gettaskid.c
+EE_SRCS += pkg/kernel/oo/src/ee_terminat.c
+EE_SRCS += pkg/kernel/oo/src/ee_thendin.c
+EE_SRCS += pkg/kernel/oo/src/ee_irqendin.c
+EE_SRCS += pkg/kernel/oo/src/ee_iparam.c
+EE_SRCS += pkg/kernel/oo/src/ee_tstub.c
+EE_SRCS += pkg/kernel/oo/src/ee_tnterm.c
+EE_SRCS += pkg/kernel/oo/src/ee_lookup.c
+EE_SRCS += pkg/kernel/oo/src/ee_rq_exchg.c
+EE_SRCS += pkg/kernel/oo/src/ee_rq_inser.c
+EE_SRCS += pkg/kernel/oo/src/ee_shtdown.c
+EE_SRCS += pkg/kernel/oo/src/ee_startos.c
+
+ifeq ($(OO2), YES)
+EE_SRCS += pkg/kernel/oo/src/ee_rq_first.c
+endif
+
+ifneq ($(call iseeopt, __OO_NO_CHAINTASK__), yes)
+EE_SRCS += pkg/kernel/oo/src/ee_chaintas.c
+endif
+
+ifneq ($(call iseeopt, __OO_NO_RESOURCES__), yes)
+EE_SRCS += pkg/kernel/oo/src/ee_lockres.c
+EE_SRCS += pkg/kernel/oo/src/ee_ulockres.c
+EE_SRCS += pkg/kernel/oo/src/ee_ulockallres.c
+endif
+
+
+ifneq ($(call iseeopt, __OO_NO_ALARMS__), yes)
+EE_SRCS += pkg/kernel/oo/src/ee_alcancel.c
+EE_SRCS += pkg/kernel/oo/src/ee_algetbase.c
+EE_SRCS += pkg/kernel/oo/src/ee_alget.c
+EE_SRCS += pkg/kernel/oo/src/ee_alsetabs.c
+EE_SRCS += pkg/kernel/oo/src/ee_alsetrel.c
+endif
+
+ifeq ($(or $(if $(call iseeopt, __OO_NO_ALARMS__),,yes), $(call iseeopt, EE_AS_SCHEDULETABLES__)), yes)
+EE_SRCS += pkg/kernel/oo/src/ee_altick.c
+EE_SRCS += pkg/kernel/oo/src/ee_getcountervalue.c
+EE_SRCS += pkg/kernel/oo/src/ee_getelapsedvalue.c
+endif # !__OO_NO_ALARMS__ || EE_AS_SCHEDULETABLES__
+
+ifeq ($(OO_ECC) , YES)
+EE_SRCS += pkg/kernel/oo/src/ee_evclear.c
+EE_SRCS += pkg/kernel/oo/src/ee_evget.c
+EE_SRCS += pkg/kernel/oo/src/ee_evset.c
+EE_SRCS += pkg/kernel/oo/src/ee_evwait.c
+endif
+
+ifeq ($(call iseeopt, __OO_SEM__), yes)
+EE_SRCS += pkg/kernel/oo/src/ee_sempost.c
+EE_SRCS += pkg/kernel/oo/src/ee_semtrywait.c
+EE_SRCS += pkg/kernel/oo/src/ee_semgetvalue.c
+
+ifeq ($(OO_ECC) , YES)
+EE_SRCS += pkg/kernel/oo/src/ee_semwait.c
+endif
+endif
+
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/doc/readme.txt b/src/bsp/hsm/os/erika2/pkg/kernel/oo/doc/readme.txt
new file mode 100644
index 0000000..c001d00
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/doc/readme.txt
@@ -0,0 +1,63 @@
+Structure of the include files for the OO Kernel
+--------------------------------------------------
+
+ee_common.h
+ ^
+ /|\
+ |
+ +------------+
+ | |
+ | |
+ | ee_intfunc.h
+ | ^
+ | /|\
+ | |
+ | +--+--------+
+ | | |
+ | ee_inline.h |
+ | ^ |
+ | /|\ |
+ | | | | Directories...
+ | +-------+ | |
+ | | | |
+ee_kern.h ee_internal.h | pkg/kernel/oo/inc
+ ^ ^ |
+ /|\ /|\ |
+ | | +--------------
+ | | |
+ee.h ee_internal.h | pkg
+
+
+
+Compilation of the oo primitives:
+ee_internal.h -> ee_internal.h -> ee_intfunc.h -> ee_common.h
+
+Compilation of the application (with source code):
+ee.h -> ee_kernel.h -> ee_inline.h -> ee_intfunc.h -> ee_common.h
+
+Compilation of the application (binary distribution):
+ee.h -> ee_kernel.h -> ee_common.h
+
+ee_common.h
+-----------
+Contains the common part between application and kernel:
+- constants
+- types
+- kernel configuration data structures ("extern" declarations)
+
+ee_intfunc.h
+------------
+Contains a set of data structures/functions that are needed to write
+inline functions
+
+ee_inline.h
+-----------
+Inline functions
+
+ee_kernel.h
+-----------
+OO API
+
+ee_internal.h
+-------------
+Internal data structures that are not needed to be seen by the application
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_api.h
new file mode 100644
index 0000000..425903f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_api.h
@@ -0,0 +1,216 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ */
+
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_API_H
+#define PKG_KERNEL_OO_INC_EE_OO_API_H
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_BCC2__)) \
+ || (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+/* These function are always called directly, never by syscall */
+#ifndef StartOS
+#define StartOS EE_oo_StartOS
+#endif
+
+#ifndef GetTaskID
+#define GetTaskID EE_oo_GetTaskID
+#endif
+
+#ifndef GetTaskState
+#define GetTaskState EE_oo_GetTaskState
+#endif
+
+#ifndef GetActiveApplicationMode
+#define GetActiveApplicationMode EE_oo_GetActiveApplicationMode
+#endif
+
+#ifndef GetEvent
+#define GetEvent EE_oo_GetEvent
+#endif
+
+#ifndef GetCounterValue
+#define GetCounterValue EE_oo_GetCounterValue
+#endif
+
+#ifndef GetElapsedValue
+#define GetElapsedValue EE_oo_GetElapsedValue
+#endif
+
+#ifndef __EE_MEMORY_PROTECTION__
+
+#ifndef ActivateTask
+#define ActivateTask EE_oo_ActivateTask
+#endif
+
+#ifndef TerminateTask
+#define TerminateTask EE_oo_TerminateTask
+#endif
+
+#ifndef ChainTask
+#define ChainTask EE_oo_ChainTask
+#endif
+
+#ifndef Schedule
+#define Schedule EE_oo_Schedule
+#endif
+
+#ifndef ForceSchedule
+#define ForceSchedule EE_oo_ForceSchedule
+#endif
+
+/* ----- */
+
+#ifndef EnableAllInterrupts
+#define EnableAllInterrupts EE_oo_EnableAllInterrupts
+#endif
+
+#ifndef DisableAllInterrupts
+#define DisableAllInterrupts EE_oo_DisableAllInterrupts
+#endif
+
+#ifndef ResumeAllInterrupts
+#define ResumeAllInterrupts EE_oo_ResumeAllInterrupts
+#endif
+
+#ifndef SuspendAllInterrupts
+#define SuspendAllInterrupts EE_oo_SuspendAllInterrupts
+#endif
+
+#ifndef ResumeOSInterrupts
+#define ResumeOSInterrupts EE_oo_ResumeOSInterrupts
+#endif
+
+#ifndef SuspendOSInterrupts
+#define SuspendOSInterrupts EE_oo_SuspendOSInterrupts
+#endif
+
+/* ----- */
+
+#ifndef GetResource
+#define GetResource EE_oo_GetResource
+#endif
+
+#ifndef ReleaseResource
+#define ReleaseResource EE_oo_ReleaseResource
+#endif
+
+/* ----- */
+
+#ifndef SetEvent
+#define SetEvent EE_oo_SetEvent
+#endif
+
+#ifndef ClearEvent
+#define ClearEvent EE_oo_ClearEvent
+#endif
+
+#ifndef WaitEvent
+#define WaitEvent EE_oo_WaitEvent
+#endif
+
+/* ----- */
+
+#ifndef CounterTick
+#define CounterTick EE_oo_IncrementCounter
+#endif
+
+#ifndef IncrementCounter
+#define IncrementCounter EE_oo_IncrementCounter
+#endif
+
+#ifndef SetRelAlarm
+#define SetRelAlarm EE_oo_SetRelAlarm
+#endif
+
+#ifndef SetAbsAlarm
+#define SetAbsAlarm EE_oo_SetAbsAlarm
+#endif
+
+#ifndef CancelAlarm
+#define CancelAlarm EE_oo_CancelAlarm
+#endif
+
+#ifndef GetAlarm
+#define GetAlarm EE_oo_GetAlarm
+#endif
+
+#ifndef GetAlarmBase
+#define GetAlarmBase EE_oo_GetAlarmBase
+#endif
+
+/* ----- */
+
+#ifndef ShutdownOS
+#define ShutdownOS EE_oo_ShutdownOS
+#endif
+
+#ifdef __OO_SEM__
+
+#ifndef InitSem
+#define InitSem EE_oo_InitSem
+#endif
+
+#ifndef WaitSem
+#define WaitSem EE_oo_WaitSem
+#endif
+
+#ifndef TryWaitSem
+#define TryWaitSem EE_oo_TryWaitSem
+#endif
+
+#ifndef PostSem
+#define PostSem EE_oo_PostSem
+#endif
+
+#ifndef GetValueSem
+#define GetValueSem EE_oo_GetValueSem
+#endif
+
+#endif /* __OO_SEM__ */
+
+#endif /* !__EE_MEMORY_PROTECTION__ */
+
+#endif /* BCC1... */
+
+#endif /* __INCLUDE_KERNEL_OO_EE_API__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_common.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_common.h
new file mode 100644
index 0000000..6508255
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_common.h
@@ -0,0 +1,1739 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_common.h,v 1.7 2006/05/03 05:59:55 pj Exp $
+ */
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_COMMON_H
+#define PKG_KERNEL_OO_INC_EE_OO_COMMON_H
+
+/*************************************************************************
+* Kernel Constants
+*************************************************************************/
+
+/* invalid TID */
+#define EE_NIL ((EE_TID)-1)
+
+/* maximum value for EE_UREG (used in EE_th_resource_last) */
+#define EE_UREG_MINUS1 ((EE_UREG)-1)
+
+/*
+ * The Kernel constants like NIL and other thread statuses are defined
+ * in the following sections:
+ *
+ * - invalid see 13.2.4
+ * - thread statuses see 13.2.4
+ */
+
+/* Moreover, the user must specify (into types.h) in a fashion like
+ * #define identifier unique_number
+ * the following identifiers:
+ * - The resource identifiers declared with the macro
+ * DeclareResource (13.4.2.1)
+ * - The task identifiers declared with the macro TASK(TaskName) (13.2.5)
+ * - The resource (RES_SCHEDULER) MUST have the maximum ceiling possible
+ * for Tasks
+ *
+ * For the Extended status and ORTI support:
+ * - EE_MAX_TASK maximum number of tasks (used in TaskActivate
+ * - EE_MAX_RESOURCE maximum number of resources
+ * - EE_MAX_ALARM maximum number of alarms
+ *
+ * For TASK/ALARM Autostart support:
+ * - EE_MAX_APPMODE maximum number of Application modes (typically
+ * >0, because there is always the mode OSDEFAULTAPPMODE.
+ */
+
+
+/*************************************************************************
+* Kernel Types
+*************************************************************************/
+
+/* priority type */
+#ifndef EE_TYPEPRIO
+#define EE_TYPEPRIO EE_UREG
+#endif
+
+/* status type */
+/* the status type, that usually was an used configurable type, is set
+ * by the OO Standard (Bindings specification, paragraph 3.2) to be
+ * unsigned char. */
+#ifndef EE_TYPESTATUS
+#define EE_TYPESTATUS EE_UREG
+#endif
+
+/* pending activation type */
+#ifndef EE_TYPENACT
+#define EE_TYPENACT EE_UREG
+#endif
+
+/* event mask type */
+#ifndef EE_TYPEEVENTMASK
+#define EE_TYPEEVENTMASK EE_UREG
+#endif
+
+/* pair type (signed!) */
+#ifndef EE_TYPEPAIR
+#define EE_TYPEPAIR EE_SREG
+#endif
+
+/* application mode type */
+#ifndef EE_TYPEAPPMODE
+#define EE_TYPEAPPMODE EE_UREG
+#endif
+
+/* service id type */
+#ifndef EE_TYPEOSSERVICEID
+#define EE_TYPEOSSERVICEID EE_UINT8
+#endif
+
+/* resource id type */
+#ifndef EE_TYPERESOURCE
+#define EE_TYPERESOURCE EE_UREG
+#endif
+
+/* counter id type */
+#ifndef EE_TYPECOUNTER
+#define EE_TYPECOUNTER EE_UREG
+#endif
+
+/* counter object id type */
+#ifndef EE_TYPECOUNTEROBJECT
+#define EE_TYPECOUNTEROBJECT EE_UREG
+#endif
+
+/* alarm id type */
+#ifndef EE_TYPEALARM
+#define EE_TYPEALARM EE_TYPECOUNTEROBJECT
+#endif
+
+/* action id type */
+#ifndef EE_TYPEACTION
+#define EE_TYPEACTION EE_UREG
+#endif
+
+/* counter tick type */
+#ifndef EE_TYPETICK
+#define EE_TYPETICK EE_UREG
+#endif
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/** @typedef This data type identifies the OS-Application. */
+typedef EE_UTID ApplicationType;
+#define INVALID_OSAPPLICATION ((ApplicationType)-1)
+#define KERNEL_OSAPPLICATION ((ApplicationType)0U)
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+/* Maximum number of pending activations */
+extern const EE_TYPENACT EE_th_rnact_max[EE_MAX_TASK];
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+/* priorities (NB: they are bit fields!!!) */
+extern const EE_TYPEPRIO EE_th_ready_prio[EE_MAX_TASK];
+extern const EE_TYPEPRIO EE_th_dispatch_prio[EE_MAX_TASK];
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/*************************************************************************
+* Kernel Variables defined by the application
+*************************************************************************/
+
+/* thread status, all initialized to SUSPENDED */
+extern EE_TYPESTATUS EE_th_status[EE_MAX_TASK];
+
+/* next: is used for:
+ * - the stacked queue
+ * - WaitEvent (?)
+ * - the ready queue (BCC1, ECC1)
+ * all initialized with EE_NIL
+ */
+extern EE_TID EE_th_next[EE_MAX_TASK];
+
+/*
+ * remaining nact: init= maximum pending activations of a Task
+ * =1 for BCC1 and ECC1, >= 0 for BCC2 and ECC2
+ *
+ * all initialized with 1 (ECC2, BCC2: or with a value >1)
+ */
+extern EE_TYPENACT EE_th_rnact[EE_MAX_TASK];
+
+#ifndef __OO_NO_CHAINTASK__
+/* The next task to be activated after a ChainTask. initvalue=all EE_NIL */
+extern EE_TID EE_th_terminate_nextask[EE_MAX_TASK];
+#endif
+
+/* The first stacked task (initvalue = EE_NIL) */
+extern EE_TID EE_stkfirst;
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_ECC1__))
+/* First task in the ready queue (initvalue = EE_NIL) */
+extern EE_TID EE_rq_first;
+#endif /* __OO_BCC1__ || __OO_ECC1__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* System ceiling (initvalue = 0) */
+extern EE_TYPEPRIO EE_sys_ceiling;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+
+/*
+ * ready queue implementation:
+ * - 16 priorities
+ * - we use a queue for each priority. Head and tail are stored in an array
+ * - each queue contains pairs (Task ID, next)
+ * - the number of pairs is the sum of all the possible activations
+ * of all the tasks (in that way, an activation will never fail due
+ * to the lack of a pair)
+ * - to know which queue have to be used, a bit mask is used to do a fast
+ * lookup (the 8 bit lookup table is defined into ee_lookup.c)
+ */
+
+/* bit mask with 16 or 8 priority levels (Initvalue = 0) */
+#if defined(__OO_BCC2__)
+typedef EE_UINT8 EE_TYPE_RQ_MASK;
+#else
+typedef EE_UINT16 EE_TYPE_RQ_MASK;
+#endif
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* The following data structure gives the link between a task and its
+ * priority queue. The values of this data structure are the same of
+ * EE_ready_prio, except that they are not stored as bitfields
+ *
+ * Initvalue: each TID = x such that th_ready_prio[TID]= 1<<x
+ */
+extern EE_TYPEPRIO EE_rq_link[EE_MAX_TASK];
+
+/* The priority queues (initvalue: all -1;
+ * number of elements: 8(BCC2) or 16(ECC2) ) */
+extern EE_TYPEPAIR EE_rq_queues_head[EE_RQ_QUEUES_HEAD_SIZE];
+extern EE_TYPEPAIR EE_rq_queues_tail[EE_RQ_QUEUES_TAIL_SIZE];
+
+/* The pairs that are enqueued into the priority queues */
+/* initvalue: something like {1,2,3,4,5,...,-1}.
+ * the number of elements is equal to the sum of the elements of
+ * EE_th_rnact */
+extern EE_TYPEPAIR EE_rq_pairs_next[EE_RQ_PAIRS_NEXT_SIZE];
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* init value=0 (no init value); the number of elements is equal to the
+ * sum of the elements of EE_th_rnact */
+extern EE_TID EE_rq_pairs_tid[EE_RQ_PAIRS_TID_SIZE];
+
+/* RQ priority Mask */
+extern EE_TYPE_RQ_MASK EE_rq_bitmask;
+/* a list of unused pairs */
+extern EE_TYPEPAIR EE_rq_free; /* pointer to a free pair; initvalue=0 */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+/* Event handling */
+
+/* Note: To save memory space, Extended tasks should have the smallest
+ * number into the task data structures. In that way, the following
+ * data structures can be sized to exactly the number of the extended
+ * tasks */
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* thread events already active; these events are set using the
+ * SetEvent primitive. initvalue = 0 */
+extern EE_TYPEEVENTMASK EE_th_event_active[EE_MAX_TASK];
+
+/* thread wait mask. this is the event mask the task is waiting using
+ * WaitEvent. A task IS waiting only if the value in this array IS != 0.
+ * initvalue = 0 */
+extern EE_TYPEEVENTMASK EE_th_event_waitmask[EE_MAX_TASK];
+
+/* this structure contains a flag that is 1 if a thread has been
+ * suspended using EE_hal_stkchange. In that case, the task have to
+ * be wakened again using the same function. initvalue = 0
+ */
+extern EE_TYPEBOOL EE_th_waswaiting[EE_MAX_TASK];
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* just a flag: this flag is 1 if the task is an extended task, 0 otherwise */
+/* Please note that this flag is defined both in STANDARD and in
+ * EXTENDED status. The need for this flag in standard status is
+ * because task activations of an extended task clears its pending
+ * event mask. */
+extern const EE_TYPEBOOL EE_th_is_extended[EE_MAX_TASK];
+
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+/* Resources data structures */
+
+#ifndef __OO_NO_RESOURCES__
+
+/* Resource ceiling */
+extern const EE_TYPEPRIO EE_resource_ceiling[EE_MAX_RESOURCE];
+
+#ifdef __OO_ISR2_RESOURCES__
+/* ISR2 priority tied to an resource */
+extern const EE_TYPEISR2PRIO EE_resource_isr2_priority[EE_MAX_RESOURCE];
+#endif /* __OO_ISR2_RESOURCES__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+
+/* Note: There is no constraint on the index that is assigned
+ * RES_SCHEDULER!!! */
+/* Old resource ceiling */
+extern EE_TYPEPRIO EE_resource_oldceiling[EE_MAX_RESOURCE];
+
+#ifdef __OO_ISR2_RESOURCES__
+/* New data structures to handle resource sharing with isr2 and isr2 hardware
+ * priority ceiling. */
+/* Old ISR2 priority */
+extern EE_TYPEISR2PRIO EE_isr2_oldpriority[EE_MAX_RESOURCE];
+#endif /* __OO_ISR2_RESOURCES__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ORTI_RES_ISLOCKED__))
+/* Only in extended status or when using ORTI with resources; for each
+ * resource, a flag is allocated to see if the resource is locked or
+ * not. Note that this information cannot be easily knew from the
+ * previous two data structures. initvalue=0
+ */
+extern EE_TYPEBOOL EE_resource_locked[EE_MAX_RESOURCE];
+#endif /*__OO_EXTENDED_STATUS__ || __OO_ORTI_RES_ISLOCKED__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ISR2_RESOURCES__))
+/* Only in extended status; for each task, we allocate a data
+ * structure that keeps track of the order in which every task has
+ * allocated a resource. This is needed to return a meaningful
+ * E_OS_NOFUNC error in the ReleaseResource call. */
+
+/* This is the last resource that the task has locked. This array
+ * contains one entry for each task. Initvalue= all -1. at runtime,
+ * it points to the first item in the EE_resource_stack data structure */
+#ifndef EE_MAX_ISR2_WITH_RESOURCES
+extern EE_UREG EE_th_resource_last[EE_MAX_TASK];
+#else /* !EE_MAX_ISR2_WITH_RESOURCES */
+extern EE_UREG EE_th_resource_last[EE_MAX_TASK + EE_MAX_ISR2_WITH_RESOURCES];
+#endif /* !EE_MAX_ISR2_WITH_RESOURCES */
+/* this array is used to store a list of resources locked by a
+ * task. there is one entry for each resource, initvalue = -1. the
+ * list of resources locked by a task is ended by -1. */
+extern EE_UREG EE_resource_stack[EE_MAX_RESOURCE];
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ISR2_RESOURCES__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __OO_NO_RESOURCES__ */
+
+#if (defined(__OO_ISR2_RESOURCES__)) || (defined(EE_AS_USER_SPINLOCKS__))
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#if (defined(EE_MAX_ISR2_WITH_RESOURCES)) && (!defined(EE_AS_USER_SPINLOCKS__))
+#if (EE_MAX_ISR2_WITH_RESOURCES > 0)
+/* Array to hold corresponding isr2 nesting levels */
+extern EE_UREG EE_isr2_nesting_level[EE_MAX_ISR2_WITH_RESOURCES];
+#endif /* (EE_MAX_ISR2_WITH_RESOURCES > 0) && !EE_AS_USER_SPINLOCKS__ */
+#elif defined(EE_MAX_ISR2)
+#if (EE_MAX_ISR2 > 0)
+extern EE_UREG EE_isr2_nesting_level[EE_MAX_ISR2];
+#endif /* EE_MAX_ISR2 > 0 */
+#endif
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+#endif /* __OO_ISR2_RESOURCES__ || EE_AS_USER_SPINLOCKS__ */
+
+/* This is the stub that have to be put into the EE_th_body array */
+extern void EE_oo_thread_stub(void);
+
+/***************************************************************************
+* 13.1 Common data types
+***************************************************************************/
+
+/* see top of the file */
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/* 13.2.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* This data type identifies a task. */
+typedef EE_TID TaskType;
+
+/* This data type points to a variable of TaskType. */
+typedef EE_TID *TaskRefType;
+
+/* This data type identifies the state of a task. */
+typedef EE_TYPESTATUS TaskStateType;
+
+/* This data type points to a variable of the data type TaskStateType. */
+typedef EE_TYPESTATUS *TaskStateRefType;
+
+/***************************************************************************
+* ISR2 management
+***************************************************************************/
+/** @typedef This data type identifies an interrupt service routine (ISR). */
+typedef EE_UTID ISRType;
+#define INVALID_ISR ((ISRType)-1)
+
+/* 13.2.4 Constants */
+/* ----------------------------------------------------------------------- */
+
+/* Constant of data type TaskStateType for task state running. */
+#define RUNNING ((EE_TYPESTATUS)0U)
+
+/* Constant of data type TaskStateType for task state waiting. */
+#define WAITING ((EE_TYPESTATUS)1U)
+
+/* Constant of data type TaskStateType for task state ready. */
+#define READY ((EE_TYPESTATUS)2U)
+
+/* Constant of data type TaskStateType for task state suspended. */
+#define SUSPENDED ((EE_TYPESTATUS)3U)
+
+
+/***************************************************************************
+* 13.4 Resource management
+***************************************************************************/
+
+/* 13.4.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+#ifndef __OO_NO_RESOURCES__
+typedef EE_TYPERESOURCE ResourceType;
+#endif
+
+/***************************************************************************
+* 13.5 Event control
+***************************************************************************/
+
+/* 13.5.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* Data type of the event mask. */
+typedef EE_TYPEEVENTMASK EventMaskType;
+
+/* Reference to an event mask. */
+typedef EE_TYPEEVENTMASK *EventMaskRefType;
+
+/***************************************************************************
+* 13.6 Counters & Alarms
+***************************************************************************/
+/** @typedef This data type represents count values in ticks. */
+typedef EE_TYPETICK TickType;
+
+/** @typedef This data type points to the data type TickType. */
+typedef TickType *TickRefType;
+
+#ifdef EE_CPU_CLOCK
+/** Utility Macro that convert an amount of ms in number of ticks at the CPU
+ * clock frequency **/
+#define EE_MILLI_TO_CPU_TICKS(X_MS) EE_MILLI_TO_TICKS(X_MS, EE_CPU_CLOCK)
+
+/** Utility Macro that convert an amount of us in number of ticks of a given
+ * frequency **/
+#define EE_MICRO_TO_CPU_TICKS(X_US) EE_MICRO_TO_TICKS(X_US, EE_CPU_CLOCK)
+#endif /* EE_CPU_CLOCK */
+
+/* Alarms Handling */
+#if (!defined(__OO_NO_ALARMS__)) || (defined(EE_AS_SCHEDULETABLES__))
+
+/* Used to handle some corner cases with TickType */
+#define EE_TYPETICK_HALF_VALUE ((((EE_TYPETICK)-1) >> 1) + 1U)
+
+/* 13.6.1 Data types */
+/* ----------------------------------------------------------------------- */
+/* A structure for storage of counter characteristics. */
+typedef struct {
+ TickType maxallowedvalue; /* Maximum possible allowed count value in
+ * ticks */
+ TickType ticksperbase; /* Number of hardware ticks required to reach a
+ * counter-specific (significant) unit. */
+#ifdef __OO_EXTENDED_STATUS__
+ TickType mincycle; /* Smallest allowed value for the cycle-parameter
+ * of SetRelAlarm/SetAbsAlarm) (only for systems
+ * with extended status) */
+#endif /* __OO_EXTENDED_STATUS__ */
+} AlarmBaseType;
+
+/** @typedef This data type points to the data type AlarmBaseType. */
+typedef AlarmBaseType *AlarmBaseRefType;
+
+/** @typedef This data type represent a counter object ID. */
+typedef EE_TYPECOUNTEROBJECT CounterObjectType;
+
+/** Define for an invalid counter object ID */
+#define INVALID_COUNTER_OBJECT ((CounterObjectType)-1)
+
+/** @typedef This data type represents an action ID. */
+typedef EE_TYPEACTION ActionType;
+
+/** @typedef This data type represents an alarm ID. */
+typedef EE_TYPEALARM AlarmType;
+
+/** Define for an invalid alarm */
+#define INVALID_ALARM ((AlarmType)-1)
+
+/** @typedef This is an additional data type that represents a counter ID. */
+typedef EE_TYPECOUNTER CounterType;
+
+/** Define for an invalid counter */
+#define INVALID_COUNTER ((CounterType)-1)
+
+/** Initialization Value: depends on configuration */
+typedef struct {
+ TickType maxallowedvalue;
+ TickType ticksperbase;
+ TickType mincycle;
+#ifdef EE_AS_OSAPPLICATIONS__
+ /** The ID of the application to which this counter belong to. */
+ ApplicationType ApplID;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+} EE_oo_counter_ROM_type;
+
+/** Initialization Value: {0, -1} */
+typedef struct {
+ TickType value; /**< current value of the counter */
+ CounterObjectType first; /**< first object queued on the counter */
+} EE_oo_counter_RAM_type;
+
+/** Add supplementary support info for hardware counters */
+#ifdef EE_MAX_COUNTER_HW
+typedef struct {
+ TickType microsecondspertick;
+} EE_oo_counter_hw_ROM_type;
+#endif /* EE_MAX_COUNTER_HW */
+
+/** These are the different kind of counter objects */
+typedef enum {
+ EE_ALARM,
+ EE_SCHEDULETABLE
+} EE_oo_counter_object_kind_type;
+
+/** Typedef to have a more harmonized type name with other OSEK type names */
+typedef EE_oo_counter_object_kind_type CounterObjectKindType;
+
+/** These data structures represent a generic counter object. Object of this
+ * kind will build a counter's expire list */
+typedef struct {
+ /** The counter this counter is linked to */
+ CounterType c;
+ /** ID specialized Id (In Alarm or Schedule Tables List) */
+ CounterObjectType spec_id;
+ /** Which kind of Counter Object is this */
+ CounterObjectKindType kind;
+} EE_oo_counter_object_ROM_type;
+
+/** These data structures represent a generic counter object. Object of this
+ * kind will build a counter's expire list */
+typedef struct {
+ EE_TYPEBOOL used; /**< a flag that is 1 when the alarm is armed */
+ TickType cntcycle; /**< cycle for periodic alarms */
+ TickType delta; /**< delta expiration time (into a queue!) */
+ CounterObjectType next; /**< next counter object in the delta queue */
+} EE_oo_counter_object_RAM_type;
+
+/** These are the different kind of counter object actions */
+typedef enum {
+ EE_ACTION_TASK = 0U,
+ EE_ACTION_EVENT = 1U,
+ EE_ACTION_COUNTER = 2U,
+ EE_ACTION_CALLBACK = 3U
+} EE_oo_action_kind_type;
+
+/** Typedef to have a more harmonized type name with other OSEK type names */
+typedef EE_oo_action_kind_type ActionKindType;
+
+/** This data structure represent an counter object action */
+typedef struct {
+ ActionKindType action_kind;
+ TaskType action_task;
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+ EventMaskType action_mask;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+ EE_VOID_CALLBACK f;
+ /* Counter to increment when the alarm expire.*/
+ CounterType inccount;
+} EE_oo_action_ROM_type;
+
+typedef struct {
+ /** The ID of the action that have to be executed when this alarm expire */
+ ActionType action_id;
+#ifdef EE_AS_OSAPPLICATIONS__
+ /** The ID of the application to which this alarm belong to. */
+ ApplicationType ApplID;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+} EE_oo_alarm_ROM_type;
+
+/* This array contains, for each counter, the characteristics of the counter.
+ * The initialization value is implementation dependent */
+#if defined(EE_COUNTER_ROM_SIZE)
+#if EE_COUNTER_ROM_SIZE > 0
+extern const EE_oo_counter_ROM_type EE_counter_ROM[EE_COUNTER_ROM_SIZE];
+#endif
+#endif
+
+#ifdef EE_MAX_COUNTER_HW
+/* Add supplementary support info for HARDWARE counters.
+ * This array contains, for each HARDWARE counter, the supplementary
+ * characteristics of the counter.The initialization value is implementation
+ * dependent */
+extern const EE_oo_counter_hw_ROM_type
+ EE_counter_hw_ROM[EE_COUNTER_HW_ROM_SIZE];
+#endif /* EE_MAX_COUNTER_HW */
+
+/* this part is the fixed part of a counter object.
+ * Initvalue= depends on how the alarm or the schedule table represented by this
+ * have been configured */
+#if defined(EE_COUNTER_OBJECTS_ROM_SIZE)
+#if (EE_COUNTER_OBJECTS_ROM_SIZE > 0)
+extern const EE_oo_counter_object_ROM_type
+ EE_oo_counter_object_ROM[EE_COUNTER_OBJECTS_ROM_SIZE];
+#endif
+#endif
+
+/* this part represent the list of the configured actions.
+ * Initvalue= depends on how the alarms and the schedule tables have been
+ * have been configured */
+#if defined(EE_ACTION_ROM_SIZE)
+#if (EE_ACTION_ROM_SIZE > 0)
+extern const EE_oo_action_ROM_type EE_oo_action_ROM[EE_ACTION_ROM_SIZE];
+#endif
+#endif
+
+/* this is the fixed part of the configuration of an alarm
+ * Initvalue= depends on how the alarm have been configured */
+#if defined(EE_ALARM_ROM_SIZE)
+#if (EE_ALARM_ROM_SIZE > 0)
+extern const EE_oo_alarm_ROM_type EE_alarm_ROM[EE_ALARM_ROM_SIZE];
+#endif
+#endif
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* This is the RAM part of a counter.
+ * Initialization value = an array of {0,-1} elements */
+extern EE_oo_counter_RAM_type EE_counter_RAM[EE_MAX_COUNTER];
+
+/* this part is the variable part of a counter object.
+ * Initvalue: all zeros. Note that setting the next value to 0 and
+ * not -1 does not give problems because used=0; the next field will
+ * be set by counter_object_insert when inserting the alarm in the queue */
+#if defined(EE_COUNTER_OBJECTS_ROM_SIZE)
+#if (EE_COUNTER_OBJECTS_ROM_SIZE > 0)
+extern EE_oo_counter_object_RAM_type
+ EE_oo_counter_object_RAM[EE_COUNTER_OBJECTS_ROM_SIZE];
+#endif
+#endif
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* !__OO_NO_ALARMS__ || EE_AS_SCHEDULETABLES__ */
+
+/***************************************************************************
+* 13.7 Operating system execution control
+***************************************************************************/
+
+/* 13.7.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* This data type represents the application mode. */
+typedef EE_TYPEAPPMODE AppModeType;
+
+/***************************************************************************
+* 13.1 Common data types
+***************************************************************************/
+
+/* 3.2 (Bindings). StatusType is an unsigned char */
+#ifndef STATUSTYPEDEFINED
+#define STATUSTYPEDEFINED
+typedef unsigned char StatusType;
+#define E_OK ((StatusType)0U)
+#endif
+
+#define E_OS_ACCESS ((StatusType)1U)
+#define E_OS_CALLEVEL ((StatusType)2U)
+#define E_OS_ID ((StatusType)3U)
+#define E_OS_LIMIT ((StatusType)4U)
+#define E_OS_NOFUNC ((StatusType)5U)
+#define E_OS_RESOURCE ((StatusType)6U)
+#define E_OS_STATE ((StatusType)7U)
+#define E_OS_VALUE ((StatusType)8U)
+#define E_OS_SERVICEID ((StatusType)9U)
+#define E_OS_ILLEGAL_ADDRESS ((StatusType)10U)
+#define E_OS_MISSINGEND ((StatusType)11U)
+#define E_OS_DISABLEDINT ((StatusType)12U)
+#define E_OS_STACKFAULT ((StatusType)13U)
+#define E_OS_PARAM_POINTER ((StatusType)14U)
+#define E_OS_PROTECTION_MEMORY ((StatusType)15U)
+#define E_OS_PROTECTION_TIME ((StatusType)16U)
+#define E_OS_PROTECTION_ARRIVAL ((StatusType)17U)
+#define E_OS_PROTECTION_LOCKED ((StatusType)18U)
+#define E_OS_PROTECTION_EXCEPTION ((StatusType)19U)
+/* Spinlocks errors */
+#define E_OS_SPINLOCK ((StatusType)20U)
+#define E_OS_INTERFERENCE_DEADLOCK ((StatusType)21U)
+#define E_OS_NESTING_DEADLOCK ((StatusType)22U)
+/* RPC errors */
+#define E_OS_CORE ((StatusType)23U)
+
+/* Implementation specific errors: they must start with E_OS_SYS_ */
+/* Error during StartOS */
+#define E_OS_SYS_INIT ((StatusType)24U)
+
+/***************************************************************************
+* ORTI support
+***************************************************************************/
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_api_bss */
+#define API_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __OO_ORTI_LASTERROR__
+
+/* a lasterror value that can be used with ORTI */
+extern StatusType EE_ORTI_lasterror;
+/* Macro to set lasterror value that can be used with ORTI */
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_lasterror(StatusType err)
+{
+ EE_ORTI_lasterror = err;
+}
+#else /* __OO_ORTI_LASTERROR__ */
+
+#define EE_ORTI_set_lasterror(ERR) ((void)0)
+#endif /* __OO_ORTI_LASTERROR__ */
+
+/* the last OO service called by the application. SERVICETRACE IDs
+ * are even numbers. The LSBit is used as a flag and it is set to 1
+ * when the servce is entered, to 0 at exit.
+ */
+
+#define EE_SERVICETRACE_ACTIVATETASK 2U
+#define EE_SERVICETRACE_TERMINATETASK 4U
+#define EE_SERVICETRACE_CHAINTASK 6U
+#define EE_SERVICETRACE_SCHEDULE 8U
+#define EE_SERVICETRACE_GETTASKID 10U
+#define EE_SERVICETRACE_GETTASKSTATE 12U
+#define EE_SERVICETRACE_DISABLEALLINTERRUPTS 14U
+#define EE_SERVICETRACE_ENABLEALLINTERRUPTS 16U
+#define EE_SERVICETRACE_SUSPENDALLINTERRUPTS 18U
+#define EE_SERVICETRACE_RESUMEALLINTERRUPTS 20U
+#define EE_SERVICETRACE_SUSPENDOSINTERRUPTS 22U
+#define EE_SERVICETRACE_RESUMEOSINTERRUPTS 24U
+#define EE_SERVICETRACE_GETRESOURCE 26U
+#define EE_SERVICETRACE_RELEASERESOURCE 28U
+#define EE_SERVICETRACE_SETEVENT 30U
+#define EE_SERVICETRACE_CLEAREVENT 32U
+#define EE_SERVICETRACE_GETEVENT 34U
+#define EE_SERVICETRACE_WAITEVENT 36U
+#define EE_SERVICETRACE_GETALARMBASE 38U
+#define EE_SERVICETRACE_GETALARM 40U
+#define EE_SERVICETRACE_SETRELALARM 42U
+#define EE_SERVICETRACE_SETABSALARM 44U
+#define EE_SERVICETRACE_CANCELALARM 46U
+#define EE_SERVICETRACE_GETACTIVEAPPLICATIONMODE 48U
+#define EE_SERVICETRACE_STARTOS 50U
+#define EE_SERVICETRACE_SHUTDOWNOS 52U
+#define EE_SERVICETRACE_FORCESCHEDULE 54U
+#define EE_SERVICETRACE_INCREMENTCOUNTER 56U
+#define EE_SERVICETRACE_GETCOUNTERVALUE 58U
+#define EE_SERVICETRACE_GETELAPSEDVALUE 60U
+
+#ifdef __OO_SEM__
+#define EE_SERVICETRACE_INITSEM 62U
+#define EE_SERVICETRACE_WAITSEM 64U
+#define EE_SERVICETRACE_TRYWAITSEM 66U
+#define EE_SERVICETRACE_POSTSEM 68U
+#define EE_SERVICETRACE_GETVALUESEM 70U
+#define EE_SERVICETRACE_OO_LAST 72U
+#else /* __OO_SEM__ */
+#define EE_SERVICETRACE_OO_LAST 62U
+#endif /* __OO_SEM__ */
+
+#ifdef __OO_ORTI_SERVICETRACE__
+extern volatile EE_UINT8 EE_ORTI_servicetrace;
+
+__INLINE__ void EE_ORTI_set_service(EE_UINT8 srv)
+{
+ EE_ORTI_servicetrace = srv;
+#ifdef __OO_ORTI_USE_OTM__
+ EE_ORTI_send_otm_servicetrace(srv);
+#endif /* __OO_ORTI_USE_OTM__ */
+}
+
+#else /* __OO_ORTI_SERVICETRACE__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_service(EE_UINT8 srv)
+{
+}
+
+#endif /* else __OO_ORTI_SERVICETRACE__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_api_bss */
+#define API_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* Mapping for ORTI service In and Out */
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_service_in(EE_UINT8 id)
+{
+ EE_ORTI_set_service(id + 1U);
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_service_out(EE_UINT8 id)
+{
+ EE_ORTI_set_service(id);
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __OO_ORTI_PRIORITY__
+/* This flag enables the visualization of the current task priority in ORTI
+ * debuggers. */
+
+/* this variable contains the current task priority and that is the priority
+ * that is read by the ORTI debugger
+ * Initvalue: the ready priority set for the task
+ */
+extern EE_TYPEPRIO EE_ORTI_th_priority[EE_MAX_TASK];
+
+/* this variable contains the current task priority saved when a task
+ * locked a resource. It works because a resource can be
+ * locked only by one task at a time.
+ * InitValue: all 0
+ */
+#if (defined(EE_MAX_RESOURCE)) && (EE_MAX_RESOURCE > 0U)
+extern EE_TYPEPRIO EE_ORTI_resource_oldpriority[EE_MAX_RESOURCE];
+#endif /* EE_MAX_RESOURCE && EE_MAX_RESOURCE > 0U */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_th_eq_dispatch_prio(EE_TID tmp)
+{
+ EE_ORTI_th_priority[tmp] = EE_th_dispatch_prio[tmp];
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_th_priority(EE_TID index,
+ EE_TYPEPRIO prio)
+{
+ EE_ORTI_th_priority[index] = prio;
+}
+#else
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_th_eq_dispatch_prio(EE_TID tmp)
+{
+}
+__INLINE__ void __ALWAYS_INLINE__ EE_ORTI_set_th_priority(EE_TID index,
+ EE_TYPEPRIO prio)
+{
+}
+#endif /*__OO_ORTI_PRIORITY__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/***************************************************************************
+* Semaphores
+***************************************************************************/
+
+/* Semaphores are not part of the OSEK API, please refer to the EE
+ * reference manual */
+/* Constants */
+/* ----------------------------------------------------------------------- */
+
+/* the maximum unsigned integer */
+#define EE_MAX_SEM_COUNTER ((EE_UREG)-1)
+
+/* Data types */
+/* ----------------------------------------------------------------------- */
+#ifdef __OO_SEM__
+
+struct EE_TYPESEM {
+ EE_UREG count;
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ EE_TID first;
+ EE_TID last;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+};
+
+/* Data type of the event mask. */
+typedef struct EE_TYPESEM SemType;
+
+/* Reference to an event mask. */
+typedef SemType *SemRefType;
+
+#endif /* __OO_SEM__ */
+
+/***************************************************************************
+* Autostart Features inside StartOS()
+***************************************************************************/
+
+/* Note: Autostart uses the symbol EE_MAX_APPMODE that represents
+ * the number of different application modes in the system. */
+
+#ifdef __OO_AUTOSTART_TASK__
+
+/* This is the data structure used to store the autostart data for tasks.
+ *
+ * - n contains the number of tasks that have to be automatically
+ * activated at startup for a given application mode.
+ *
+ * - task contains the list of TIDs that have to be activated for a
+ * given application mode.
+ */
+
+struct EE_oo_autostart_task_type {
+ EE_UREG nt;
+ const EE_TID(*task)[];/* pointer to array of TIDs */
+};
+
+/* For each valid APPMODE (that ranges from 0 to EE_MAX_APPMODE-1) there must
+ * be an item in this array with the tasks that are activated at startup. */
+extern const struct EE_oo_autostart_task_type
+ EE_oo_autostart_task_data[EE_MAX_APPMODE];
+
+#endif
+
+#ifdef __OO_AUTOSTART_ALARM__
+
+/* This is the data structure used to store the autostart data for alarms.
+ *
+ * - n contains the number of alarms that have to be automatically
+ * set at startup for a given application mode.
+ *
+ * - alarm contains the list of Alarm IDs that have to be activated for a
+ * given application mode.
+ */
+
+struct EE_oo_autostart_alarm_type {
+ EE_UREG na;
+ const EE_TYPEALARM(*alarm)[];
+};
+
+/* For each valid APPMODE (that ranges from 0 to EE_MAX_APPMODE-1) there must
+ * be an item in this array with the tasks that are activated at startup. */
+extern const struct EE_oo_autostart_alarm_type
+ EE_oo_autostart_alarm_data[EE_MAX_APPMODE];
+
+/* For each Alarm that is activated there should be an item in these
+ * arrays that contains the cycle and increment values that have to be
+ * used when activating a given alarm ID. Note that cycle/increment
+ * are unique for each alarm activation time.
+ * The size of these two arrays is MAXALARM.
+ */
+extern const EE_TYPETICK EE_oo_autostart_alarm_increment[EE_MAX_ALARM];
+extern const EE_TYPETICK EE_oo_autostart_alarm_cycle[EE_MAX_ALARM];
+#endif
+
+#ifdef __MSRP__
+/*******************************************************************************
+ * Autosar Multicore support Type Declarations
+ ******************************************************************************/
+/* The following type declarations are added here and not inside AS kernel
+ * because i need "TryToGetSpinlockType *" to completely define EE_os_param
+ * type (used inside Error parameters structure).
+ * The problem is that theoretically there is not in C such a thing as
+ * "standard pointer dimension" but each pointer COULD HAVE his own dimension
+ * (it never happens... Actually the 99% of architectures has pointer and
+ * value registers with same dimension). */
+
+typedef EE_TYPECOREID CoreIdType;
+
+#ifdef EE_AS_USER_SPINLOCKS__
+typedef EE_TYPESPIN SpinlockIdType;
+#define INVALID_SPINLOCK ((SpinlockIdType)-1)
+
+typedef enum {
+ TRYTOGETSPINLOCK_NOSUCCESS = 0x0,
+ TRYTOGETSPINLOCK_SUCCESS
+} TryToGetSpinlockType;
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#endif /* __MSRP__ */
+
+/*[OS088] If an OS-Application makes a service call from the wrong context AND
+ * is currently not inside a Category 1 ISR the Operating System module shall
+ * not perform the requested action (the service call shall have no effect),
+ * and return E_OS_CALLEVEL (see [12], section 13.1) or the "invalid value" of
+ * the service. (BSW11009, BSW11013) */
+/** @typedef OS-Application contexts enum used to implement Autosar OS O0S88
+ * requirement */
+typedef enum {
+ Kernel_Context,
+ TASK_Context,
+ ISR2_Context,
+ ErrorHook_Context,
+ ProtectionHook_Context,
+ PreTaskHook_Context,
+ PostTaskHook_Context,
+ StartupHook_Context,
+ ShutdownHook_Context,
+ AlarmCallback_Context,
+ Idle_Context
+} EE_TYPECONTEXT;
+
+#ifdef EE_SERVICE_PROTECTION__
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @var used by the kernel to flag in witch context is executing */
+extern EE_TYPECONTEXT EE_as_execution_context;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+__INLINE__ EE_TYPECONTEXT __ALWAYS_INLINE__ EE_as_get_execution_context(void)
+{
+ return EE_as_execution_context;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_as_set_execution_context(EE_TYPECONTEXT
+ ctx)
+{
+ EE_as_execution_context = ctx;
+}
+#else /* EE_SERVICE_PROTECTION__ */
+#define EE_as_get_execution_context() Kernel_Context
+__INLINE__ void __ALWAYS_INLINE__ EE_as_set_execution_context(EE_TYPECONTEXT
+ ctx)
+{
+ /* Unusefull operation to meet Linters requirements */
+ (void)ctx;
+}
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+/*******************************************************************************
+ * Autosar support Type Declarations
+ ******************************************************************************/
+/* The following type declarations are added here and not inside AS kernel
+ * because i need "TrustedFunctionParameterRefType" and
+ * "ApplicationStateRefType" to completely define EE_os_param type
+ * (used inside Error parameters structure).
+ * The problem is that theoretically there is not in C such a thing as
+ * "standard pointer dimension" but each pointer COULD HAVE his own dimension
+ * (it never happens... Actually the 99% of architectures has pointer and
+ * value registers with same dimension). */
+
+/** @typedef This data type identifies the state of an OS-Application. */
+typedef enum {
+ APPLICATION_ACCESSIBLE,
+ APPLICATION_RESTARTING,
+ APPLICATION_TERMINATED
+} ApplicationStateType;
+
+/** @typedef This data type points to location where a ApplicationStateType can
+ * be stored. */
+typedef ApplicationStateType *ApplicationStateRefType;
+
+/** @typedef This data type identifies if an OS-Application has access to an object. */
+typedef enum {
+ NO_ACCESS = 0U,
+ ACCESS
+} ObjectAccessType;
+
+/** @typedef This data type defines the use of a Restart Task after terminating
+ * an OS-Application. */
+typedef enum {
+ NO_RESTART = 0U,
+ RESTART
+} RestartType;
+
+/** @typedef This type will hold the access mask for an "object" system ID */
+typedef EE_UREG EE_TYPEACCESSMASK;
+
+/** @typedef This data type identifies an object. */
+typedef enum {
+ OBJECT_TASK = 0U,
+ OBJECT_ISR,
+ OBJECT_ALARM,
+ OBJECT_RESOURCE,
+ OBJECT_COUNTER,
+ OBJECT_SCHEDULETABLE,
+ OBJECT_SPINLOCK
+} ObjectTypeType;
+
+/** @typedef Static ISR descriptor */
+typedef struct {
+ ApplicationType ApplID; /**< ID of the application the ISR belongs to */
+#ifdef __OO_ORTI_RUNNINGISR2__
+ EE_ORTI_runningisr2_type handler; /**< Handler for ISR2 tracing */
+#endif /* __OO_ORTI_RUNNINGISR2__ */
+} EE_as_ISR_ROM_type;
+
+/** @typedef This data type is a pointer which is able to point to any location
+ * in the MCU. */
+typedef EE_ADDR MemoryStartAddressType;
+
+/** @typedef Runtime ISR descriptor. */
+typedef struct {
+ /** TOS to be restored when the ISR is terminated. */
+ MemoryStartAddressType TerminationTOS;
+ /** ISR ID that hold the position in ISR stack. */
+ ISRType ISR_ID;
+ /** Contain the interrupted OS Application */
+ ApplicationType Interrupted_App;
+ /** Architecture dependent register value used to rewind ISR call stack
+ * in ISR termination. */
+ EE_UREG ISR_Terminate_data;
+} EE_as_ISR_RAM_type;
+
+/** @typedef Static OS Application descriptor */
+typedef struct {
+ EE_APP_SEC_INFO_T sec_info; /**< Address and size of application sections */
+ /** Mode bits, to distinguish between trusted and untrusted applications
+ * (encoding is platform dependent). NOTE: it could be critical for
+ * performance, as it is accessed on every mode switch. */
+ EE_UREG Mode;
+ EE_UREG ISRTOS; /**< TOS used by the application's ISRs. */
+ TaskType restart_task; /**< ID of the application restarting TASK */
+} EE_as_Application_ROM_type;
+
+/** @typedef Runtime OS Application descriptor */
+typedef struct {
+ ApplicationStateType ApplState; /**< State of the application */
+ /** Used to flag if the OS-Application is calling a TRUSTED Service */
+ EE_UREG TrustedFunctionCallsCounter;
+} EE_as_Application_RAM_type;
+
+/** Utility to fill EE_as_Application_RAM_type struct */
+#define EE_APP_RAM_INIT(stack) { ((MemoryStartAddressType)(stack)), \
+ APPLICATION_ACCESSIBLE, 0U }
+
+/** @brief Type that hold an hook function pointer (without parameters) */
+typedef void (*EE_HOOKTYPE)(void);
+
+/** @brief Type that hold an hook function pointer
+ * (with a StatusType parameter) */
+typedef void (*EE_STATUSHOOKTYPE)(StatusType);
+
+/** @var Static OS Application info. The first entry is reserved for Kernel
+ * OS-Application. */
+extern const EE_as_Application_ROM_type EE_as_Application_ROM[EE_MAX_APP];
+/** @var Mapping from tasks to applications */
+extern const ApplicationType EE_th_app[EE_MAX_TASK + 1U];
+
+/** @var Mapping from ISRs to applications */
+extern const EE_as_ISR_ROM_type EE_as_ISR_ROM[EE_MAX_ISR_ID];
+
+/** @brief OS Applications STARTUPHOOKs List */
+extern EE_HOOKTYPE const EE_as_Application_startuphook[EE_MAX_APP];
+
+/** @brief OS Applications SHUTDOWNHOOKs List */
+extern EE_STATUSHOOKTYPE const EE_as_Application_shutdownhook[EE_MAX_APP];
+
+/** @brief OS Applications ERRORHOOKs List */
+extern EE_STATUSHOOKTYPE const EE_as_Application_errorhook[EE_MAX_APP];
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @var To flag which OS-Application is running */
+extern ApplicationType EE_as_active_app;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/** @var Run-time info about applications. The first entry is reserved for
+ * Kernel OS-Application. */
+extern EE_as_Application_RAM_type EE_as_Application_RAM[EE_MAX_APP];
+
+#if (defined(EE_MAX_NESTING_LEVEL))
+/** @var LIFO list of running ISRs. The current record is given by
+ * (EE_hal_get_IRQ_nesting_level() - 1U), when an ISR is running. */
+extern EE_as_ISR_RAM_type EE_as_ISR_stack[EE_MAX_NESTING_LEVEL];
+#endif /* EE_MAX_NESTING_LEVEL */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __EE_MEMORY_PROTECTION__
+/*******************************************************************************
+ * Memory Protection Support
+ ******************************************************************************/
+
+/*
+ * 8.2 Macros
+ */
+#define OSMEMORY_IS_READABLE(acc) (((acc) & EE_ACCESS_READ) != (AccessType)0)
+#define OSMEMORY_IS_WRITEABLE(acc) (((acc) & EE_ACCESS_WRITE) != (AccessType)0)
+#define OSMEMORY_IS_EXECUTABLE(acc) (((acc) & EE_ACCESS_EXEC) != (AccessType)0)
+#define OSMEMORY_IS_STACKSPACE(acc) (((acc) & EE_ACCESS_STACK) != (AccessType)0)
+
+/*
+ * 8.3 Type definitions
+ */
+
+/** @typedef This data type identifies a trusted function. */
+typedef EE_UINT32 TrustedFunctionIndexType;
+/** @typedef This data type points to a structure which holds the arguments
+ * for a call to a trusted function. */
+typedef void *TrustedFunctionParameterRefType;
+
+/** @typedef This type holds information how a specific memory region can be
+ * accessed. */
+typedef EE_UREG AccessType;
+
+/* AccessType is a mask made by ORing together a subset of these bits: */
+#define EE_ACCESS_READ ((AccessType)0x1U)
+#define EE_ACCESS_WRITE ((AccessType)0x2U)
+#define EE_ACCESS_EXEC ((AccessType)0x4U)
+#define EE_ACCESS_STACK ((AccessType)0x8U)
+
+/** @typedef This data type holds the size (in bytes) of a memory region. */
+typedef EE_UREG MemorySizeType;
+#endif /* __EE_MEMORY_PROTECTION__ */
+
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+/*******************************************************************************
+ * 7.3 Schedule Tables (AUTOSAR_SWS_OS R4.0 Rev 3)
+ ******************************************************************************/
+#ifdef EE_AS_SCHEDULETABLES__
+/* IMPORTANT (Implementation Notes):
+ * In order to Implement Schedule Tables re-using the majority possible of
+ * alarms handling code, we will declare a "complete alarm" (this means with
+ * both RAM and ROM structures configured) for each schedule table appended to
+ * the "Users Alarms". And a "partial alarm" (this means with only the ROM
+ * structure configured) for each "Expiry Point Action", appended to
+ * "Schedule Tables Alarms".
+ */
+
+/** @typedef This data type identifies a schedule table. */
+typedef EE_UTID ScheduleTableType;
+#define INVALID_SCHEDULETABLE ((ScheduleTableType)-1)
+
+#ifdef EE_AS_AUTOSTART_SCHEDULETABLE__
+
+typedef enum EE_as_kind_of_start_type {
+ /** Declare that the schedule table have to be started as
+ * StartScheduleTableRel does */
+ EE_ST_START_ABSOLUTE,
+ /** Declare that the schedule table have to be started as
+ * StartScheduleTableAbs does */
+ EE_ST_START_RELATIVE,
+ /** Declare that the schedule table have to be started as
+ * StartScheduleTableSynchron does.XXX: Not implement yet */
+ EE_ST_START_SYNCHRON
+} EE_as_kind_of_start;
+
+/** @typedef Type used to support schedule table autostart data */
+typedef struct EE_as_schedule_table_autostart_data_type {
+ /** ID of the schedule table to be started */
+ ScheduleTableType scheduletable_id;
+ /** Type of start */
+ EE_as_kind_of_start start_kind;
+ /** Start primitive parameters his semantics is tied to the start kind:
+ * it could be an offset or the absolute counter value. In case of SYNCRON
+ * Start it is useless */
+ TickType start_value;
+} EE_as_schedule_table_autostart_data;
+
+/** @typedef Type used to support schedule table autostart */
+typedef struct EE_as_schedule_table_autostart_type_ {
+ /** Number of alarms that have to be automatically set at startup for a given
+ * application mode */
+ EE_UREG n;
+ const EE_as_schedule_table_autostart_data *autostart_schedule_tables;
+} EE_as_schedule_table_autostart_type;
+
+/** For each valid APPMODE (that ranges from 0 to EE_MAX_APPMODE-1) there must
+ * be an item in this array with the tasks that are activated at startup. */
+extern const EE_as_schedule_table_autostart_type
+ EE_as_schedule_table_autostart[] /*EE_MAX_APPMODE*/;
+
+#endif /* EE_AS_AUTOSTART_SCHEDULETABLE__ */
+
+/** @typedef This type describes the status of a schedule. The status can be
+ * one of the following: */
+typedef EE_TYPESTATUS ScheduleTableStatusType;
+
+/** The schedule table is not started. */
+#define SCHEDULETABLE_STOPPED 0U
+/** The schedule table will be started after the end of currently running
+ * schedule table (schedule table was used in NextScheduleTable() service). */
+#define SCHEDULETABLE_NEXT 1U
+/** The schedule table uses explicit synchronization, has been started and is
+ * waiting for the global time. */
+#define SCHEDULETABLE_WAITING 2U
+/** The schedule table is running, but is currently not synchronous to a
+ * global time source. */
+#define SCHEDULETABLE_RUNNING 3U
+/** Used as bit-mask, flag if the schedule table is synchronized */
+#define SCHEDULETABLE_SYNCHRONOUS 0x04U
+/** Used as bit-mask, flag if the schedule table shall be not synchronized */
+#define SCHEDULETABLE_ASYNC 0x08U
+/** The schedule table is running and is synchronous to a global time source
+ * (SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS) */
+#define SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS SCHEDULETABLE_RUNNING + \
+ SCHEDULETABLE_SYNCHRONOUS
+
+
+/** @typedef This data type points to a variable of the data type
+ * ScheduleTableStatusType. */
+typedef ScheduleTableStatusType *ScheduleTableStatusRefType;
+
+/** @typedef Schedule Table Synchronization strategies symbols */
+typedef enum {
+ /** No support for synchronization. (default) */
+ EE_SCHEDTABLE_SYNC_NONE,
+ /** The counter driving the schedule table is the counter with which
+ * synchronization is required */
+ EE_SCHEDTABLE_SYNC_IMPLICIT,
+ /** The schedule table is driven by an OS counter but processing needs to be
+ * synchronized with a different counter which is not an OS counter object.
+ * Specification of Operating System */
+ EE_SCHEDTABLE_SYNC_EXPLICIT
+} EE_as_synch_strategy;
+
+/** @typedef to have a more harmonized type name with other OSEK type names. */
+typedef EE_as_synch_strategy SynchStrategyType;
+
+/** @typedef Structures that hold the information related to an expiry point */
+typedef struct {
+ /** Expiry point offset in its own schedule table */
+ TickType offset;
+ /** Index of the first expiry point's action */
+ ActionType actions_first;
+ /** Index of the last expiry point's action */
+ ActionType actions_last;
+ /** Maximum value that can be subtracted from the expiry offset */
+ TickType max_shorten;
+ /** Maximum value that can be added to the expiry point offset */
+ TickType max_lengthen;
+} EE_as_Expiry_Point_ROM_type;
+
+/** @typedef to have a more harmonized type name with other OSEK type names. */
+typedef EE_UREG ExpiryPointType;
+
+/**
+ * @typedef EE_as_Schedule_Table_ROM_type
+ *
+ * This is the data structure used to describe the constant part of a
+ * schedule table. */
+typedef struct {
+ /** Index of the first schedule table's expiry point. */
+ ExpiryPointType expiry_point_first;
+ /** Index of the last schedule table's expiry point. */
+ ExpiryPointType expiry_point_last;
+ /** Schedule table synchronization strategy */
+ SynchStrategyType sync_strategy;
+ /** The length of the schedule table in ticks */
+ TickType duration;
+ /** Minimum deviation from synchronization source to be synchronized */
+ TickType precision;
+ /** TRUE if the schedule table shall be repeated after the last expiry point,
+ * FALSE if the schedule table is single-shot */
+ EE_TYPEBOOL repeated;
+#ifdef EE_AS_OSAPPLICATIONS__
+ /** The ID of the application to which this schedule table belong to. */
+ ApplicationType ApplID;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+} EE_as_Schedule_Table_ROM_type;
+
+#define INVALID_SCHEDULETABLE_PRECISION ((TickType)-1)
+
+/**
+ * @typedef EE_as_Schedule_Table_RAM_type
+ *
+ * Data structure to store variable informations about a schedule table.
+ */
+typedef struct {
+ /** Schedule Table current status */
+ ScheduleTableStatusType status;
+ /** Expiry point to be processed in the schedule table */
+ EE_UREG position;
+ /** Deviation of the schedule table from synchronization */
+ TickType deviation;
+ /** ID of next schedule table to be started */
+ ScheduleTableType next_table;
+} EE_as_Schedule_Table_RAM_type;
+#define INVALID_SCHEDULETABLE_POSITION ((EE_UREG)-1)
+
+/** @var Array of constant descriptors of Expiry accessed by
+ #ScheduleTableType values*/
+extern const EE_as_Expiry_Point_ROM_type
+ EE_as_Expiry_Point_ROM[] /*EE_MAX_SCHEDULETABLE*/;
+
+
+/** @var Array of constant descriptors of schedule tables accessed by
+ #ExpiryPointType values */
+extern const EE_as_Schedule_Table_ROM_type
+ EE_as_Schedule_Table_ROM[] /*EE_MAX_SCHEDULETABLE*/;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA API section: ee_kernel_data */
+#define OS_START_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+
+/** @var Array of mutable descriptors of schedule tables accessed by
+ #ScheduleTableType values */
+extern EE_as_Schedule_Table_RAM_type
+ EE_as_Schedule_Table_RAM[] /*EE_MAX_SCHEDULETABLE*/;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_DATA
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+/***************************************************************************
+* 13.8 Hook routines
+***************************************************************************/
+
+
+/* 13.8.1 Data Types */
+/* ----------------------------------------------------------------------- */
+
+/** @typedef This data type represents the identification of system services. */
+typedef EE_TYPEOSSERVICEID OSServiceIdType;
+
+/** @typedef primitive object id parameter type */
+typedef EE_UTID EE_os_param_id;
+#define INVALID_OBJECTID ((EE_os_param_id)-1)
+
+/** @typedef primitive parameter type */
+typedef union EE_os_param_type {
+ EE_UREG value_param;
+ TaskRefType task_ref;
+ TaskStateRefType task_state_ref;
+#ifndef __OO_NO_ALARMS__
+ AlarmBaseRefType alarm_base_ref;
+ TickRefType tick_ref;
+#endif /* !__OO_NO_ALARMS__ */
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+ EventMaskRefType event_ref;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+#ifdef EE_AS_USER_SPINLOCKS__
+ TryToGetSpinlockType *try_to_get_spinlock_ref;
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#ifdef EE_AS_SCHEDULETABLES__
+ ScheduleTableStatusRefType schedule_table_status_ref;
+#endif /* EE_AS_SCHEDULETABLES__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+#if (defined(EE_SYSCALL_NR) && defined(EE_MAX_SYS_SERVICEID) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID))
+ TrustedFunctionParameterRefType trusted_function_parameter_ref;
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+ ApplicationStateRefType application_state_ref;
+#ifdef __EE_MEMORY_PROTECTION__
+ MemoryStartAddressType memory_address;
+#endif /* __EE_MEMORY_PROTECTION__ */
+#endif /* EE_AS_OSAPPLICATIONS__ */
+#ifdef __OO_SEM__
+ SemRefType sem_ref;
+#endif /* __OO_SEM__ */
+} EE_os_param;
+
+/* 13.8.3 Constants */
+/* ----------------------------------------------------------------------- */
+
+/* To be used as place holder when an API doesn't have a parameter */
+/* defined in ee_startos.c */
+extern const EE_os_param EE_os_invalid_param;
+
+#define EE_OS_INVALID_PARAM (EE_os_invalid_param)
+
+/* unique identifier of system service xx */
+#define OSServiceId_ActivateTask 1U
+#define OSServiceId_TerminateTask 2U
+#define OSServiceId_ChainTask 3U
+#define OSServiceId_Schedule 4U
+#define OSServiceId_GetTaskID 5U
+#define OSServiceId_GetTaskState 6U
+/* DisableAllInterrupts, EnableAllInterrupts, SuspendAllInterrupts,
+ * ResumeAllInterrupts, SuspendOSInterrupts, ResumeOSInterrupts never
+ * return an error */
+#define OSServiceId_GetResource 7U
+#define OSServiceId_ReleaseResource 8U
+#define OSServiceId_SetEvent 9U
+#define OSServiceId_ClearEvent 10U
+#define OSServiceId_GetEvent 11U
+#define OSServiceId_WaitEvent 12U
+#define OSServiceId_GetAlarmBase 13U
+#define OSServiceId_GetAlarm 14U
+#define OSServiceId_SetRelAlarm 15U
+#define OSServiceId_SetAbsAlarm 16U
+#define OSServiceId_CancelAlarm 17U
+#define OSServiceId_IncrementCounter 18U
+#define OSServiceId_GetCounterValue 19U
+#define OSServiceId_GetElapsedValue 20U
+
+/* GetActiveApplicationMode, ShutdownOS never return an error */
+#define OSServiceId_StartOS 21U
+#define OSServiceId_ForceSchedule 22U
+
+/* Special value to flag an error happened in the Task body
+ * needed for AS requirement [OS069] */
+#define OSId_TaskBody 23U
+/* Special value to flag an error happened in the ISR2 body
+ * needed for AS requirement [OS368] */
+#define OSId_ISR2Body 24U
+/* Special value to flag an error happened in a Alarm or Schedule Table
+ * action */
+#define OSId_Action 25U
+/* Special value to flag an error happened in a Kernel only callable service
+ * (like EE_oo_IncrementCounterHardware) */
+#define OSId_Kernel 26U
+
+#ifdef __OO_SEM__
+/* InitSem, TryWaitSem, GetValueSem never return an error */
+#define OSServiceId_GetValueSem 27U
+#define OSServiceId_WaitSem 28U
+#define OSServiceId_PostSem 29U
+#define OSServiceId_TryWaitSem 30U
+/* Flag the first id free for new services */
+#define OSId_OO_Services_End 30U
+#else /* __OO_SEM__ */
+/* Flag the first id free for new services */
+#define OSId_OO_Services_End 27U
+#endif /* __OO_SEM__ */
+
+/* 13.8.4 Macros */
+/* ----------------------------------------------------------------------- */
+
+/* The following type MUST be visible always, because the "New Error Handling"
+ * implementation */
+/** @var structure that hold the service that caused an Error parameter value */
+typedef struct EE_oo_ErrorHook_parameters_type {
+ EE_os_param param1;
+ EE_os_param param2;
+ EE_os_param param3;
+} EE_oo_ErrorHook_parameters;
+
+#if (defined(__OO_HAS_ERRORHOOK__)) && (!defined(__OO_ERRORHOOK_NOMACROS__))
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* Used to flag if we are already in a ErrorHook */
+extern EE_TYPEBOOL EE_ErrorHook_nested_flag;
+
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Stop ERIKA API */
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifndef __MSRP__
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+extern OSServiceIdType EE_oo_ErrorHook_ServiceID;
+extern EE_oo_ErrorHook_parameters EE_oo_ErrorHook_data;
+
+#define EE_oo_get_errorhook_service_id() (&EE_oo_ErrorHook_ServiceID)
+#define EE_oo_get_errorhook_data() (&EE_oo_ErrorHook_data)
+
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Stop ERIKA API */
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#else /* !__MSRP__ */
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+extern OSServiceIdType EE_SHARED_UDATA EE_oo_ErrorHook_ServiceID[EE_MAX_CPU];
+extern EE_oo_ErrorHook_parameters EE_SHARED_UDATA
+ EE_oo_ErrorHook_data[EE_MAX_CPU];
+#ifdef EE_SUPPORT_MEMMAP_H
+#define SHARED_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#define EE_oo_get_errorhook_service_id() \
+ (&EE_oo_ErrorHook_ServiceID[EE_hal_get_core_id()])
+#define EE_oo_get_errorhook_data() \
+ (&EE_oo_ErrorHook_data[EE_hal_get_core_id()])
+#endif /* !__MSRP__ */
+
+#endif /* __OO_ERRORHOOK_NOMACROS__ && !__OO_HAS_ERRORHOOK__ */
+
+#endif /* __INCLUDE_OO_COMMON_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_inline.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_inline.h
new file mode 100644
index 0000000..583744e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_inline.h
@@ -0,0 +1,311 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2004 Paolo Gai
+ * CVS: $Id: ee_inline.h,v 1.3 2006/04/08 21:15:23 pj Exp $
+ */
+
+/* This file is ONLY included when we are NOT compiling a library that
+ * will be used in BINARY DISTRIBUTIONS */
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_INLINE_H
+#define PKG_KERNEL_OO_INC_EE_OO_INLINE_H
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/***************************************************************************
+* 13.3 Interrupt handling
+***************************************************************************/
+
+/***************************************************************************
+* The simbol EE_OLD_HAL marks architecture that doesn't not implement new
+* HAL APIs (MUST be defined in the header ee_cpu.h of these architectures)
+***************************************************************************/
+#ifndef EE_OLD_HAL
+/* 13.3.2.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_ENABLEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_EnableAllInterrupts(void)
+{
+ register volatile EE_FREG temp_suspend;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+ /* I begin with the suspend for atomicity. */
+ temp_suspend = EE_hal_suspendIRQ();
+ /* [OS299]: If EnableAllInterrupts()/ResumeAllInterrupts()/
+ * ResumeOSInterrupts() are called and no corresponding
+ * DisableAllInterupts()/SuspendAllInterrupts()/SuspendOSInterrupts()
+ * was done before, the Operating System shall not perform this OS
+ * service. */
+ if (EE_oo_IRQ_disable_count > 0U) {
+ --EE_oo_IRQ_disable_count;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ /* Stop DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_stop_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+
+ EE_hal_enableIRQ();
+ }
+ } else {
+ /* Revert What I did */
+ EE_hal_resumeIRQ(temp_suspend);
+ }
+ EE_ORTI_set_service_out(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+}
+#endif
+
+/* 13.3.2.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_DISABLEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_DisableAllInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+ /* I begin with the disable for atomicity. */
+ EE_hal_disableIRQ();
+ ++EE_oo_IRQ_disable_count;
+
+ /* Enable DisableAllInterrupts TP budget, if needed */
+ if (EE_oo_IRQ_disable_count == 1U) {
+ EE_as_tp_active_activate_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_DISABLEALLINTERRUPTS__ && ! __EE_MEMORY_PROTECTION__ */
+
+/* 13.3.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_ResumeAllInterrupts(void)
+{
+ register volatile EE_FREG temp_suspend;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+ /* I begin with the suspend for atomicity. */
+ temp_suspend = EE_hal_suspendIRQ();
+ /* OS299: If EnableAllInterrupts()/ResumeAllInterrupts()/ResumeOSInterrupts()
+ * are called and no corresponding DisableAllInterupts()/
+ * SuspendAllInterrupts() / SuspendOSInterrupts() was done before,
+ * the Operating System shall not perform this OS service. */
+ if (EE_oo_IRQ_disable_count > 0U) {
+ --EE_oo_IRQ_disable_count;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ /* Stop DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_stop_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ EE_hal_resumeIRQ(EE_oo_IRQ_suspend_status);
+ }
+ } else {
+ /* Revert What I did */
+ EE_hal_resumeIRQ(temp_suspend);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_RESUMEALLINTERRUPTS__ && ! __EE_MEMORY_PROTECTION__ */
+
+/* 13.3.2.4: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_SuspendAllInterrupts(void)
+{
+ register volatile EE_FREG temp_suspend;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+ /* I begin with the suspend for atomicity. */
+ temp_suspend = EE_hal_suspendIRQ();
+ /* Increment disabling counter */
+ EE_oo_IRQ_disable_count++;
+ /* Check if this is the first time that a Disable/Suspend function is called
+ * by this TASK */
+ if (EE_oo_IRQ_disable_count == 1U) {
+ EE_oo_IRQ_suspend_status = temp_suspend;
+ /* Enable DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_activate_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_SUSPENDALLINTERRUPTS__ && ! __EE_MEMORY_PROTECTION__ */
+
+/* 13.3.2.5: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEOSINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_ResumeOSInterrupts(void)
+{
+ register volatile EE_FREG temp_suspend;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RESUMEOSINTERRUPTS);
+ /* I begin with the suspend for atomicity. */
+ temp_suspend = EE_hal_suspendIRQ();
+ /* [OS299]: If EnableAllInterrupts()/ResumeAllInterrupts()/ResumeOSInterrupts()
+ * are called and no corresponding DisableAllInterupts()/
+ * SuspendAllInterrupts() / SuspendOSInterrupts() was done before,
+ * the Operating System shall not perform this OS service. */
+ if (EE_oo_IRQ_disable_count > 0U) {
+ --EE_oo_IRQ_disable_count;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ /* Stop DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_stop_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ EE_hal_resumeIRQ(EE_oo_IRQ_suspend_status);
+ }
+ } else {
+ /* Revert What I did */
+ EE_hal_resumeIRQ(temp_suspend);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RESUMEOSINTERRUPTS);
+}
+#endif /* ! __PRIVATE_RESUMEOSINTERRUPTS__ && ! __EE_MEMORY_PROTECTION__ */
+
+/* 13.3.2.6: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDOSINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_SuspendOSInterrupts(void)
+{
+ register volatile EE_FREG temp_suspend;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SUSPENDOSINTERRUPTS);
+ /* I begin with the suspend for atomicity. */
+ temp_suspend = EE_hal_suspendIRQ();
+ /* Increment disabling counter */
+ EE_oo_IRQ_disable_count++;
+ /* Check if this is the first time that a Disable/Suspend function is called
+ * by this TASK */
+ if (EE_oo_IRQ_disable_count == 1U) {
+ EE_oo_IRQ_suspend_status = temp_suspend;
+ /* Enable DisableAllInterrupts TP budget, if needed */
+ EE_as_tp_active_activate_budget(EE_ALL_INTERRUPT_LOCK_BUDGET,
+ INVALID_OBJECTID, EE_TRUE);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SUSPENDOSINTERRUPTS);
+}
+#endif /* ! __PRIVATE_SUSPENDOSINTERRUPTS__ && ! __EE_MEMORY_PROTECTION__ */
+
+#else /* !!! OLD INTERRUPT HANDLING PRIMITIVES !!! */
+
+/* 13.3.2.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_ENABLEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_EnableAllInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+
+ EE_hal_enableIRQ();
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_ENABLEALLINTERRUPTS);
+}
+#endif
+
+/* 13.3.2.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_DISABLEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_DisableAllInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+
+ EE_hal_disableIRQ();
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_DISABLEALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_DISABLEALLINTERRUPTS__ */
+
+/* 13.3.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_ResumeAllInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+
+ EE_oo_IRQ_disable_count--;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ EE_hal_enableIRQ();
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RESUMEALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_RESUMEALLINTERRUPTS__ */
+
+/* 13.3.2.4: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDALLINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_SuspendAllInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+
+ if (EE_oo_IRQ_disable_count == 0U) {
+ EE_hal_disableIRQ();
+ }
+ EE_oo_IRQ_disable_count++;
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SUSPENDALLINTERRUPTS);
+}
+#endif /* ! __PRIVATE_SUSPENDALLINTERRUPTS__ */
+
+/* 13.3.2.5: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RESUMEOSINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_ResumeOSInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RESUMEOSINTERRUPTS);
+
+ EE_oo_IRQ_disable_count--;
+ if (EE_oo_IRQ_disable_count == 0U) {
+ EE_hal_enableIRQ();
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RESUMEOSINTERRUPTS);
+}
+#endif /* ! __PRIVATE_RESUMEOSINTERRUPTS__ */
+
+/* 13.3.2.6: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SUSPENDOSINTERRUPTS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_SuspendOSInterrupts(void)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SUSPENDOSINTERRUPTS);
+
+ if (EE_oo_IRQ_disable_count == 0U) {
+ EE_hal_disableIRQ();
+ }
+ EE_oo_IRQ_disable_count++;
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SUSPENDOSINTERRUPTS);
+}
+#endif /* ! __PRIVATE_SUSPENDOSINTERRUPTS__ */
+
+#endif /* EE_OLD_HAL */
+
+#endif /* __INCLUDE_OO_INLINE_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_internal.h
new file mode 100644
index 0000000..d6a3e16
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_internal.h
@@ -0,0 +1,796 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_internal.h,v 1.6 2006/12/03 22:07:50 pj Exp $
+ */
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_INTERNAL_H
+#define PKG_KERNEL_OO_INC_EE_OO_INTERNAL_H
+
+#include "kernel/oo/inc/ee_oo_common.h"
+#include "kernel/oo/inc/ee_oo_intfunc.h"
+#include "kernel/oo/inc/ee_oo_irq.h"
+
+/*******************************************************************************
+ * New Error Handling Internal Utilities
+ ******************************************************************************/
+
+/* Error Parameters Utilities Macros */
+#define EE_OS_PARAM(param_name) EE_os_param param_name
+#define EE_OS_PARAM_VALUE(param_name, param_value) \
+ ((param_name).value_param = (param_value))
+
+#define EE_OS_PARAM_REF(param_name, param_field, param_ref) \
+ ((param_name).param_field = (param_ref))
+
+#ifdef __OO_HAS_ERRORHOOK__
+/* Error Parameters Data Structure Utilities Macros from user space */
+#define EE_OS_ERROR_PARAMETERS() EE_oo_ErrorHook_parameters error_parameters
+
+#define EE_OS_ERROR_PARAMETERS_INIT(param1_in, param2_in, param3_in) \
+ EE_oo_ErrorHook_parameters error_parameters = { param1_in, param2_in, \
+ param3_in }
+
+#define EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(param1_value) \
+ (error_parameters.param1.value_param = param1_value)
+#define EE_OS_ERROR_PARAMETERS_PARAM2_VALUE(param2_value) \
+ (error_parameters.param2.value_param = param2_value)
+#define EE_OS_ERROR_PARAMETERS_PARAM3_VALUE(param3_value) \
+ (error_parameters.param3.value_param = param3_value)
+
+#define EE_OS_ERROR_PARAMETERS_PARAM1_REF(param_field, param_ref) \
+ (error_parameters.param1.param_field = (param_ref))
+#define EE_OS_ERROR_PARAMETERS_PARAM2_REF(param_field, param_ref) \
+ (error_parameters.param2.param_field = (param_ref))
+#define EE_OS_ERROR_PARAMETERS_PARAM3_REF(param_field, param_ref) \
+ (error_parameters.param3.param_field = (param_ref))
+#else /* __OO_HAS_ERRORHOOK__ */
+#define EE_OS_ERROR_PARAMETERS() ((void)0)
+
+#define EE_OS_ERROR_PARAMETERS_INIT(param1_in, param2_in, param3_in) ((void)0)
+
+#define EE_OS_ERROR_PARAMETERS_PARAM1_VALUE(param1_value) ((void)0)
+#define EE_OS_ERROR_PARAMETERS_PARAM2_VALUE(param2_value) ((void)0)
+#define EE_OS_ERROR_PARAMETERS_PARAM3_VALUE(param3_value) ((void)0)
+
+#define EE_OS_ERROR_PARAMETERS_PARAM1_REF(param_field, param_ref) ((void)0)
+#define EE_OS_ERROR_PARAMETERS_PARAM2_REF(param_field, param_ref) ((void)0)
+#define EE_OS_ERROR_PARAMETERS_PARAM3_REF(param_field, param_ref) ((void)0)
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+/* Error Handling */
+#ifdef __OO_HAS_ERRORHOOK__
+#ifndef __OO_ERRORHOOK_NOMACROS__
+
+__INLINE__ void __ALWAYS_INLINE__ EE_os_fill_error_data(OSServiceIdType
+ ServiceID,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = ServiceID;
+ p_errorhook_parameter->param1 = param1;
+ p_errorhook_parameter->param2 = param2;
+ p_errorhook_parameter->param3 = param3;
+}
+#else /* !__OO_ERRORHOOK_NOMACROS__ */
+
+#define EE_os_fill_error_data(ServiceID, param1, param2, param3) ((void)0)
+#endif /* !__OO_ERRORHOOK_NOMACROS__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_os_notify_error(OSServiceIdType ServiceID,
+ EE_os_param param1,
+ EE_os_param param2,
+ EE_os_param param3,
+ StatusType Error)
+{
+ EE_ORTI_set_lasterror(Error);
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_os_fill_error_data(ServiceID, param1, param2, param3);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#ifndef __EE_MEMORY_PROTECTION__
+__INLINE__ void __ALWAYS_INLINE__ EE_os_notify_error_from_us(
+ OSServiceIdType ServiceID,
+ const EE_oo_ErrorHook_parameters *const
+ error_parameters_ref,
+ StatusType Error)
+{
+ if (error_parameters_ref != NULL) {
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+ EE_os_notify_error(ServiceID, error_parameters_ref->param1,
+ error_parameters_ref->param2, error_parameters_ref->param3, Error);
+ EE_hal_end_nested_primitive(flag);
+ }
+}
+#else /* !__EE_MEMORY_PROTECTION__ */
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following code belong to ERIKA API section ee_api_text */
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+void EE_os_notify_error_from_us(OSServiceIdType ServiceID,
+ const EE_oo_ErrorHook_parameters *const error_parameters_ref,
+ StatusType Error);
+
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+#endif /* !__EE_MEMORY_PROTECTION__ */
+#else /* __OO_HAS_ERRORHOOK__ */
+
+/* Macro used for remapping to prevent compiler warnings on unused parameters */
+#define EE_os_notify_error(k, j, x, y, z) EE_os_notify_error_impl(z)
+
+__INLINE__ void __ALWAYS_INLINE__ EE_os_notify_error_impl(StatusType Error)
+{
+ EE_ORTI_set_lasterror(Error);
+}
+
+/* Macro used for remapping to prevent compiler warnings on unused parameters */
+#define EE_os_notify_error_from_us(x, y, z) EE_os_notify_error_from_us_impl(z)
+
+__INLINE__ void __ALWAYS_INLINE__ EE_os_notify_error_from_us_impl(
+ StatusType Error)
+{
+ EE_ORTI_set_lasterror(Error);
+}
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+/*******************************************************************************
+ * Kernel Critical Section Utility Macros
+ ******************************************************************************/
+#ifndef __EE_MEMORY_PROTECTION__
+
+#define EE_OS_DECLARE_CRITICAL_SECTION() register EE_FREG flag
+
+#define EE_OS_ENTER_CRITICAL_SECTION() \
+ do { \
+ flag = EE_hal_begin_nested_primitive(); \
+ EE_as_tp_active_pause_and_update_budgets(); \
+ } while (0)
+
+#define EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION() \
+ EE_OS_DECLARE_CRITICAL_SECTION(); \
+ EE_OS_ENTER_CRITICAL_SECTION()
+
+#define EE_OS_EXIT_CRITICAL_SECTION() \
+ do { \
+ EE_as_tp_active_update_budgets_and_restart(); \
+ EE_hal_end_nested_primitive(flag); \
+ } while (0)
+
+#define EE_OS_FOREVER_CRITICAL_SECTION() \
+ do { \
+ EE_hal_disableIRQ(); \
+ EE_as_tp_active_pause_and_update_budgets(); \
+ } while (0)
+
+#else /* !__EE_MEMORY_PROTECTION__ */
+/* TP in any case have to be handled in Service Implementation. Syscall
+ * mechanism can be implement in C language and, in that case, a function call
+ * cannot be done in syscall handler. */
+#define EE_OS_DECLARE_CRITICAL_SECTION() ((void)0)
+#define EE_OS_ENTER_CRITICAL_SECTION() \
+ EE_as_tp_active_pause_and_update_budgets()
+#define EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION() \
+ EE_as_tp_active_pause_and_update_budgets()
+#define EE_OS_EXIT_CRITICAL_SECTION() \
+ EE_as_tp_active_update_budgets_and_restart()
+#define EE_OS_FOREVER_CRITICAL_SECTION() \
+ EE_as_tp_active_pause_and_update_budgets()
+#endif /* !__EE_MEMORY_PROTECTION__ */
+
+/* return the first stacked task (the running task) without extracting it
+ * we suppose that this function can be called ALSO at interrupt ENABLED!!!
+ * (see WaitEvent.c) */
+#ifndef __PRIVATE_STK_QUERYFIRST__
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void)
+{
+ return EE_stkfirst;
+}
+#endif /* __PRIVATE_STK_QUERYFIRST__ */
+
+/* This function notifies a tick to a hardware counter.
+ * That is, the counter is
+ * incremented by 1. It must be called into an ISR2 or into a
+ * task notify that the event linked to the counter occurred.
+ *
+ * The function will also implement the notification of expired alarms
+ * (calling an alarm callback, setting an event, or activating a
+ * task).
+ *
+ * The function can be considered atomic, and NO RESCHEDULING will
+ * take place after the execution of this function. To implement the
+ * rescheduling at task level, you can use the Schedule() or the
+ * ForceSchedule() functions just after this notification.
+ *
+ * see also internal.h
+ */
+#if (!defined(__OO_NO_ALARMS__)) || (defined(EE_AS_SCHEDULETABLES__))
+
+StatusType EE_oo_IncrementCounterHardware(CounterType CounterID);
+void EE_oo_IncrementCounterImplementation(CounterType CounterID);
+
+/* kernel internal API */
+#define IncrementCounterHardware EE_oo_IncrementCounterHardware
+
+/* Helper function (0 as increment means next tick)*/
+void EE_oo_counter_object_insert(CounterObjectType ObjectID,
+ TickType
+ increment);
+
+#if defined(EE_COUNTER_OBJECTS_ROM_SIZE)
+#if (EE_COUNTER_OBJECTS_ROM_SIZE > 0)
+__INLINE__ void __ALWAYS_INLINE__
+EE_oo_handle_abs_counter_object_insertion(CounterObjectType ObjectID,
+ TickType absstart,
+ TickType abscycle)
+{
+ /* These are used to evaluate alarm time handling wrap around */
+ register TickType alarm_time;
+ register TickType start_rel;
+ register CounterType const cnt = EE_oo_counter_object_ROM[ObjectID].c;
+
+ /* first, use the alarm and set the cycle */
+ EE_oo_counter_object_RAM[ObjectID].used = EE_TRUE;
+ EE_oo_counter_object_RAM[ObjectID].cntcycle = abscycle;
+
+ /* Handling wrap around for alarm time */
+ start_rel = absstart - EE_counter_RAM[cnt].value;
+
+ /* When will be here start value will be already checked against counter
+ * max allowed value */
+ if (start_rel == 0U) {
+ /* start_rel == 0U -> the alarm should start now or next time that counter
+ * has this value. Has been chosen the second option */
+ alarm_time = EE_counter_ROM[cnt].maxallowedvalue;
+ } else if (start_rel < EE_TYPETICK_HALF_VALUE) {
+ /* Normal behavior */
+ alarm_time = start_rel - 1U;
+ } else {
+ /* start_rel is "negative" in this case (unsigned wrap around do the
+ * work) */
+ alarm_time = EE_counter_ROM[cnt].maxallowedvalue + start_rel;
+ }
+
+ /* Set alarm with a relative amount of time (alarm_time already is a "0 as
+ * next tick" value)*/
+ EE_oo_counter_object_insert(ObjectID, alarm_time);
+}
+
+__INLINE__ void __ALWAYS_INLINE__
+EE_oo_handle_rel_counter_object_insertion(CounterObjectType ObjectID,
+ TickType increment,
+ TickType relcycle)
+{
+ /* first, use the alarm and set the cycle */
+ EE_oo_counter_object_RAM[ObjectID].used = EE_TRUE;
+ EE_oo_counter_object_RAM[ObjectID].cntcycle = relcycle;
+
+ /* then, insert the task into the delta queue with an increment equal
+ * (increment - 1U) increment equal to 0 means next tick */
+ EE_oo_counter_object_insert(ObjectID, (increment - 1U));
+}
+
+/* cancellation */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_handle_counter_object_cancellation(
+ CounterObjectType ObjectID)
+{
+ register CounterObjectType current, previous;
+ register CounterType ct = EE_oo_counter_object_ROM[ObjectID].c;
+
+ /* to compute the relative value in ticks, we have to follow the counter
+ * delay chain */
+ current = EE_counter_RAM[ct].first;
+
+ if (current == ObjectID) {
+ /* the alarm is the first one in the delta queue */
+ EE_counter_RAM[ct].first = EE_oo_counter_object_RAM[ObjectID].next;
+ } else {
+ /* the alarm is not the first one in the delta queue */
+ /* Find it */
+ do {
+ previous = current;
+ if (current < EE_COUNTER_OBJECTS_ROM_SIZE) {
+ current = EE_oo_counter_object_RAM[current].next;
+ }
+ } while ((current != ObjectID) && (current < EE_COUNTER_OBJECTS_ROM_SIZE));
+ /* remove it from the queue */
+ if (previous < EE_COUNTER_OBJECTS_ROM_SIZE) {
+ EE_oo_counter_object_RAM[previous].next =
+ EE_oo_counter_object_RAM[ObjectID].next;
+ }
+ }
+ /* Adjust delta value */
+ if (EE_oo_counter_object_RAM[ObjectID].next != INVALID_COUNTER_OBJECT) {
+ EE_oo_counter_object_RAM[EE_oo_counter_object_RAM[ObjectID].next].delta +=
+ EE_oo_counter_object_RAM[ObjectID].delta;
+ }
+
+ EE_oo_counter_object_RAM[ObjectID].used = EE_FALSE;
+}
+#endif /* EE_COUNTER_OBJECTS_ROM_SIZE */
+#endif /* EE_COUNTER_OBJECTS_ROM_SIZE > 0 */
+#endif /* !__OO_NO_ALARMS__ || EE_AS_SCHEDULETABLES__ */
+
+/*************************************************************************
+* HAL extensions
+*************************************************************************/
+
+/* these are the functions that have been inserted to support tha OO layer
+ * under the EE HAL.
+ *
+ * - all the functions for interrupt handling (13.3)
+ * - EE_hal_begin_nested_primitive
+ * EE_hal_end_nested_primitive
+ * (for primitives that can be called both into a task and into an ISR2
+ * - EE_hal_terminate_task(EE_TID t)
+ * - EE_hal_terminate_savestk(EE_TID t)
+ * EE_oo_preemption_point() execute task preemption if is needed
+ * - EE_oo_shutdown() if not redefined it does for(;;);
+ * - All the alarm constants listed in 13.6.4
+ */
+
+
+/***************************************************************************
+* Internal data structures and functions
+***************************************************************************/
+
+/*
+ * Call Hooks utilities
+ */
+
+#ifdef __OO_HAS_PRETASKHOOK__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_PreTaskHook(void)
+{
+ EE_as_set_execution_context(PreTaskHook_Context);
+ PreTaskHook();
+ /* Set the execution context on TASK */
+ EE_as_set_execution_context(TASK_Context);
+}
+
+#else /* __OO_HAS_PRETASKHOOK__ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_PreTaskHook(void)
+{
+ /* Set the execution context on TASK */
+ EE_as_set_execution_context(TASK_Context);
+}
+#endif /* __OO_HAS_PRETASKHOOK__ */
+
+#if defined(__OO_HAS_POSTTASKHOOK__)
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_PostTaskHook(void)
+{
+ EE_as_set_execution_context(PostTaskHook_Context);
+ PostTaskHook();
+}
+#else /* __OO_HAS_POSTTASKHOOK__ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_PostTaskHook(void)
+{
+}
+#endif /* __OO_HAS_POSTTASKHOOK__ */
+
+
+/* StartOS Flag defined inside ee_startos.c to check that the system has correctly started */
+extern EE_UREG volatile EE_oo_started;
+
+
+/* Used to check if we are in disable interrupt error. It return
+ * 'signed register type' because usually it is native integer type. */
+__INLINE__ EE_TYPEBOOL __ALWAYS_INLINE__ EE_oo_check_disableint_error(void)
+{
+ return EE_oo_IRQ_disable_count != 0U;
+}
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+/* A lookup table to speedup ready queue handling */
+extern const EE_INT8 EE_rq_lookup[256];
+/* Lookup functions */
+#if defined(__OO_ECC2__)
+__INLINE__ EE_INT8 __ALWAYS_INLINE__ EE_rq_get_first_not_empty_queue(void)
+{
+ /* Lookup at bits 15-9 */
+ EE_INT8 x = EE_rq_lookup[(EE_rq_bitmask & 0xFF00U) >> 8];
+
+ if (x == (EE_INT8)-1) {
+ x = EE_rq_lookup[EE_rq_bitmask];
+ } else {
+ x += (EE_INT8)8;
+ }
+ return x;
+}
+#else /* __OO_ECC2__ */
+__INLINE__ EE_INT8 __ALWAYS_INLINE__ EE_rq_get_first_not_empty_queue(void)
+{
+ return EE_rq_lookup[EE_rq_bitmask];
+}
+#endif /* __OO_ECC2__ */
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+/* Internal Queue management functions */
+
+/* return the first ready task without extracting it */
+#ifndef __PRIVATE_RQ_QUERYFIRST__
+#if (defined(__OO_BCC1__)) || (defined(__OO_ECC1__))
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_rq_queryfirst(void)
+{
+ return EE_rq_first;
+}
+#endif
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+EE_TID EE_rq_queryfirst(void);
+#endif
+#endif
+
+/* __INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_queryfirst(void) in intfunc.h */
+
+/* Extract the RUNNING task from the stack, and return the new head */
+#ifndef __PRIVATE_STK_GETFIRST__
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_stk_getfirst(void)
+{
+ return EE_stkfirst = EE_th_next[EE_stkfirst];
+}
+#endif /* __PRIVATE_STK_GETFIRST__ */
+
+/* insert a task into the stack data structures */
+#ifndef __PRIVATE_STK_INSERTFIRST__
+__INLINE__ void __ALWAYS_INLINE__ EE_stk_insertfirst(EE_TID t)
+{
+ EE_th_next[t] = EE_stkfirst;
+ EE_stkfirst = t;
+}
+#endif
+
+/* insert a task into the ready queue */
+#ifndef __PRIVATE_RQ_INSERT__
+void EE_rq_insert(EE_TID t);
+#endif
+
+/* put the first ready task into the stack */
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+EE_TID EE_rq2stk_exchange(void);
+#endif
+
+#ifndef __OO_NO_RESOURCES__
+/*
+ * Method to release all resources locked by a Thread,
+ * used to fulfill AS requirement OS070
+ */
+#if ((!defined(__OO_EXTENDED_STATUS__)) && \
+ (!defined(__PRIVATE_RELEASEALLRESOURCE__))) && \
+ (!defined(__OO_ISR2_RESOURCES__))
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_release_all_resources(EE_TID tid)
+{
+ /* release the internal resource. a EE_TYPEPRIO is a bit mask with only one
+ * bit set to one.
+ * If i subtract one to this I obtain a bit mask with all
+ * ones before the starting one and all zeros after
+ * (exactly what I want to release resources!)
+ */
+ EE_sys_ceiling &= (EE_th_dispatch_prio[tid] - 1U);
+}
+#else
+EE_UREG EE_oo_release_all_resources(EE_TID tid);
+#endif /* !__OO_EXTENDED_STATUS__ && !__OO_ISR2_RESOURCES__ */
+#else /* __OO_NO_RESOURCES__ */
+#define EE_oo_release_all_resources(tid) ((void)0)
+#endif /* __OO_NO_RESOURCES__ */
+
+#ifndef __PRIVATE_THREANTERMINATED__
+/* this the function that will be called if a Task doesn't end calling
+ * TerminateTask */
+
+extern void EE_thread_not_terminated(void);
+#endif /* __PRIVATE_THREANTERMINATED__ */
+
+/* This call terminates a thread instance. It must be called as the
+ * LAST function call BEFORE the `}' that ends a thread. If the
+ * primitive is not inserted at the end of */
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+void EE_thread_end_instance(void);
+#endif
+
+#if (defined(__OO_ISR2_RESOURCES__)) || (defined(EE_AS_USER_SPINLOCKS__))
+/* Index used to give ISR2 Temporary TID value and to access at
+ * EE_isr2_nesting_level array */
+extern EE_UREG EE_isr2_index;
+
+/* Assign a fake TID to an ISR2 to eventually handle resources clean-up */
+EE_TID EE_oo_assign_TID_to_ISR2(void);
+
+/* Get the last assigned fake ISR2 TID */
+__INLINE__ EE_TID __ALWAYS_INLINE__ EE_oo_get_ISR2_TID(void)
+{
+ return (EE_isr2_index != EE_UREG_MINUS1) ?
+ (EE_MAX_TASK + (EE_TID)EE_isr2_index) : EE_NIL;
+}
+#endif /* __OO_ISR2_RESOURCES__ || EE_AS_USER_SPINLOCKS__ */
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+/*
+ * Reset Active Events THREAD utility method.
+ *
+ * When an extended task is transferred from suspended state
+ * into ready state all its events have to be cleared cleared
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_reset_th_event_active(TaskType tnotactive)
+{
+ EE_th_event_active[tnotactive] = 0U;
+}
+
+/*
+ * This method actually do a CONTEXT SWITCH, with the highest priority TASK
+ */
+#ifdef __MULTI__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_run_next_task(void)
+{
+ register TaskType tmp;
+
+ /* swap from ready queue to stack queue */
+ tmp = EE_rq2stk_exchange();
+ if (EE_th_waswaiting[tmp]) {
+ /* if the task was waiting switch the context to restart it */
+ EE_th_waswaiting[tmp] = EE_FALSE;
+ /* Call the PreTaskHook, here no stub will do that for you */
+ EE_oo_call_PreTaskHook();
+ EE_hal_stkchange(tmp);
+ } else {
+ /* the next task have to be started */
+ EE_hal_ready2stacked(tmp);
+ }
+}
+#else
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_run_next_task(void)
+{
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+}
+#endif /* __MULTI__ */
+#else
+#define EE_oo_reset_th_event_active(TaskID) ((void)0)
+
+/*
+ * This method actually do a CONTEXT SWITCH, with the highest priority TASK
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_run_next_task(void)
+{
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+}
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
+
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+/*
+ * Set THREAD ready utility method.
+ * If the task is BCC2/ECC2 it can be that it is ready or
+ * running. in that case we have to check and queue it anyway
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_set_th_status_ready(TaskType TaskID)
+{
+ if (EE_th_status[TaskID] == SUSPENDED) {
+ EE_th_status[TaskID] = READY;
+ EE_oo_reset_th_event_active(TaskID);
+ }
+}
+#else
+/*
+ * Set THREAD ready utility method
+ * If the task is BCC1/ECC1 it can be here only because
+ * it had rnact=1 before the call, and so it is in suspended state
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_set_th_status_ready(TaskType tready)
+{
+ EE_th_status[tready] = READY;
+ EE_oo_reset_th_event_active(tready);
+}
+#endif /* defined(__OO_BCC2__) || defined(__OO_ECC2__) */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_task_in_ready_queue(TaskType tid)
+{
+ /* Decrement the residual number activation */
+ --EE_th_rnact[tid];
+ /* Set the status READY handling multiple activations */
+ EE_oo_set_th_status_ready(tid);
+ /* insert the task in the ready queue */
+ EE_rq_insert(tid);
+}
+
+/* Execute a preemption */
+#ifndef __PRIVATE_PREEMPTION_POINTS__
+/*
+ * Moved preemption check implementation into an outside method because the
+ * behaviour is common to EE_ActivateTask, EE_oo_ForceSchedule,
+ * EE_oo_IncrementCounter, EE_oo_ReleaseResource, EE_oo_PostSem
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_preemption_point(void)
+{
+ register EE_TID current, rq;
+
+ /* check if there is a preemption */
+ current = EE_stk_queryfirst();
+ rq = EE_rq_queryfirst();
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(__EE_MEMORY_PROTECTION__))
+#if (defined(EE_SYSCALL_NR)) && (defined(EE_MAX_SYS_SERVICEID)) \
+ && (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+ /* Reaction to timing protection can be defined to terminate the
+ * OSApplication. If a task is inside CallTrustedFunction() and task
+ * rescheduling takes place within the same OSApplication,
+ * the newly running higher priority task may cause timing protection and
+ * terminate the OSApplication, thus indirectly aborting the trusted
+ * function. To avoid this, the scheduling of other Tasks which belong to
+ * the same OS-Application as the caller needs to be restricted, as well as
+ * the availability of interrupts of the same OS-Application. */
+ /* [SWS_Os_00563]: The OperatingSystem shall not schedule any other Tasks
+ * which belong to the same OS-Application as the non-trusted caller of the
+ * service. Also interrupts of Category 2 which belong to the same
+ * OS-Application shall be disabled during the execution of the service. */
+ if ((EE_as_active_app != EE_th_app[rq + 1]) ||
+ (EE_as_Application_RAM[EE_as_active_app].
+ TrustedFunctionCallsCounter == 0U) ||
+ (EE_as_Application_ROM[EE_as_active_app].Mode == EE_MEMPROT_TRUST_MODE)
+ )
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ */
+ {
+ if (rq != EE_NIL) {
+ /* We check if the system ceiling is greater or not the first task
+ * in the ready queue */
+ if (EE_sys_ceiling < EE_th_ready_prio[rq]) {
+ if (current != EE_NIL) {
+ EE_oo_call_PostTaskHook();
+ /* We have to put the task in the READY status */
+ EE_th_status[current] = READY;
+ /* !!! BUT NOT IN THE READY QUEUE !!!
+ * The task remains into the Stacked Queue! */
+ }
+
+ /* Get the new internal resource */
+ EE_sys_ceiling |= EE_th_dispatch_prio[rq];
+ /* Put the task in running state */
+ EE_th_status[rq] = RUNNING;
+
+ EE_ORTI_set_th_eq_dispatch_prio(rq);
+
+ /* "Press TP start for the first time" for this new activation/release of
+ * the TASK */
+ EE_as_tp_active_start_on_TASK_stacking(rq);
+
+ /* Execute context SWITCH, this method return when we have a switch
+ * back on the previous TASK contest. */
+ EE_oo_run_next_task();
+ }
+ }
+ }
+}
+
+#if ((defined(__OO_ECC1__)) || (defined(__OO_ECC2__))) && (defined(__MULTI__))
+
+/* Prepare current Task to Block if Extended Task is configured */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_prepare_to_block(void)
+{
+ /* Get the current TASK */
+ register EE_TID current = EE_stk_queryfirst();
+
+ /* The task must go into the WAITING state */
+ EE_th_status[current] = WAITING;
+
+ /* [SWS_Os_00473]: The Operating System module shall reset a task's
+ * OsTaskExecutionBudget on a transition to the SUSPENDED or WAITING states.
+ * (SRS_Os_11008) */
+ EE_as_tp_stop_budget(EE_as_tp_active.active_tp_RAM_ref, EE_EXECUTION_BUDGET);
+
+ /* Call the Post Task Hook before change stk data structure */
+ EE_oo_call_PostTaskHook();
+
+ /* Reset the thread priority bit in the system_ceiling */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+ /* The ready priority is not touched, it is not the same as Schedule! */
+
+ /* Reset ORTI priority */
+ EE_ORTI_set_th_priority(current, 0U);
+
+ /* Since the task blocks, it has to be woken up by another EE_hal_stkchange */
+ EE_th_waswaiting[current] = EE_TRUE;
+
+ /* Extract the TASK from the stacked queue */
+ (void)EE_stk_getfirst();
+}
+
+/* Reschedule on task blocking if Extended Task is configured */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_reschedule_on_block(void)
+{
+ register EE_TID nexttask;
+
+ nexttask = EE_rq_queryfirst();
+ if ((nexttask == EE_NIL) || (EE_sys_ceiling >= EE_th_ready_prio[nexttask])) {
+ /* we have to schedule an interrupted thread that is on the top
+ * of its stack; the state is already STACKED! */
+ nexttask = EE_stk_queryfirst();
+ if (nexttask != EE_NIL) {
+ EE_th_status[nexttask] = RUNNING;
+ EE_oo_call_PreTaskHook();
+ /* Enable the TASK Timing Protection Set */
+ EE_as_tp_active_set_from_TASK(nexttask);
+ } else {
+ /* We are switching back to the Idle loop */
+ EE_as_set_execution_context(Idle_Context);
+ EE_as_tp_active_start_idle();
+ }
+
+ /* CONTEXT SWITCH to a previous stacked Task */
+ EE_hal_stkchange(nexttask);
+ } else {
+ /* We have to schedule a ready thread that is not yet on the stack.
+ * This means that the TASK set in excution for the first time or that it
+ * was waiting. */
+ EE_th_status[nexttask] = RUNNING;
+ EE_sys_ceiling |= EE_th_dispatch_prio[nexttask];
+
+ EE_ORTI_set_th_eq_dispatch_prio(nexttask);
+
+ /* "Press TP start for the first time" for this new release of the
+ * TASK */
+ EE_as_tp_active_start_on_TASK_stacking(nexttask);
+
+ /* Execute context SWITCH, this method return when we have a switch
+ * back on the previous TASK contest. */
+ EE_oo_run_next_task();
+ }
+}
+#endif /* (__OO_ECC1__ || __OO_ECC2__) && __MULTI__ */
+#endif /* __PRIVATE_PREEMPTION_POINTS__ */
+
+/** Internal part of ShutdownOS Service */
+void EE_oo_ShutdownOS_internal(StatusType Error);
+
+#endif /* __INCLUDE_OO_INTERNAL_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_intfunc.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_intfunc.h
new file mode 100644
index 0000000..2e61c69
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_intfunc.h
@@ -0,0 +1,755 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_intfunc.h,v 1.2 2006/04/08 21:15:23 pj Exp $
+ */
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_INTFUNC_H
+#define PKG_KERNEL_OO_INC_EE_OO_INTFUNC_H
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* The following variables belong to ERIKA OS section: ee_kernel_bss */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* This file contains internal functions and data structures needed to
+ * inline some kernel functions. */
+extern EE_UREG EE_oo_IRQ_disable_count;
+
+/***************************************************************************
+* The simbol EE_OLD_HAL marks architecture that do not implement new
+* HAL APIs (MUST be defined in the header ee_cpu.h of these architectures)
+***************************************************************************/
+#ifndef EE_OLD_HAL
+extern EE_FREG EE_oo_IRQ_suspend_status;
+#endif /* EE_OLD_HAL */
+
+extern EE_TYPEAPPMODE EE_ApplicationMode;
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/***************************************************************************
+* 13.7 Operating system execution control
+***************************************************************************/
+
+/* 13.7.2 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.7.2.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETACTIVEAPPLICATIONMODE__
+/* by default there is only 6the default application mode defined!... */
+__INLINE__ AppModeType __ALWAYS_INLINE__ EE_oo_GetActiveApplicationMode(void)
+{
+ /* EG: XXX Add Service Protection? (I think is just overkilling, can we
+ * just count this as features extension?) */
+ /* Both assignment to enable smart debuggers to notice the entry and
+ * exit from GetActiveApplicationMode.
+ * Note that the variable is volatile, so both the writings succeeds */
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETACTIVEAPPLICATIONMODE);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETACTIVEAPPLICATIONMODE);
+
+ return EE_ApplicationMode;
+}
+#endif /* __PRIVATE_GETACTIVEAPPLICATIONMODE__ */
+
+#if (defined(__MSRP__)) && (!defined(__OO_NO_RESOURCES__))
+__INLINE__ EE_UREG __ALWAYS_INLINE__ EE_oo_isGlobal(ResourceType ResID)
+{
+ register EE_UREG isGlobal, ureg_tmp1, ureg_tmp2;
+ EE_SREG sreg_tmp;
+
+ /* mask off the MSB, that indicates whether this is a global or a
+ * local resource */
+
+ /*
+ * This is the compact expression
+ * isGlobal = ((ResID & EE_GLOBAL_MUTEX) != (ResourceType)0U);
+ *
+ * The following is the extended version introduced to
+ * meet MISRA requirements
+ */
+ ureg_tmp1 = (ResID & EE_GLOBAL_MUTEX);
+ ureg_tmp2 = (ResourceType)0U;
+ sreg_tmp = (EE_SREG)(ureg_tmp1 != ureg_tmp2);
+ isGlobal = (EE_UREG)sreg_tmp;
+
+ return isGlobal;
+}
+#endif /* __MSRP__ && !__OO_NO_RESOURCES__ */
+
+#ifdef __OO_HAS_ERRORHOOK__
+
+#ifdef EE_SERVICE_PROTECTION__
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_ErrorHook(StatusType Error)
+{
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* Call status application hook with right privileges */
+ extern void EE_hal_call_app_status_hook(StatusType Error, EE_STATUSHOOKTYPE
+ status_hook, ApplicationType app);
+
+ register ApplicationType i;
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+ /* Handle Error Hooks execution context */
+ EE_TYPECONTEXT prev_context = EE_as_execution_context;
+
+ /* Set the context execution at ErrorHook Context */
+ EE_as_set_execution_context(ErrorHook_Context);
+
+ ErrorHook(Error);
+
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* [SWS_Os_00246] When an error occurs AND an application-specific error
+ * hook is configured for the faulty OS-Application <App>, the Operating
+ * System module shall call that application-specific error hook
+ * ErrorHook_<App> after the system specific error hook is called
+ * (if configured). (SRS_Os_11013) */
+
+ /* ApplID 0 is always reserved by the Kernel */
+ for (i = 1U; i < EE_MAX_APP; ++i) {
+ register EE_STATUSHOOKTYPE error_hook =
+ EE_as_Application_errorhook[i];
+
+ if (error_hook != 0U) {
+ /* [SWS_Os_00085] The Operating System module shall execute an
+ * application-specific error hook with the access rights of the
+ * associated OS-Application. */
+ EE_hal_call_app_status_hook(Error, error_hook, i);
+ }
+ }
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+ /* Set back the previous context */
+ EE_as_set_execution_context(prev_context);
+}
+#else /* EE_SERVICE_PROTECTION__ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_ErrorHook(StatusType Error)
+{
+ /* Just Call the error Hook */
+ ErrorHook(Error);
+}
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifndef __OO_ERRORHOOK_NOMACROS__
+/*
+ * Inlines functions to fill parameters of the system service which called
+ * ErrorHook
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_set_error_serviceid(OSServiceIdType
+ ServiceID)
+{
+ (*EE_oo_get_errorhook_service_id()) = ServiceID;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_ActivateTask(TaskType
+ TaskID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_ActivateTask;
+ EE_oo_get_errorhook_data()->param1.value_param = (EE_UREG)TaskID;
+}
+
+#ifndef __OO_NO_CHAINTASK__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_ChainTask(TaskType
+ TaskID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_ChainTask;
+ EE_oo_get_errorhook_data()->param1.value_param = (EE_UREG)TaskID;
+}
+#else /* __OO_NO_CHAINTASK__ */
+#define EE_oo_fill_error_data_ChainTask(TaskID) ((void)0)
+#endif /* __OO_NO_CHAINTASK__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetTaskID(TaskRefType
+ TaskID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetTaskID;
+ EE_oo_get_errorhook_data()->param1.task_ref = TaskID;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetTaskState(TaskType
+ TaskID,
+ TaskStateRefType State)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetTaskState;
+ p_errorhook_parameter->param1.value_param = (EE_UREG)TaskID;
+ p_errorhook_parameter->param2.task_state_ref = State;
+}
+
+#ifndef __OO_NO_RESOURCES__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetResource(
+ ResourceType ResID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetResource;
+ EE_oo_get_errorhook_data()->param1.value_param = ResID;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_ReleaseResource(
+ ResourceType ResID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_ReleaseResource;
+ EE_oo_get_errorhook_data()->param1.value_param = ResID;
+}
+#else /* __OO_NO_RESOURCES__ */
+#define EE_oo_fill_error_data_GetResource(ResID) ((void)0)
+#define EE_oo_fill_error_data_ReleaseResource(ResID) ((void)0)
+#endif /* __OO_NO_RESOURCES__ */
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_SetEvent(TaskType
+ TaskID,
+ EventMaskType Mask)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_SetEvent;
+ p_errorhook_parameter->param1.value_param = (EE_UREG)TaskID;
+ p_errorhook_parameter->param2.value_param = Mask;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_ClearEvent(
+ EventMaskType Mask)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_ClearEvent;
+ EE_oo_get_errorhook_data()->param1.value_param = Mask;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetEvent(TaskType
+ TaskID,
+ EventMaskRefType Event)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetEvent;
+ p_errorhook_parameter->param1.value_param = (EE_UREG)TaskID;
+ p_errorhook_parameter->param2.event_ref = Event;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_WaitEvent(EventMaskType
+ Mask)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_WaitEvent;
+ EE_oo_get_errorhook_data()->param1.value_param = Mask;
+}
+#else /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
+#define EE_oo_fill_error_data_SetEvent(TaskID, Mask) ((void)0)
+#define EE_oo_fill_error_data_ClearEvent(Mask) ((void)0)
+#define EE_oo_fill_error_data_GetEvent(TaskID, Event) ((void)0)
+#define EE_oo_fill_error_data_WaitEvent(Mask) ((void)0)
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
+
+#ifndef __OO_NO_ALARMS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetAlarmBase(AlarmType
+ AlarmID,
+ AlarmBaseRefType Info)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetAlarmBase;
+ p_errorhook_parameter->param1.value_param = AlarmID;
+ p_errorhook_parameter->param2.alarm_base_ref = Info;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetAlarm(AlarmType
+ AlarmID,
+ TickRefType Tick)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetAlarm;
+ p_errorhook_parameter->param1.value_param = AlarmID;
+ p_errorhook_parameter->param2.tick_ref = Tick;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_SetRelAlarm(AlarmType
+ AlarmID,
+ TickType increment,
+ TickType cycle)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_SetRelAlarm;
+ p_errorhook_parameter->param1.value_param = AlarmID;
+ p_errorhook_parameter->param2.value_param = increment;
+ p_errorhook_parameter->param3.value_param = cycle;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_SetAbsAlarm(AlarmType
+ AlarmID,
+ TickType start,
+ TickType cycle)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_SetAbsAlarm;
+ p_errorhook_parameter->param1.value_param = AlarmID;
+ p_errorhook_parameter->param2.value_param = start;
+ p_errorhook_parameter->param3.value_param = cycle;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_CancelAlarm(AlarmType
+ AlarmID)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_CancelAlarm;
+ EE_oo_get_errorhook_data()->param1.value_param = AlarmID;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_IncrementCounter(
+ CounterType CounterID)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_IncrementCounter;
+ p_errorhook_parameter->param1.value_param = CounterID;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetCounterValue(
+ CounterType CounterID,
+ TickRefType Value)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetCounterValue;
+ p_errorhook_parameter->param1.value_param = CounterID;
+ p_errorhook_parameter->param2.tick_ref = Value;
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_GetElapsedValue(
+ CounterType CounterID,
+ TickRefType Value,
+ TickRefType ElapsedValue)
+{
+ register EE_oo_ErrorHook_parameters *const
+ p_errorhook_parameter = EE_oo_get_errorhook_data();
+
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_GetElapsedValue;
+ p_errorhook_parameter->param1.value_param = CounterID;
+ p_errorhook_parameter->param2.tick_ref = Value;
+ p_errorhook_parameter->param3.tick_ref = ElapsedValue;
+}
+
+#else /* __OO_NO_ALARMS__ */
+#define EE_oo_fill_error_data_GetAlarmBase(AlarmID, Info) ((void)0)
+#define EE_oo_fill_error_data_GetAlarm(AlarmID, Tick) ((void)0)
+#define EE_oo_fill_error_data_SetRelAlarm(AlarmID, increment, cycle) \
+ ((void)0)
+#define EE_oo_fill_error_data_SetAbsAlarm(AlarmID, start, cycle) ((void)0)
+#define EE_oo_fill_error_data_CancelAlarm(AlarmID) ((void)0)
+#define EE_oo_fill_error_data_IncrementCounter(CounterID) ((void)0)
+#define EE_oo_fill_error_data_GetCounterValue(CounterID, Value) ((void)0)
+#define EE_oo_fill_error_data_GetElapsedValue(CounterID, Value, ElapsedValue) \
+ ((void)0)
+#endif /* __OO_NO_ALARMS__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_fill_error_data_StartOS(AppModeType
+ Mode)
+{
+ (*EE_oo_get_errorhook_service_id()) = OSServiceId_StartOS;
+ EE_oo_get_errorhook_data()->param1.value_param = Mode;
+}
+
+#else /* __OO_ERRORHOOK_NOMACROS__ */
+#define EE_oo_set_error_serviceid(ServiceID) ((void)0)
+#define EE_oo_fill_error_data_ActivateTask(TaskID) ((void)0)
+#define EE_oo_fill_error_data_ChainTask(TaskID) ((void)0)
+#define EE_oo_fill_error_data_GetTaskID(TaskID) ((void)0)
+#define EE_oo_fill_error_data_GetTaskState(TaskID, State) ((void)0)
+#define EE_oo_fill_error_data_GetResource(ResID) ((void)0)
+#define EE_oo_fill_error_data_ReleaseResource(ResID) ((void)0)
+#define EE_oo_fill_error_data_SetEvent(TaskID, Mask) ((void)0)
+#define EE_oo_fill_error_data_ClearEvent(Mask) ((void)0)
+#define EE_oo_fill_error_data_GetEvent(TaskID, Event) ((void)0)
+#define EE_oo_fill_error_data_WaitEvent(Mask) ((void)0)
+#define EE_oo_fill_error_data_GetAlarmBase(AlarmID, Info) ((void)0)
+#define EE_oo_fill_error_data_GetAlarm(AlarmID, Tick) ((void)0)
+#define EE_oo_fill_error_data_SetRelAlarm(AlarmID, increment, cycle) \
+ ((void)0)
+#define EE_oo_fill_error_data_SetAbsAlarm(AlarmID, start, cycle) ((void)0)
+#define EE_oo_fill_error_data_CancelAlarm(AlarmID) ((void)0)
+#define EE_oo_fill_error_data_IncrementCounter(AlarmID, TaskID, ActionKind) \
+ ((void)0)
+#define EE_oo_fill_error_data_with_mask_IncrementCounter(AlarmID, TaskID, \
+ Mask, ActionKind) ((void)0)
+#define EE_oo_fill_error_data_GetCounterValue(CounterID, Value) ((void)0)
+#define EE_oo_fill_error_data_GetElapsedValue(CounterID, Value, ElapsedValue) \
+ ((void)0)
+#define EE_oo_fill_error_data_StartOS(Mode) ((void)0)
+#define EE_oo_fill_error_data_WaitSem(Sem) ((void)0)
+#define EE_oo_fill_error_data_PostSem(Sem) ((void)0)
+#endif /* __OO_ERRORHOOK_NOMACROS__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_service(OSServiceIdType
+ ServiceID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_set_error_serviceid(ServiceID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_ActivateTask(TaskType
+ TaskID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_ActivateTask(TaskID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#ifndef __OO_NO_CHAINTASK__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_ChainTask(TaskType TaskID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_ChainTask(TaskID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#else /* __OO_NO_CHAINTASK__ */
+#define EE_oo_notify_error_ChainTask(TaskID, Error) ((void)0);
+#endif /* __OO_NO_CHAINTASK__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetTaskID(TaskRefType
+ TaskID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetTaskID(TaskID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetTaskState(TaskType
+ TaskID,
+ TaskStateRefType State,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetTaskState(TaskID, State);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#ifndef __OO_NO_RESOURCES__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetResource(
+ ResourceType ResID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetResource(ResID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_ReleaseResource(
+ ResourceType ResID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_ReleaseResource(ResID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+#else /* __OO_NO_RESOURCES__ */
+#define EE_oo_notify_error_GetResource(ResID, Error) ((void)0)
+#define EE_oo_notify_error_ReleaseResource(ResID, Error) ((void)0)
+#endif /* __OO_NO_RESOURCES__ */
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_SetEvent(TaskType
+ TaskID,
+ EventMaskType Mask,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_SetEvent(TaskID, Mask);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_ClearEvent(EventMaskType
+ Mask,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_ClearEvent(Mask);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetEvent(TaskType TaskID,
+ EventMaskRefType Event,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetEvent(TaskID, Event);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_WaitEvent(EventMaskType
+ Mask,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_WaitEvent(Mask);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+#else /* if defined __OO_ECC1__ or defined __OO_ECC2__ */
+#define EE_oo_notify_error_SetEvent(TaskID, Mask, Error) ((void)0)
+#define EE_oo_notify_error_ClearEvent(Mask, Error) ((void)0)
+#define EE_oo_notify_error_GetEvent(TaskID, Event, Error) ((void)0)
+#define EE_oo_notify_error_WaitEvent(Mask, Error) ((void)0)
+#endif /* if defined __OO_ECC1__ or defined __OO_ECC2__ */
+
+#ifndef __OO_NO_ALARMS__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetAlarmBase(AlarmType
+ AlarmID,
+ AlarmBaseRefType Info,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetAlarmBase(AlarmID, Info);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetAlarm(AlarmType AlarmID,
+ TickRefType Tick,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetAlarm(AlarmID, Tick);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_SetRelAlarm(AlarmType
+ AlarmID,
+ TickType increment,
+ TickType cycle,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_SetRelAlarm(AlarmID, increment, cycle);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_SetAbsAlarm(AlarmType
+ AlarmID,
+ TickType start,
+ TickType cycle,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_SetAbsAlarm(AlarmID, start, cycle);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_CancelAlarm(AlarmType
+ AlarmID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_CancelAlarm(AlarmID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_IncrementCounter(
+ CounterType CounterID,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_IncrementCounter(CounterID);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetCounterValue(
+ CounterType CounterID,
+ TickRefType Value,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetCounterValue(CounterID, Value);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_GetElapsedValue(CounterType
+ CounterID,
+ TickRefType Value,
+ TickRefType ElapsedValue,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_GetElapsedValue(CounterID, Value, ElapsedValue);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#else /* __OO_NO_ALARMS__ */
+#define EE_oo_notify_error_GetAlarmBase(AlarmID, Tick, Error) ((void)0)
+#define EE_oo_notify_error_GetAlarm(AlarmID, Tick, Error) ((void)0)
+#define EE_oo_notify_error_SetRelAlarm(AlarmID, increment, cycle, Error) \
+ ((void)0)
+#define EE_oo_notify_error_SetAbsAlarm(AlarmID, start, cycle, Error) \
+ ((void)0)
+#define EE_oo_notify_error_CancelAlarm(AlarmID, Error) ((void)0)
+#define EE_oo_notify_error_IncrementCounter(CounterID, Error) ((void)0)
+#define EE_oo_notify_error_GetCounterValue(CounterID, Value, Error) ((void)0)
+#define EE_oo_notify_error_GetElapsedValue(CounterID, Value, ElapsedValue, \
+ Error) ((void)0)
+#endif /* __OO_NO_ALARMS__ */
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_notify_error_StartOS(AppModeType
+ Mode,
+ StatusType Error)
+{
+ if (EE_ErrorHook_nested_flag == 0U) {
+ EE_oo_fill_error_data_StartOS(Mode);
+ EE_ErrorHook_nested_flag = 1U;
+ EE_oo_call_ErrorHook(Error);
+ EE_ErrorHook_nested_flag = 0U;
+ }
+}
+
+#else /* __OO_HAS_ERRORHOOK__ */
+#define EE_oo_notify_error_service(ServiceID, Error) ((void)0)
+#define EE_oo_notify_error_ActivateTask(TaskID, Error) ((void)0)
+#define EE_oo_notify_error_ChainTask(TaskID, Error) ((void)0)
+#define EE_oo_notify_error_TerminateTask ((void)0)
+#define EE_oo_notify_error_GetTaskID(TaskID, Error) ((void)0)
+#define EE_oo_notify_error_GetTaskState(TaskID, State, Error) ((void)0)
+#define EE_oo_notify_error_GetResource(ResID, Error) ((void)0)
+#define EE_oo_notify_error_ReleaseResource(ResID, Error) ((void)0)
+#define EE_oo_notify_error_SetEvent(TaskID, Mask, Error) ((void)0)
+#define EE_oo_notify_error_ClearEvent(Mask, Error) ((void)0)
+#define EE_oo_notify_error_GetEvent(TaskID, Event, Error) ((void)0)
+#define EE_oo_notify_error_WaitEvent(Mask, Error) ((void)0)
+#define EE_oo_notify_error_GetAlarmBase(AlarmID, Tick, Error) ((void)0)
+#define EE_oo_notify_error_GetAlarm(AlarmID, Tick, Error) ((void)0)
+#define EE_oo_notify_error_SetRelAlarm(AlarmID, increment, cycle, Error) \
+ ((void)0)
+#define EE_oo_notify_error_SetAbsAlarm(AlarmID, start, cycle, Error) \
+ ((void)0)
+#define EE_oo_notify_error_CancelAlarm(AlarmID, Error) ((void)0)
+#define EE_oo_notify_error_IncrementCounter(CounterID, Error) ((void)0)
+#define EE_oo_notify_error_GetCounterValue(CounterID, Value, Error) \
+ ((void)0)
+#define EE_oo_notify_error_GetElapsedValue(CounterID, Value, ElapsedValue, \
+ Error) ((void)0)
+#define EE_oo_notify_error_StartOS(Mode, Error) ((void)0)
+#define EE_oo_notify_error_WaitSem(Sem, Error) ((void)0)
+#define EE_oo_notify_error_PostSem(Sem, Error) ((void)0)
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+/* XXX: Here because have to be seen in eecfg.c to generate syscall array */
+#if (defined(__EE_MEMORY_PROTECTION__)) && (defined(__OO_HAS_ERRORHOOK__))
+void EE_oo_notify_error_from_us_internal(OSServiceIdType ServiceID,
+ const EE_oo_ErrorHook_parameters *const error_parameters_ref,
+ StatusType Error);
+#endif /* __INCLUDE_OO_INTFUNC_H__ && __OO_HAS_ERRORHOOK__*/
+
+#endif /* __INCLUDE_OO_INTFUNC_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_irq.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_irq.h
new file mode 100644
index 0000000..24c926f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_irq.h
@@ -0,0 +1,100 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2012 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/**
+ * @author Errico Guidieri
+ * @date 2012
+ **/
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_IRQ_H
+#define PKG_KERNEL_OO_INC_EE_OO_IRQ_H
+
+/**************************************************************************
+* This header contains kernel API that have to be called by IRQ handlers
+**************************************************************************/
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allow IRQ nesting the C_end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the
+ * stack
+ * - if there are other interrupts on the stack the IRQ end_instance should
+ * do nothing
+ */
+void EE_IRQ_end_instance(void);
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ post-stub.
+ * This primitive done needed clean-up as restting kernel interrupt nested
+ * counters and release got resources if application forget to do that as
+ * specified by Autosar standard.
+ */
+void EE_IRQ_end_post_stub(void);
+#endif /* __PRIVATE_IRQ_END_INSTANCE__ */
+
+/*
+ * ORTI ISR2 Support
+ */
+#ifdef __OO_ORTI_RUNNINGISR2__
+
+/* This variable stores 0 if no ISR is running, or the address of the ISR stub
+ * generated for the particular ISR handler
+ * Initvalue: 0 */
+extern volatile EE_ORTI_runningisr2_type EE_ORTI_runningisr2;
+
+__INLINE__ EE_ORTI_runningisr2_type EE_ORTI_get_runningisr2(void)
+{
+ return EE_ORTI_runningisr2;
+}
+
+__INLINE__ void EE_ORTI_set_runningisr2(EE_ORTI_runningisr2_type i2number)
+{
+ EE_ORTI_runningisr2 = i2number;
+ EE_ORTI_send_otm_runningisr2(i2number);
+}
+
+#else /* if __OO_ORTI_RUNNINGISR2__ */
+
+#define EE_ORTI_get_runningisr2() (NULL)
+#define EE_ORTI_set_runningisr2(isr2) ((void)0)
+
+#endif /* else __OO_ORTI_RUNNINGISR2__ */
+
+#endif /* INCLUDE_OO_IRQ_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_kernel.h b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_kernel.h
new file mode 100644
index 0000000..94a234c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/inc/ee_oo_kernel.h
@@ -0,0 +1,805 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_kernel.h,v 1.9 2006/12/03 22:07:50 pj Exp $
+ */
+
+
+#ifndef PKG_KERNEL_OO_INC_EE_OO_KERNEL_H
+#define PKG_KERNEL_OO_INC_EE_OO_KERNEL_H
+
+/* Symbols that can be defined into EEOPT
+ * __OO_EXTENDED_STATUS__
+ * __PRIVATE_XXXX__
+ * __OO_BCC1__
+ * __OO_BCC2__
+ * __OO_ECC1__
+ * __OO_ECC2__
+ * __OO_NO_CHAINTASK__ if the application do not use chaintask
+ * __OO_NO_RESOURCES__ if the application do not use resources
+ * __OO_NO_ALARMS__ if the application do not use alarms
+ *
+ *
+ * __OO_ORTI_LASTERROR__ if the application should record the last
+ * error for ORTI use
+ *
+ * __OO_ORTI_SERVICETRACE__ if the application should record the
+ * ORTI servicetrace attribute
+ *
+ * __OO_ORTI_PRIORITY__ if the application should record the current
+ * priority for each task. Note that that
+ * information is used only for debugging, the
+ * kernel schedules using just the system
+ * ceiling.
+ *
+ * __OO_ORTI_RUNNINGISR2__ if the application should generate some ISR
+ * stubs capable to register the ISRs that are
+ * currently running.
+ *
+ * __OO_ORTI_ALARMTIME__ if defined, it stores informations about the
+ * expiration time of an alarm
+ *
+ * __OO_ORTI_RES_ISLOCKED__ if defined, the resource functions keep trace
+ * of the fact that a resource is locked or not
+ *
+ * __OO_ORTI_RES_LOCKER_TASK__ if defined, the resource functions keep
+ * trace of the locker task.
+ *
+ * __OO_ORTI_STACK__ This define is not included in the OO
+ * sources, but instead it is contained in the BSP
+ * boot code, and specifies if stack
+ * initialization should be performed for all the
+ * stacks in the system.
+ *
+ * - The extension of resource usage into ISR2 is optional and it is
+ * not implemented.
+ *
+ * __OO_HAS_STARTUPHOOK__ & co.
+ *
+ * __OO_ERRORHOOK_NOMACROS__ disables macro support inside ErrorHooK
+ * (end of 11.2)
+ *
+ * __OO_AUTOSTART_TASK__ if defined, StartOS() will processthe OIL
+ * Task AUTOSTART informations.
+ *
+ * __OO_AUTOSTART_ALARM__ if defined, StartOS() will processthe OIL
+ * Alarm AUTOSTART informations.
+ *
+ * OO_CPU_HAS_STARTOS_ROUTINE This is defined internally by the CPU
+ */
+
+
+/*************************************************************************
+* Common part
+*************************************************************************/
+
+/*
+ * - Constants
+ * - Types
+ * - Data structures used at configuration time
+ */
+
+#include "kernel/oo/inc/ee_oo_common.h"
+
+/***************************************************************************
+* 13.1 Common data types
+***************************************************************************/
+
+/* See ee_common.h */
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/* 13.2.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* See ee_common.h */
+
+/* 13.2.2 Constructional elements */
+/* ----------------------------------------------------------------------- */
+
+/* 13.2.2.1: BCC1, BCC2, ECC1, ECC2 */
+#define DeclareTask(t) void Func##t(void)
+
+/* 13.2.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.2.3.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_ACTIVATETASK__
+StatusType EE_oo_ActivateTask(TaskType TaskID);
+#endif
+
+/* 13.2.3.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_TERMINATETASK__
+StatusType EE_oo_TerminateTask(void);
+#endif
+
+/* 13.2.3.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_CHAINTASK__
+StatusType EE_oo_ChainTask(TaskType TaskID);
+#endif
+
+/* 13.2.3.4: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SCHEDULE__
+StatusType EE_oo_Schedule(void);
+#endif
+
+/* Needed for counters (see later) */
+#ifndef __PRIVATE_FORCESCHEDULE__
+StatusType EE_oo_ForceSchedule(void);
+#endif
+
+/* 13.2.3.5: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETTASKID__
+StatusType EE_oo_GetTaskID(TaskRefType TaskID);
+#endif /* __PRIVATE_GETTASKID__ */
+
+/* 13.2.3.6: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETTASKSTATE__
+StatusType EE_oo_GetTaskState(TaskType TaskID,
+ TaskStateRefType State);
+#endif
+
+/* 13.2.4 Constants */
+/* ----------------------------------------------------------------------- */
+
+/* task states in common.h */
+
+/* Constant of data type TaskType for a not defined task. */
+/* This definition has the same behavior of the NIL constant, that is -1 */
+#define INVALID_TASK EE_NIL
+
+
+/* 13.2.5 Naming Conventions */
+/* ----------------------------------------------------------------------- */
+
+/* Why Note 14 page 54 says that a Task must have a StatusType ret. value? */
+#define TASK(t) void Func##t(void)
+
+
+/***************************************************************************
+* 13.3 Interrupt handling
+***************************************************************************/
+
+/* 13.3.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* none */
+
+/* 13.3.2 System services */
+/* ----------------------------------------------------------------------- */
+
+/* (see ee_inline.h) */
+
+/* 13.3.3 Naming convention */
+/* ----------------------------------------------------------------------- */
+
+/* to implement the RUNNINGISR2 parameter, the only identifier I can
+ * use is the name of the ISR itself. For that reason, I use that
+ * identifier as unique ISR2 identifier.
+ *
+ * Please note that the ISR macro should be implemented by the CPU or
+ * the MCU layer, because it depends a lot on the particular
+ * microcontroller. For this reason, the following is reported as a
+ * comment.
+ *
+ * Please note that EE_ORTI_get_runningisr2() and EE_ORTI_set_runningisr2() do
+ * not produce any code when the macro __OO_ORTI_RUNNINGISR2__ is not defined,
+ * so the example below could be written with no "#ifdef".
+ */
+
+#if 0 /* This is just an example! */
+#ifdef __OO_ORTI_RUNNINGISR2__
+#define ISR(t) static void t##_ORTI(void); \
+ void t(void) \
+ { \
+ EE_ORTI_runningisr2_type ortiold \
+ ortiold = EE_ORTI_get_runningisr2(); \
+ EE_ORTI_set_runningisr2(t); \
+ t##_ORTI(); \
+ EE_ORTI_set_runningisr2(ortiold); \
+ } \
+ static void t##_ORTI(void)
+
+#else
+#define ISR(t) void t(void)
+#endif
+#endif /* #if 0 */
+
+/***************************************************************************
+* 13.4 Resource management
+***************************************************************************/
+
+#ifndef __OO_NO_RESOURCES__
+
+/* 13.4.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+/* 13.4.2 Constructional elements */
+/* ----------------------------------------------------------------------- */
+
+/* 13.4.2.1: BCC1, BCC2, ECC1, ECC2 */
+/* this is a void declaration ;-) */
+#define DeclareResource(ResourceIdentifier) extern EE_TID EE_th_next[] /* void! */
+
+
+/* 13.4.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* NB: The extension of resource usage into ISR2 is optional and it is
+ * not implemented.
+ */
+
+/* 13.4.3.1: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETRESOURCE__
+StatusType EE_oo_GetResource(ResourceType ResID);
+#endif
+
+/* 13.4.3.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_RELEASERESOURCE__
+StatusType EE_oo_ReleaseResource(ResourceType ResID);
+#endif
+
+/* 13.4.4 Constants RES_SCHEDULER */
+/* ----------------------------------------------------------------------- */
+
+/* 13.4.4 Constants */
+
+/* note: TYPEPRIO must be unsigned!!! */
+
+/* RES_SCHEDULER is defined only if USE_RESSCHEDULER is defined inside
+ * the OIL file. In general its value is variable and depends on the
+ * code that is automatically generated */
+
+#if 0 /* Disabled! */
+#define RES_SCHEDULER 0
+#endif
+
+#endif /* !__OO_NO_RESOURCES__ */
+
+/***************************************************************************
+* 13.5 Event control
+***************************************************************************/
+
+/* 13.5.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+/* 13.5.2 Constructional elements */
+/* ----------------------------------------------------------------------- */
+
+/* 13.5.2.1: ECC1, ECC2 */
+/* this is a void definition ;-) */
+#define DeclareEvent(EventIdentifier) extern EE_TID EE_th_next[]/* void! */
+
+/* 13.5.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* see also internal.h */
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+
+/* 13.5.3.1: ECC1, ECC2 */
+#ifndef __PRIVATE_SETEVENT__
+StatusType EE_oo_SetEvent(TaskType TaskID,
+ EventMaskType Mask);
+#endif
+
+/* 13.5.3.2: ECC1, ECC2 */
+#ifndef __PRIVATE_CLEAREVENT__
+StatusType EE_oo_ClearEvent(EventMaskType Mask);
+#endif
+
+/* 13.5.3.3: ECC1, ECC2 */
+#ifndef __PRIVATE_GETEVENT__
+StatusType EE_oo_GetEvent(TaskType TaskID,
+ EventMaskRefType Event);
+#endif
+
+/* 13.5.3.4: ECC1, ECC2 */
+#ifndef __PRIVATE_WAITEVENT__
+StatusType EE_oo_WaitEvent(EventMaskType Mask);
+#endif
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+/***************************************************************************
+* Semaphores
+***************************************************************************/
+#ifdef __OO_SEM__
+
+/* These functions are an extension of the OSEK/VDX API */
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#define STATICSEM(value) { (value), EE_NIL, EE_NIL }
+#else
+#define STATICSEM(value) { (value) }
+#endif
+
+/* Semaphore Initialization: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_INITSEM__
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_InitSem(SemRefType Sem,
+ int value)
+{
+ EE_ORTI_set_service_in(EE_SERVICETRACE_INITSEM);
+
+ if (Sem != NULL) {
+ (Sem)->count = (EE_UREG)(value);
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ (Sem)->first = EE_NIL;
+ (Sem)->last = EE_NIL;
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_INITSEM);
+}
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+/* Semaphore Blocking Wait: ECC1, ECC2 */
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#ifndef __PRIVATE_WAITSEM__
+StatusType EE_oo_WaitSem(SemRefType Sem);
+#endif
+#endif
+
+/* Semaphore Non-Blocking Wait: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_TRYWAITSEM__
+int EE_oo_TryWaitSem(SemRefType Sem);
+#endif
+
+/* Semaphore Post: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_POSTSEM__
+StatusType EE_oo_PostSem(SemRefType Sem);
+#endif
+
+/* Semaphore value read: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETVALUESEM__
+int EE_oo_GetValueSem(const SemType *Sem);
+#endif
+
+#endif /* __OO_SEM__ */
+
+/***************************************************************************
+* AS 4.0 Counters
+***************************************************************************/
+#if (defined(EE_MAX_COUNTER)) && (EE_MAX_COUNTER > 0U)
+/*
+ * AS 4.0 OS SWS 8.4.16
+ * AS OS requirement OS399:
+ *
+ * This function notifies a tick to a counter. That is, the counter is
+ * incremented by 1.
+ *
+ * The function will also implement the notification of expired alarms
+ * (calling an alarm callback, setting an event, or activating a
+ * task).
+ *
+ * And DO RESCHEDULING.
+ * see also internal.h
+ */
+#ifndef __PRIVATE_INCREMENTCOUNTER__
+StatusType EE_oo_IncrementCounter(CounterType CounterID);
+#endif /* !__PRIVATE_INCREMENTCOUNTER__ && EE_MAX_COUNTER > 0 */
+
+/*
+ * AS 4.0 OS SWS 8.4.17 GetCounterValue
+ * AS OS requirement OS383:
+ */
+#ifndef __PRIVATE_GETCOUNTERVALUE__
+StatusType EE_oo_GetCounterValue(CounterType CounterID,
+ TickRefType Value);
+#endif
+
+/*
+ * AS 4.0 OS SWS 8.4.18 GetElapsedValue
+ * AS OS requirement OS392:
+ */
+#ifndef __PRIVATE_GETELAPSEDVALUE__
+StatusType EE_oo_GetElapsedValue(CounterType CounterID,
+ TickRefType Value,
+ TickRefType ElapsedValue);
+#endif
+#endif /* EE_MAX_COUNTER > 0 */
+
+/***************************************************************************
+* 13.6 Alarms
+***************************************************************************/
+#ifndef __OO_NO_ALARMS__
+
+/* Implementation defined functions */
+
+/* Counter initialization
+ * ----------------------
+ *
+ * Counter initialization is done at initialization time OUTSIDE
+ * StartOS. Since software counters are stored in RAM, their
+ * initialization values are typically set to 0. That also conforms to
+ * note 10 page 43 of the specification version 2.2.1 that says:
+ *
+ * "Counters are - if possible - set to zero by the system
+ * initialization before alarms are autostarted. Exception: calendar
+ * timers, etc. For autostarted alarms, all values are relative
+ * values.
+ *
+ */
+
+/* 13.6.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+
+/* 13.6.2 Constructional elements */
+/* ----------------------------------------------------------------------- */
+
+/* 13.6.2.1: BCC1, BCC2, ECC1, ECC2 */
+/* this is a void definition ;-) */
+#define DeclareAlarm(AlarmIdentifier) extern EE_TID EE_th_next[]/* void! */
+
+/* 13.6.3 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.6.3.1 BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETALARMBASE__
+StatusType EE_oo_GetAlarmBase(AlarmType AlarmID,
+ AlarmBaseRefType Info);
+#endif
+
+/* 13.6.3.2 BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETALARM_
+StatusType EE_oo_GetAlarm(AlarmType AlarmID,
+ TickRefType Tick);
+#endif
+
+/* 13.6.3.3 BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2 */
+#ifndef __PRIVATE_SETRELALARM__
+StatusType EE_oo_SetRelAlarm(AlarmType AlarmID,
+ TickType increment,
+ TickType cycle);
+#endif
+
+/* 13.6.3.4 BCC1, BCC2, ECC1, ECC2; Events only ECC1, ECC2 */
+#ifndef __PRIVATE_SETABSALARM__
+StatusType EE_oo_SetAbsAlarm(AlarmType AlarmID,
+ TickType start,
+ TickType cycle);
+#endif
+
+/* 13.6.3.5 BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_CANCELALARM__
+StatusType EE_oo_CancelAlarm(AlarmType AlarmID);
+#endif
+
+/* 13.6.4 Constants */
+/* ----------------------------------------------------------------------- */
+
+
+/* NOTE: these #defines have to be defined by the user or by the HAL!!!
+ * x is the counter */
+
+/* Maximum possible allowed value of counter x in ticks. */
+/* define OSMAXALLOWEDVALUE_x */
+
+/* Number of ticks required to reach a specific unit of counter x. */
+/* define OSTICKSPERBASE_x */
+/* Minimum allowed number of ticks for a cyclic alarm of counter x. */
+/* define OSMINCYCLE_x */
+/* Maximum possible allowed value of the system counter in ticks. */
+/* define OSMAXALLOWEDVALUE */
+/* Number of ticks required to reach a specific unit of the system counter. */
+/* define OSTICKSPERBASE */
+/* Minimum allowed number of ticks for a cyclic alarm of the system counter. */
+/* define OSMINCYCLE */
+
+/* Duration of a tick of the system counter in nanoseconds. */
+/* define OSTICKDURATION */
+
+/* 13.6.5 Naming convention */
+/* ----------------------------------------------------------------------- */
+
+#define ALARMCALLBACK(t) void t(void)
+
+#endif /* __OO_NO_ALARMS__ */
+
+/***************************************************************************
+* 13.7 Operating system execution control
+***************************************************************************/
+
+/* 13.7.1 Data types */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+/* 13.7.2 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.7.2.1: BCC1, BCC2, ECC1, ECC2 */
+/* see ee_inline.h */
+
+/* 13.7.2.2: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_STARTOS__
+StatusType EE_oo_StartOS(AppModeType Mode);
+#endif
+
+/* 13.7.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_SHUTDOWNOS__
+void EE_oo_ShutdownOS(StatusType Error);
+#endif
+
+/* 13.7.3 Constants */
+/* ----------------------------------------------------------------------- */
+
+/* Default application mode, always a valid parameter to StartOS.
+ * Note: because of this parameter, the constant EE_MAX_APPMODE should
+ * be always >1 */
+#define OSDEFAULTAPPMODE 0U
+
+/***************************************************************************
+* 13.8 Hook routines
+***************************************************************************/
+
+/* 13.8.1 Data Types */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+/* 13.8.2 System services */
+/* ----------------------------------------------------------------------- */
+
+/* 13.8.2.1: BCC1, BCC2, ECC1, ECC2 */
+#ifdef __OO_HAS_ERRORHOOK__
+void ErrorHook(StatusType Error);
+#endif
+
+/* 13.8.2.2: BCC1, BCC2, ECC1, ECC2 */
+#ifdef __OO_HAS_PRETASKHOOK__
+void PreTaskHook(void);
+#endif
+
+/* 13.8.2.3: BCC1, BCC2, ECC1, ECC2 */
+#ifdef __OO_HAS_POSTTASKHOOK__
+void PostTaskHook(void);
+#endif
+
+/* 13.8.2.4: BCC1, BCC2, ECC1, ECC2 */
+#ifdef __OO_HAS_STARTUPHOOK__
+void StartupHook(void);
+#endif
+
+/* 13.8.2.5: BCC1, BCC2, ECC1, ECC2 */
+#ifdef __OO_HAS_SHUTDOWNHOOK__
+void ShutdownHook(StatusType Error);
+#endif
+
+/* 13.8.3 Constants */
+/* ----------------------------------------------------------------------- */
+
+/* see ee_common.h */
+
+/* 13.8.4 Macros */
+/* ----------------------------------------------------------------------- */
+
+#ifdef __OO_HAS_ERRORHOOK__
+#ifndef __OO_ERRORHOOK_NOMACROS__
+
+
+/* see ee_common.h */
+
+/* provides the service identifier where the error has been risen. */
+__INLINE__ OSServiceIdType __ALWAYS_INLINE__ OSErrorGetServiceId(void)
+{
+ return *EE_oo_get_errorhook_service_id();
+}
+
+/* names of macros to access (within ErrorHook) parameters of the
+ * system service which called ErrorHook */
+__INLINE__ TaskType __ALWAYS_INLINE__ OSError_ActivateTask_TaskID(void)
+{
+ return (TaskType)(EE_oo_get_errorhook_data()->param1.value_param);
+}
+
+#ifndef __OO_NO_CHAINTASK__
+__INLINE__ TaskType __ALWAYS_INLINE__ OSError_ChainTask_TaskID(void)
+{
+ return (TaskType)(EE_oo_get_errorhook_data()->param1.value_param);
+}
+#endif /* __OO_NO_CHAINTASK__ */
+
+__INLINE__ TaskRefType __ALWAYS_INLINE__ OSError_GetTaskID_TaskID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.task_ref;
+}
+
+__INLINE__ TaskType __ALWAYS_INLINE__ OSError_GetTaskState_TaskID(void)
+{
+ return (TaskType)(EE_oo_get_errorhook_data()->param1.value_param);
+}
+__INLINE__ TaskStateRefType __ALWAYS_INLINE__ OSError_GetTaskState_State(void)
+{
+ return EE_oo_get_errorhook_data()->param2.task_state_ref;
+}
+
+#ifndef __OO_NO_RESOURCES__
+__INLINE__ ResourceType __ALWAYS_INLINE__ OSError_GetResource_ResID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ ResourceType __ALWAYS_INLINE__ OSError_ReleaseResource_ResID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+#endif /* __OO_NO_RESOURCES__ */
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+__INLINE__ TaskType __ALWAYS_INLINE__ OSError_SetEvent_TaskID(void)
+{
+ return (TaskType)(EE_oo_get_errorhook_data()->param1.value_param);
+}
+__INLINE__ EventMaskType __ALWAYS_INLINE__ OSError_SetEvent_Mask(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+
+__INLINE__ EventMaskType __ALWAYS_INLINE__ OSError_ClearEvent_Mask(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TaskType __ALWAYS_INLINE__ OSError_GetEvent_TaskID(void)
+{
+ return (TaskType)(EE_oo_get_errorhook_data()->param1.value_param);
+}
+__INLINE__ EventMaskRefType __ALWAYS_INLINE__ OSError_GetEvent_Event(void)
+{
+ return EE_oo_get_errorhook_data()->param2.event_ref;
+}
+
+__INLINE__ EventMaskType __ALWAYS_INLINE__ OSError_WaitEvent_Mask(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+#ifndef __OO_NO_ALARMS__
+__INLINE__ AlarmType __ALWAYS_INLINE__ OSError_GetAlarmBase_AlarmID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+__INLINE__ AlarmBaseRefType __ALWAYS_INLINE__ OSError_GetAlarmBase_Info(void)
+{
+ return EE_oo_get_errorhook_data()->param2.alarm_base_ref;
+}
+
+__INLINE__ AlarmType __ALWAYS_INLINE__ OSError_GetAlarm_AlarmID(void)
+{
+ return (AlarmType)EE_oo_get_errorhook_data()->param1.value_param;
+}
+__INLINE__ TickRefType __ALWAYS_INLINE__ OSError_GetAlarm_Tick(void)
+{
+ return EE_oo_get_errorhook_data()->param2.tick_ref;
+}
+
+__INLINE__ AlarmType __ALWAYS_INLINE__ OSError_SetRelAlarm_AlarmID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+__INLINE__ TickType __ALWAYS_INLINE__ OSError_SetRelAlarm_increment(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+__INLINE__ TickType __ALWAYS_INLINE__ OSError_SetRelAlarm_cycle(void)
+{
+ return EE_oo_get_errorhook_data()->param3.value_param;
+}
+
+__INLINE__ AlarmType __ALWAYS_INLINE__ OSError_SetAbsAlarm_AlarmID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+__INLINE__ TickType __ALWAYS_INLINE__ OSError_SetAbsAlarm_start(void)
+{
+ return EE_oo_get_errorhook_data()->param2.value_param;
+}
+__INLINE__ TickType __ALWAYS_INLINE__ OSError_SetAbsAlarm_cycle(void)
+{
+ return EE_oo_get_errorhook_data()->param3.value_param;
+}
+
+__INLINE__ AlarmType __ALWAYS_INLINE__ OSError_CancelAlarm_AlarmID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ CounterObjectType __ALWAYS_INLINE__
+OSError_IncrementCounter_CounterID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ CounterType __ALWAYS_INLINE__ OSError_GetCounterValue_CounterID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TickRefType __ALWAYS_INLINE__ OSError_GetCounterValue_Value(void)
+{
+ return EE_oo_get_errorhook_data()->param2.tick_ref;
+}
+
+__INLINE__ CounterType __ALWAYS_INLINE__ OSError_GetElapsedValue_CounterID(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+__INLINE__ TickRefType __ALWAYS_INLINE__ OSError_GetElapsedValue_Value(void)
+{
+ return EE_oo_get_errorhook_data()->param2.tick_ref;
+}
+
+__INLINE__ TickRefType __ALWAYS_INLINE__
+OSError_GetElapsedValue_ElapsedValue(void)
+{
+ return EE_oo_get_errorhook_data()->param3.tick_ref;
+}
+
+#endif /* !__OO_NO_ALARMS__ */
+
+__INLINE__ AppModeType __ALWAYS_INLINE__ OSError_StartOS_Mode(void)
+{
+ return EE_oo_get_errorhook_data()->param1.value_param;
+}
+
+#endif /* __OO_ERRORHOOK_NOMACROS__ */
+#endif /* __OO_HAS_ERRORHOOK__ */
+
+/***************************************************************************
+* Inline inclusions
+***************************************************************************/
+/* Error handling data structures and functions plus other stuff that have to
+ * be moved */
+#include "kernel/oo/inc/ee_oo_intfunc.h"
+/* include "kernel/oo/inc/ee_oo_inline.h" XXX: Moved inside
+ * {ee.h,ee_internal.h} because Disable/Suspend/Resume API depends upon TP
+ * (Timing Protection) declarations. */
+#endif /* __INCLUDE_OO_KERNEL_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/makefile b/src/bsp/hsm/os/erika2/pkg/kernel/oo/makefile
new file mode 100644
index 0000000..ae9d1d4
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/makefile
@@ -0,0 +1,101 @@
+LOCAL_PATH := $(call cur-dir)
+
+ifeq ($(OS_ERIKA2), true)
+
+LOCAL_MODULE := os_erika_kernel_oo
+
+EE_SRCS :=
+
+ifeq ($(call iseeopt, __OO_BCC1__), yes)
+OO=YES
+endif
+ifeq ($(call iseeopt, __OO_BCC2__), yes)
+OO=YES
+OO2=YES
+endif
+ifeq ($(call iseeopt, __OO_ECC1__), yes)
+OO=YES
+ifeq ($(call iseeopt, __MULTI__), yes)
+OO_ECC=YES
+endif
+endif
+ifeq ($(call iseeopt, __OO_ECC2__), yes)
+OO=YES
+OO2=YES
+ifeq ($(call iseeopt, __MULTI__), yes)
+OO_ECC=YES
+endif
+endif
+
+ifeq ($(OO), YES)
+EE_SRCS += ./src/ee_activate.c
+EE_SRCS += ./src/ee_schedule.c
+EE_SRCS += ./src/ee_force_schedule.c
+EE_SRCS += ./src/ee_gettaskstate.c
+EE_SRCS += ./src/ee_gettaskid.c
+EE_SRCS += ./src/ee_terminat.c
+EE_SRCS += ./src/ee_thendin.c
+EE_SRCS += ./src/ee_irqendin.c
+EE_SRCS += ./src/ee_iparam.c
+EE_SRCS += ./src/ee_tstub.c
+EE_SRCS += ./src/ee_tnterm.c
+EE_SRCS += ./src/ee_lookup.c
+EE_SRCS += ./src/ee_rq_exchg.c
+EE_SRCS += ./src/ee_rq_inser.c
+EE_SRCS += ./src/ee_shtdown.c
+EE_SRCS += ./src/ee_startos.c
+
+ifeq ($(OO2), YES)
+EE_SRCS += ./src/ee_rq_first.c
+endif
+
+ifneq ($(call iseeopt, __OO_NO_CHAINTASK__), yes)
+EE_SRCS += ./src/ee_chaintas.c
+endif
+
+ifneq ($(call iseeopt, __OO_NO_RESOURCES__), yes)
+EE_SRCS += ./src/ee_lockres.c
+EE_SRCS += ./src/ee_ulockres.c
+EE_SRCS += ./src/ee_ulockallres.c
+endif
+
+
+ifneq ($(call iseeopt, __OO_NO_ALARMS__), yes)
+EE_SRCS += ./src/ee_alcancel.c
+EE_SRCS += ./src/ee_algetbase.c
+EE_SRCS += ./src/ee_alget.c
+EE_SRCS += ./src/ee_alsetabs.c
+EE_SRCS += ./src/ee_alsetrel.c
+endif
+
+ifeq ($(or $(if $(call iseeopt, __OO_NO_ALARMS__),,yes), $(call iseeopt, EE_AS_SCHEDULETABLES__)), yes)
+EE_SRCS += ./src/ee_altick.c
+EE_SRCS += ./src/ee_getcountervalue.c
+EE_SRCS += ./src/ee_getelapsedvalue.c
+endif # !__OO_NO_ALARMS__ || EE_AS_SCHEDULETABLES__
+
+ifeq ($(OO_ECC) , YES)
+EE_SRCS += ./src/ee_evclear.c
+EE_SRCS += ./src/ee_evget.c
+EE_SRCS += ./src/ee_evset.c
+EE_SRCS += ./src/ee_evwait.c
+endif
+
+ifeq ($(call iseeopt, __OO_SEM__), yes)
+EE_SRCS += ./src/ee_sempost.c
+EE_SRCS += ./src/ee_semtrywait.c
+EE_SRCS += ./src/ee_semgetvalue.c
+
+ifeq ($(OO_ECC) , YES)
+EE_SRCS += ./src/ee_semwait.c
+endif
+endif
+
+EE_INCS := ./inc
+endif
+
+ALL_SRCS += $(foreach SRC, $(EE_SRCS:./%=%), $(addprefix $(LOCAL_PATH)/, $(SRC)))
+ALL_INCDIRS += $(foreach INC, $(EE_INCS), $(addprefix $(LOCAL_PATH)/, $(INC)))
+
+endif
+
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_activate.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_activate.c
new file mode 100644
index 0000000..990668d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_activate.c
@@ -0,0 +1,166 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_activate.c,v 1.5 2006/01/05 14:37:22 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* ActivateTask:
+ * - The task is moved from the suspended state to the ready state
+ * - called from interrupts, from tasks, from StartupHook
+ * - returns E_OS_LIMIT if too many activations are issued
+ * E_OK otherwise
+ * E_OS_ID if the taskID is invalid (Extended status)
+ * - clears the events of a task (extended task)
+ *
+ * NOTE: part of this source code is copied into altick.c!
+ */
+
+#ifndef __PRIVATE_ACTIVATETASK__
+StatusType EE_oo_ActivateTask(TaskType TaskID)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_ACTIVATETASK);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* ActivateTask is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__RN_TASK__)) || (defined(EE_AS_RPC__))
+ if (EE_IS_TID_REMOTE(TaskID)) {
+#ifdef EE_AS_RPC__
+ /* Tmp Tid (introduced to meet MISRA requirements) */
+ EE_TID tmp_tid;
+
+ EE_os_param unmarked_tid;
+ /* Two steps macro assignment to meet MISRA 10.3 required rule */
+ tmp_tid = EE_UNMARK_REMOTE_TID(TaskID);
+ unmarked_tid.value_param = (EE_UREG)tmp_tid;
+ /* Forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_ActivateTask, unmarked_tid,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM);
+#else /* EE_AS_RPC__ */
+ EE_TYPERN_PARAM par;
+ par.pending = 1U;
+ /* Forward the request to another CPU in asynchronous way */
+ (void)EE_rn_send(EE_UNMARK_REMOTE_TID(TaskID), EE_RN_TASK, par);
+ ev = E_OK;
+#endif /* EE_AS_RPC__ */
+ } else {
+#endif /* __RN_TASK__ || EE_AS_RPC__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* Check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_TASK_ACCESS_ERR(TaskID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* Check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ /* Check for pending activations */
+ if (EE_th_rnact[TaskID] == 0U) {
+ ev = E_OS_LIMIT;
+ } else {
+ /* [SWS_Os_00469]: The Operating System module shall start an
+ * OsTaskTimeFrame when a task is activated successfully.
+ * (SRS_Os_11008) */
+ /* [SWS_Os_00466]: If an attempt is made to activate a task before the
+ * end of an OsTaskTimeFrame then the Operating System module shall not
+ * perform the activation AND shall call the ProtectionHook()
+ * with E_OS_PROTECTION_ARRIVAL. */
+ /* Check Interarrival Frame */
+ if (EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(TaskID))) {
+ /* Put the TASK in ready queue */
+ EE_oo_task_in_ready_queue(TaskID);
+
+ /* Check for preemption:
+ * this test has to be done only if we are inside a task */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ /* we are inside a task */
+ EE_oo_preemption_point();
+ }
+ }
+ ev = E_OK;
+ }
+#if (defined(__RN_TASK__)) || (defined(EE_AS_RPC__))
+}
+#endif /* __RN_TASK__ || EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_ActivateTask(TaskID, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_ACTIVATETASK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* !__PRIVATE_ACTIVATETASK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alcancel.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alcancel.c
new file mode 100644
index 0000000..e971cf4
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alcancel.c
@@ -0,0 +1,138 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alcancel.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* CancelAlarm
+ * - This function cancels the AlarmID
+ * - it returns E_OK if all OK
+ * E_OS_NOFUNC if the Alarm is not used
+ * E_OS_ID if the alarm is invalid (only Extended status)
+ */
+
+#ifndef __PRIVATE_CANCELALARM__
+StatusType EE_oo_CancelAlarm(AlarmType AlarmID)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CANCELALARM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* CancelAlarm is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(AlarmID)) {
+ EE_os_param unmarked_alarm_id;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(AlarmID);
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_CancelAlarm, unmarked_alarm_id,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local alarm are not defined cut everything else */
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else if (EE_ALARM_ACCESS_ERR(AlarmID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ if (EE_oo_counter_object_RAM[AlarmID].used == EE_FALSE) {
+ ev = E_OS_NOFUNC;
+ } else {
+ /* Actually cancel the alarm */
+ EE_oo_handle_counter_object_cancellation(AlarmID);
+ ev = E_OK;
+ }
+#else /* EE_MAX_ALARM > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_ALARM > 0U */
+
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_CancelAlarm(AlarmID, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CANCELALARM);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* __PRIVATE_CANCELALARM__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alget.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alget.c
new file mode 100644
index 0000000..468cced
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alget.c
@@ -0,0 +1,176 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alget.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* GetAlarm
+ * - This function returns the relative value in ticks before the alarm
+ * expires
+ * - it returns E_OK if all OK
+ * E_OS_NOFUNC if the Alarm is not used
+ * E_OS_ID if the alarm is invalid (only Extended status)
+ */
+
+#ifndef __PRIVATE_GETALARM__
+StatusType EE_oo_GetAlarm(AlarmType AlarmID,
+ TickRefType Tick)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETALARM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetAlarm is callable by Task, ISR2, ErrorHook Pre and Post TaskHook */
+ if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != PreTaskHook_Context) &&
+ (EE_as_execution_context != PostTaskHook_Context)) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL. +
+ * MISRA dictate NULL check for pointers always. */
+ if (Tick == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Tick, sizeof(*Tick)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(AlarmID)) {
+ EE_os_param as_tick;
+ EE_os_param unmarked_alarm_id;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(AlarmID);
+ as_tick.tick_ref = Tick;
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_GetAlarm, unmarked_alarm_id,
+ as_tick, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local alarm are not defined cut everything else */
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else if (EE_ALARM_ACCESS_ERR(AlarmID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ if (EE_oo_counter_object_RAM[AlarmID].used == EE_FALSE) {
+ ev = E_OS_NOFUNC;
+ } else {
+ register CounterObjectType current;
+ /* to compute the relative value in ticks, we have to follow the counter
+ * delay chain */
+ current = EE_counter_RAM[EE_oo_counter_object_ROM[AlarmID].c].first;
+
+ /* Added 1 because alarm list is a "zero as next tick" list
+ * (so zero count one) */
+ *Tick = EE_oo_counter_object_RAM[current].delta + 1U;
+
+ while ((current != AlarmID) && (current < EE_COUNTER_OBJECTS_ROM_SIZE)) {
+ current = EE_oo_counter_object_RAM[current].next;
+ *Tick += EE_oo_counter_object_RAM[current].delta;
+ }
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_ALARM > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_ALARM > 0U */
+
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_GetAlarm(AlarmID, Tick, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETALARM);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* !__PRIVATE_GETALARM__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_algetbase.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_algetbase.c
new file mode 100644
index 0000000..d4bd749
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_algetbase.c
@@ -0,0 +1,167 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_algetbase.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* GetAlarmBase
+ * - This function returns the base characteristics of a counter
+ * - in Extended Status it returns E_OK or E_OS_ID if the alarm_id is invalid
+ */
+
+#ifndef __PRIVATE_GETALARMBASE__
+StatusType EE_oo_GetAlarmBase(AlarmType AlarmID,
+ AlarmBaseRefType Info)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETALARMBASE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetAlarmBase is callable by Task, ISR2, ErrorHook Pre and Post TaskHook */
+ if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != PreTaskHook_Context) &&
+ (EE_as_execution_context != PostTaskHook_Context)) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL. +
+ * MISRA dictate NULL check for pointers always. */
+ if (Info == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Info, sizeof(*Info)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(AlarmID)) {
+ EE_os_param os_info;
+ EE_os_param unmarked_alarm_id;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(AlarmID);
+ os_info.alarm_base_ref = Info;
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_GetAlarmBase, unmarked_alarm_id, os_info,
+ EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local alarm are not defined cut everything else */
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else if (EE_ALARM_ACCESS_ERR(AlarmID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ {
+ /* Fill the informations required */
+ register EE_oo_counter_ROM_type const *c_ref =
+ &EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c];
+
+ Info->maxallowedvalue = c_ref->maxallowedvalue;
+ Info->ticksperbase = c_ref->ticksperbase;
+#ifdef __OO_EXTENDED_STATUS__
+ Info->mincycle = c_ref->mincycle;
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_ALARM > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_ALARM > 0U */
+
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_GetAlarmBase(AlarmID, Info, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETALARMBASE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* !__PRIVATE_GETALARMBASE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetabs.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetabs.c
new file mode 100644
index 0000000..96cbc1f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetabs.c
@@ -0,0 +1,154 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alsetabs.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* SetAbsAlarm
+ * - This function occupies the AlarmID setting an alarm when the counter
+ * will reach the absolute value passed as parameter.
+ * - the Alarm must not be already in use
+ *
+ * returns the relative value in ticks before the alarm expires
+ * - it returns E_OK if all OK
+ * E_OS_STATE if the Alarm is already used
+ * E_OS_ID if the alarm is invalid (only Extended status)
+ * E_OS_VALUE if the parameters are incorrect
+ */
+
+#ifndef __PRIVATE_SETABSALARM__
+StatusType EE_oo_SetAbsAlarm(AlarmType AlarmID,
+ TickType start,
+ TickType cycle)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SETABSALARM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * invalid value of the service. (BSW11009, BSW11013) */
+ /* SetAbsAlarm is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(AlarmID)) {
+ EE_os_param unmarked_alarm_id, as_start, as_cycle;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(AlarmID);
+ as_start.value_param = start;
+ as_cycle.value_param = cycle;
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_SetAbsAlarm, unmarked_alarm_id,
+ as_start, as_cycle);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local alarm are not defined cut everything else */
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else if (EE_ALARM_ACCESS_ERR(AlarmID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ if ((start > EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].
+ maxallowedvalue) || ((cycle != 0U) &&
+ ((cycle < EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].mincycle) ||
+ (cycle > EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].
+ maxallowedvalue)))) {
+ ev = E_OS_VALUE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ if (EE_oo_counter_object_RAM[AlarmID].used) {
+ ev = E_OS_STATE;
+ } else {
+ EE_oo_handle_abs_counter_object_insertion(AlarmID, start, cycle);
+ ev = E_OK;
+ }
+#else /* EE_MAX_ALARM > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_ALARM > 0U */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_SetAbsAlarm(AlarmID, start, cycle, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SETABSALARM);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* !__PRIVATE_SETABSALARM__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetrel.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetrel.c
new file mode 100644
index 0000000..dd15f87
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_alsetrel.c
@@ -0,0 +1,158 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_alsetrel.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* SetRelAlarm
+ * - This function occupies the AlarmID setting an alarm after increment ticks.
+ * - if increment=0, E_OS_VALUE is returned.
+ * - the Alarm must not be already in use
+ *
+ * returns the relative value in ticks before the alarm expires
+ * - it returns E_OK if all OK
+ * E_OS_STATE if the Alarm is already used
+ * E_OS_ID if the alarm is invalid (only Extended status)
+ * E_OS_VALUE if the parameters are incorrect
+ */
+
+#ifndef __PRIVATE_SETRELALARM__
+StatusType EE_oo_SetRelAlarm(AlarmType AlarmID,
+ TickType increment,
+ TickType cycle)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SETRELALARM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * “invalid value” of the service. (BSW11009, BSW11013) */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(AlarmID)) {
+ EE_os_param unmarked_alarm_id, as_increment, as_cycle;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(AlarmID);
+ as_increment.value_param = increment;
+ as_cycle.value_param = cycle;
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_SetRelAlarm, unmarked_alarm_id, as_increment,
+ as_cycle);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If local alarm are not defined cut everything else */
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else if (EE_ALARM_ACCESS_ERR(AlarmID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ if (AlarmID >= EE_MAX_ALARM) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ if ((increment > EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].
+ maxallowedvalue) || ((cycle != 0U) &&
+ ((cycle < EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].mincycle) ||
+ (cycle > EE_counter_ROM[EE_oo_counter_object_ROM[AlarmID].c].
+ maxallowedvalue)))) {
+ ev = E_OS_VALUE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ /* OS304: */
+ if (increment == 0U) {
+ ev = E_OS_VALUE;
+ } else if (EE_oo_counter_object_RAM[AlarmID].used) {
+ ev = E_OS_STATE;
+ } else {
+ EE_oo_handle_rel_counter_object_insertion(AlarmID, increment, cycle);
+ ev = E_OK;
+ }
+#else /* EE_MAX_ALARM > 0U */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_ALARM > 0U */
+
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_SetRelAlarm(AlarmID, increment, cycle, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SETRELALARM);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* !__PRIVATE_SETRELALARM__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_altick.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_altick.c
new file mode 100644
index 0000000..581647c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_altick.c
@@ -0,0 +1,745 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_altick.c,v 1.5 2006/06/08 20:40:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* If local alarm or schedule tables are not defined: cut everything */
+#if ((defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)) \
+ || ((defined(EE_MAX_SCHEDULETABLE)) && (EE_MAX_SCHEDULETABLE > 0U))
+#define EE_KEEP_ALARM_QUEUE_CODE
+#endif /* (EE_MAX_ALARM > 0) || (EE_MAX_SCHEDULETABLE > 0U) */
+
+#if (defined(RTDRUID_CONFIGURATOR_NUMBER)) \
+ && (RTDRUID_CONFIGURATOR_NUMBER >= RTDRUID_CONFNUM_NO_ORTI_VARS)
+
+/* ORTI variables */
+#if (defined(__OO_ORTI_ALARMTIME__)) && (defined(EE_KEEP_ALARM_QUEUE_CODE))
+static EE_TYPETICK EE_ORTI_alarmtime[EE_MAX_ALARM
+#ifdef EE_AS_SCHEDULETABLES__
+ + EE_MAX_SCHEDULETABLE
+#endif /* EE_AS_SCHEDULETABLES__ */
+];
+#endif /* __OO_ORTI_ALARMTIME__ && EE_KEEP_ALARM_QUEUE_CODE */
+
+#endif /* RTDRUID_CONFIGURATOR_NUMBER */
+
+#ifdef EE_AS_SCHEDULETABLES__
+#if (defined(EE_MAX_SCHEDULETABLE)) && (EE_MAX_SCHEDULETABLE > 0)
+#define EE_KEEP_ALARM_QUEUE_CODE
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+#ifdef EE_KEEP_ALARM_QUEUE_CODE
+/* Increment equal to 0 means next tick. Has been used this convention to
+ * utilize all values from zero to counter.maxallowedvalue range */
+void EE_oo_counter_object_insert(CounterObjectType ObjectID,
+ TickType increment)
+{
+ register CounterObjectType current, previous;
+ register CounterType ctr = EE_oo_counter_object_ROM[ObjectID].c;
+
+#ifdef __OO_ORTI_ALARMTIME__
+ EE_ORTI_alarmtime[ObjectID] = increment + 1U + EE_counter_RAM[ctr].value;
+#endif /* __OO_ORTI_ALARMTIME__ */
+
+ current = EE_counter_RAM[ctr].first;
+
+ if (current == INVALID_COUNTER_OBJECT) {
+ /* The alarm becomes the first into the delta queue, because the queue was
+ * empty */
+ EE_counter_RAM[ctr].first = ObjectID;
+ } else if (EE_oo_counter_object_RAM[current].delta > increment) {
+ /* The alarm becomes the first into the delta queue, because increment is
+ * less than previous delta */
+ EE_counter_RAM[ctr].first = ObjectID;
+ EE_oo_counter_object_RAM[current].delta -= increment;
+ } else {
+ /* The alarm is not the first into the delta queue */
+
+ /* Follow the delta chain until I reach the right place */
+ do {
+ increment -= EE_oo_counter_object_RAM[current].delta;
+ previous = current;
+ current = EE_oo_counter_object_RAM[current].next;
+ } while ((current != INVALID_COUNTER_OBJECT) &&
+ (EE_oo_counter_object_RAM[current].delta <= increment));
+
+ /* Insert the alarm between previous and current */
+ if (current != INVALID_COUNTER_OBJECT) {
+ EE_oo_counter_object_RAM[current].delta -= increment;
+ }
+ EE_oo_counter_object_RAM[previous].next = ObjectID;
+ }
+
+ EE_oo_counter_object_RAM[ObjectID].delta = increment;
+ EE_oo_counter_object_RAM[ObjectID].next = current;
+}
+#endif /* EE_KEEP_ALARM_QUEUE_CODE */
+
+/* If counters are not defined cut everything */
+#if (defined(EE_MAX_COUNTER)) && (EE_MAX_COUNTER > 0U)
+
+static void EE_oo_handle_action_task(EE_oo_action_ROM_type const *const p_action);
+
+static void EE_oo_handle_action_task(EE_oo_action_ROM_type const *const
+ p_action)
+{
+ /* Error Value */
+ register StatusType ev;
+ /* Activate the task; NOTE: no pre-emption at all...
+ * This code was directly copied from ActivateTask */
+ register TaskType TaskID = 0;
+
+ if (p_action != NULL) {
+ TaskID = p_action->action_task;
+ }
+
+#ifdef EE_AS_RPC__
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ EE_os_param unmarked_tid;
+ unmarked_tid.value_param = (EE_UREG)EE_UNMARK_REMOTE_TID(TaskID);
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_ActivateTask, unmarked_tid,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM);
+ } else {
+#elif defined(__RN_TASK__)
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ register EE_TYPERN_PARAM par;
+ par.pending = 1U;
+ /* forward the request to another CPU whether the thread do
+ * not become to the current CPU */
+ (void)EE_rn_send(EE_UNMARK_REMOTE_TID(TaskID), EE_RN_TASK, par);
+ ev = E_OK;
+ } else {
+#endif /* EE_AS_RPC__ || __RN_TASK__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ /* XXX: This means a configuration Error it should never happens! */
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ /* check for pending activations */
+ if (EE_th_rnact[TaskID] == 0U) {
+ ev = E_OS_LIMIT;
+ } else {
+ /* [SWS_Os_00469]: The Operating System module shall start an
+ * OsTaskTimeFrame when a task is activated successfully.
+ * (SRS_Os_11008) */
+ /* [SWS_Os_00466]: If an attempt is made to activate a task before the
+ * end of an OsTaskTimeFrame then the Operating System module shall not
+ * perform the activation AND shall call the ProtectionHook()
+ * with E_OS_PROTECTION_ARRIVAL. */
+ /* Check Interarrival Frame */
+ if (EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(TaskID))) {
+ /* insert the task in the ready queue */
+ EE_oo_task_in_ready_queue(TaskID);
+ }
+ ev = E_OK;
+ }
+#if (defined(EE_AS_RPC__)) || (defined(__RN_TASK__))
+ }
+#endif /* EE_AS_RPC__ || __RN_TASK__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_task_id);
+ EE_OS_PARAM(os_action_type);
+ EE_OS_PARAM_VALUE(os_task_id, (EE_UREG)TaskID);
+ EE_OS_PARAM_VALUE(os_action_type, (EE_UREG)EE_ACTION_TASK);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSId_Action, os_task_id, EE_OS_INVALID_PARAM,
+ os_action_type, ev);
+ }
+ }
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+ static void EE_oo_handle_action_event(EE_oo_action_ROM_type const *const p_action);
+
+ static void EE_oo_handle_action_event(EE_oo_action_ROM_type const *const
+ p_action)
+ {
+ /* Error Value */
+ register StatusType ev;
+ /* Set an event for a task... NOTE: no pre-emption at all...
+ * This code was directly copied from SetEvent */
+ register TaskType TaskID = 0;
+ register EventMaskType Mask = 0U;
+
+ if (p_action != NULL) {
+ TaskID = p_action->action_task;
+ Mask = p_action->action_mask;
+ }
+
+#ifdef EE_AS_RPC__
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ EE_os_param unmarked_tid, as_mask;
+
+ unmarked_tid.value_param = EE_UNMARK_REMOTE_TID(TaskID);
+ as_mask.value_param = Mask;
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_SetEvent, unmarked_tid,
+ as_mask, EE_OS_INVALID_PARAM);
+ } else {
+#elif defined(__RN_EVENT__)
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ register EE_TYPERN_PARAM par;
+ par.ev = Mask;
+ /* forward the request to another CPU whether the thread do
+ * not become to the current CPU */
+ (void)EE_rn_send((EE_SREG)EE_UNMARK_REMOTE_TID(TaskID), EE_RN_EVENT, par);
+ ev = E_OK;
+ } else {
+#endif /* EE_AS_RPC__ || __RN_EVENT__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_th_is_extended[TaskID] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+ /* XXX: These means a configuration Error: it should never happens! */
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ if (EE_th_status[TaskID] == SUSPENDED) {
+ ev = E_OS_STATE;
+ } else {
+ /* [SWS_Os_00472] The Operating System module shall start an
+ * OsTaskTimeFrame when a task is released successfully.
+ * (SRS_Os_11008) */
+ /* [SWS_Os_00467] If an attempt is made to release a task before the end
+ * of an OsTaskTimeFrame then the Operating System module shall not
+ * perform the release AND shall call the ProtectionHook() with
+ * E_OS_PROTECTION_ARRIVAL AND the EVENT SHALL BE SET. */
+ /* Set the event mask only if the task is not suspended */
+ EE_th_event_active[TaskID] |= Mask;
+ /* Check Interarrival Frame */
+ if (EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(TaskID))) {
+ /* Check if the task was waiting for an event we just set
+ *
+ * WARNING:
+ * the test with status==WAITING is FUNDAMENTAL to avoid double
+ * insertion of the task in the ready queue!!! Example, when I call
+ * two times the same setevent... the first time the task must go in
+ * the ready queue, the second time NOT!!!
+ */
+ if (((EE_th_event_waitmask[TaskID] & Mask) != 0U) &&
+ (EE_th_status[TaskID] == WAITING)) {
+ /* if yes, the task must go back into the READY state */
+ EE_th_status[TaskID] = READY;
+ /* insert the task in the ready queue */
+ EE_rq_insert(TaskID);
+ }
+ }
+
+ ev = E_OK;
+ }
+#if (defined(EE_AS_RPC__)) || (defined(__RN_TASK__))
+ }
+#endif /* EE_AS_RPC__ || __RN_TASK__ */
+
+ if (ev != E_OK) {
+#ifdef __OO_HAS_ERRORHOOK__
+ EE_OS_PARAM(os_task_id);
+ EE_OS_PARAM(os_mask);
+ EE_OS_PARAM(os_action_type);
+ EE_OS_PARAM_VALUE(os_task_id, (EE_UREG)TaskID);
+ EE_OS_PARAM_VALUE(os_mask, Mask);
+ EE_OS_PARAM_VALUE(os_action_type, (EE_UREG)EE_ACTION_EVENT);
+#endif /* __OO_HAS_ERRORHOOK__ */
+ EE_os_notify_error(OSId_Action, os_task_id, os_mask,
+ os_action_type, ev);
+ }
+ }
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+ static void EE_oo_handle_action_callback(const EE_oo_action_ROM_type *
+ const p_action);
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ static void EE_oo_handle_action_callback(const EE_oo_action_ROM_type *
+ const p_action)
+ {
+ /* Handle Alarm callback execution context */
+ EE_TYPECONTEXT prev_context = EE_as_execution_context;
+
+ EE_as_execution_context = AlarmCallback_Context;
+ (p_action->f)();
+ EE_as_execution_context = prev_context;
+ }
+#else /* EE_AS_OSAPPLICATIONS__ && EE_SERVICE_PROTECTION__ */
+ static void EE_oo_handle_action_callback(const EE_oo_action_ROM_type *
+ const p_action)
+ {
+ if (p_action != NULL) {
+ (p_action->f)();
+ }
+ }
+#endif /* EE_AS_OSAPPLICATIONS__ && EE_SERVICE_PROTECTION__ */
+
+ static void EE_oo_handle_action(EE_oo_action_ROM_type const *const p_action);
+
+ static void EE_oo_handle_action(EE_oo_action_ROM_type const *const p_action)
+ {
+ if (p_action != NULL) {
+ switch (p_action->action_kind) {
+ case EE_ACTION_TASK:
+ /* activate the task */
+ EE_oo_handle_action_task(p_action);
+ break;
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+ case EE_ACTION_EVENT:
+ /* set an event for a task */
+ EE_oo_handle_action_event(p_action);
+ break;
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
+
+ case EE_ACTION_CALLBACK:
+ EE_oo_handle_action_callback(p_action);
+ break;
+
+ case EE_ACTION_COUNTER:
+ /*
+ * This "case" statement is not fully supported.
+ * It has been temporary commented to prevent from MISRA
+ * error dealing with recursive functions. If
+ * it will be fully supported and recursive call is
+ * unavoidable, thus consider a MISRA deviation.
+ */
+ /* Recursive Call
+ * TODO: HANDLE CYCLIC COUNTERS !!! */
+#if 0
+ EE_oo_IncrementCounterImplementation(p_action->inccount);
+#endif
+ break;
+
+ default:
+ /* Invalid action: this should never happen, as `action' is
+ * initialized by RT-Druid */
+ break;
+ }
+ }
+ }
+
+#ifdef EE_AS_SCHEDULETABLES__
+#if (defined(EE_MAX_SCHEDULETABLE)) && (EE_MAX_SCHEDULETABLE > 0)
+ static void EE_as_handle_schedule_table(ScheduleTableType STId)
+ {
+ do {
+ /* Index to traverse expiry point actions */
+ register EE_UREG i;
+ register TickType nextOffset;
+ /* Expiry point description */
+ register EE_as_Expiry_Point_ROM_type const *p_expiry_point;
+ /* Get Schedule Table Configuration Structures */
+ register EE_as_Schedule_Table_ROM_type const *p_schedule_table_ROM =
+ &EE_as_Schedule_Table_ROM[STId];
+ register EE_as_Schedule_Table_RAM_type *p_schedule_table_RAM =
+ &EE_as_Schedule_Table_RAM[STId];
+ /* Expiry point position */
+ register ExpiryPointType expiry_position = p_schedule_table_RAM->position;
+
+ /* This can happen:
+ * - When a next schedule table is activated to stop the original
+ * schedule table after the final delay
+ * - When the original schedule table is repeating */
+ if (expiry_position == INVALID_SCHEDULETABLE_POSITION) {
+ /* Get the next Schedule Table */
+ ScheduleTableType const nextSTId = p_schedule_table_RAM->next_table;
+
+ if (nextSTId != INVALID_SCHEDULETABLE) {
+ p_schedule_table_RAM->status = SCHEDULETABLE_STOPPED;
+ /* This is needed to stop the underlying alarm tied to the schedule
+ * table, otherwise the alarm handling cycle will be reschedule
+ * this alarm */
+ EE_oo_counter_object_RAM[EE_MAX_ALARM + STId].cntcycle = 0;
+ p_schedule_table_RAM->next_table = INVALID_SCHEDULETABLE;
+
+ /* nextSTId handling */
+ p_schedule_table_ROM = &EE_as_Schedule_Table_ROM[nextSTId];
+ p_schedule_table_RAM = &EE_as_Schedule_Table_RAM[nextSTId];
+
+ p_schedule_table_RAM->status = SCHEDULETABLE_RUNNING;
+
+ expiry_position = p_schedule_table_ROM->expiry_point_first;
+
+ p_schedule_table_RAM->position = expiry_position;
+ p_schedule_table_RAM->next_table = INVALID_SCHEDULETABLE;
+
+ nextOffset = EE_as_Expiry_Point_ROM[expiry_position].offset;
+
+ /* Handle special case of some expiry points with offset equal to
+ * zero */
+ if (nextOffset > 0U) {
+ /* Exit From The Loop */
+ STId = INVALID_SCHEDULETABLE;
+ } else {
+ /* Continue The Loop with the next Schedule Table expiry points:
+ * before them, evaluate next alarm event offset to enable
+ * underlying schedule table alarm (counter object). */
+ do {
+ ++expiry_position;
+ nextOffset = EE_as_Expiry_Point_ROM[expiry_position].offset;
+ } while ((nextOffset == 0U) &&
+ (expiry_position < p_schedule_table_ROM->expiry_point_last));
+ if (nextOffset == 0U) {
+ nextOffset = p_schedule_table_ROM->duration;
+ }
+ STId = nextSTId;
+ }
+ /* Schedule the alarm tied to the next Schedule Table */
+ EE_oo_handle_rel_counter_object_insertion(EE_MAX_ALARM + nextSTId,
+ nextOffset, 0U);
+ } else {
+ /* Reapiting schedule table */
+ expiry_position = p_schedule_table_ROM->expiry_point_first;
+ p_schedule_table_RAM->position = expiry_position;
+ nextOffset = EE_as_Expiry_Point_ROM[expiry_position].offset;
+
+ if (nextOffset > 0U) {
+ /* This is an Hack to let alarm handling cycle reschedule the schedule
+ * table alarm with the right offset (increment) */
+ EE_oo_counter_object_RAM[EE_MAX_ALARM + STId].cntcycle = nextOffset;
+ /* Exit From The Loop */
+ STId = INVALID_SCHEDULETABLE;
+ }
+ }
+ } else {
+ /* Get the Expiry point */
+ p_expiry_point = &EE_as_Expiry_Point_ROM[expiry_position];
+ for (i = p_expiry_point->actions_first;
+ i <= p_expiry_point->actions_last; ++i) {
+ /* Execute the action */
+ EE_oo_handle_action(&EE_oo_action_ROM[i]);
+ }
+
+ /* Handle next expiry point insertion in alarm queue */
+ /* if it is the last expiry point and if this is not a repeating
+ * schedule table, handle next schedule table or stop it */
+ if (expiry_position == p_schedule_table_ROM->expiry_point_last) {
+ /* We reached the end of schedule table so we stop it */
+ if ((p_schedule_table_RAM->next_table == INVALID_SCHEDULETABLE) &&
+ (p_schedule_table_ROM->repeated == 0)) {
+ /* [SWS_Os_00009] If the schedule table is single-shot, the Operating
+ * System module shall stop the processing of the schedule table
+ * Final Delay ticks after the Final Expiry Point is processed. */
+ p_schedule_table_RAM->status = SCHEDULETABLE_STOPPED;
+ /* This is needed to stop the underlying alarm tied to the schedule
+ * table, otherwise the alarm handling cycle will be reschedule this
+ * alarm */
+ EE_oo_counter_object_RAM[EE_MAX_ALARM + STId].cntcycle = 0;
+ /* Exit From The Loop */
+ STId = INVALID_SCHEDULETABLE;
+ } else {
+ /* Schedule the final delay for original schedule table */
+ p_schedule_table_RAM->position = INVALID_SCHEDULETABLE_POSITION;
+ /* [OS427] If the schedule table is single-shot, the Operating System
+ * module shall allow a Final Delay between
+ * 0 .. OsCounterMaxAllowedValue of the underlying counter. */
+ /* This is an Hack to let alarm handling cycle reschedule the schedule
+ * table alarm with the right offset (increment) */
+ /* XXX: The final delay it's any value between
+ * 0 .. OsCounterMaxAllowedValue. This means that I could have a
+ * EE_oo_counter_object_RAM.cycle variable wrap around if I would
+ * sum an Initial Expiry Point Initial Offset directly here,
+ * instead I will handle this case as I have done for the
+ * 'next table' */
+ if (p_schedule_table_ROM->duration > p_expiry_point->offset) {
+ EE_oo_counter_object_RAM[EE_MAX_ALARM + STId].cntcycle =
+ p_schedule_table_ROM->duration - p_expiry_point->offset;
+ /* Exit From The Loop */
+ STId = INVALID_SCHEDULETABLE;
+ }
+ }
+ } else {
+ if (p_schedule_table_ROM->sync_strategy != EE_SCHEDTABLE_SYNC_NONE) {
+ /* *** TODO: HANDLE SYNCRONIZATION *** */
+ }
+ /* Schedule the next expiry point */
+ ++expiry_position;
+ p_schedule_table_RAM->position = expiry_position;
+ nextOffset = EE_as_Expiry_Point_ROM[expiry_position].offset;
+ if (nextOffset > p_expiry_point->offset) {
+ /* This is an Hack to let alarm handling cycle reschedule the schedule
+ * table alarm with the right offset (increment) */
+ EE_oo_counter_object_RAM[EE_MAX_ALARM + STId].cntcycle =
+ nextOffset - p_expiry_point->offset;
+ /* Exit From The Loop */
+ STId = INVALID_SCHEDULETABLE;
+ }
+ }
+ }
+ } while (STId != INVALID_SCHEDULETABLE);
+ }
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+#endif /* EE_AS_SCHEDULETABLES__ */
+
+ void EE_oo_IncrementCounterImplementation(CounterType CounterID)
+ {
+ /* to_fire: Is the head of the splitted queue that have to be served at this
+ * counter tick. */
+ register CounterObjectType to_fire = EE_counter_RAM[CounterID].first;
+
+ /* Increment the counter value or reset it when overcome maxallowedvalue.
+ * I need this behaviour for AS services GetCounterValue and GetElapsedValue
+ */
+ EE_counter_RAM[CounterID].value += 1U;
+ if (EE_counter_RAM[CounterID].value >
+ EE_counter_ROM[CounterID].maxallowedvalue) {
+ EE_counter_RAM[CounterID].value = 0U;
+ }
+
+ /* I split Alarm queue in two: The queue that SHALL be handled at this tick
+ * and the remainder.
+ * current & previous are double indexes used to split the alarm queue.
+ */
+ /* If the alarm queue is empty I have to do nothing */
+ if (to_fire != INVALID_COUNTER_OBJECT) {
+ /* If the head of alarm queue has not delta equal to zero I have only
+ * to decrement the first alarm delta */
+ if (EE_oo_counter_object_RAM[to_fire].delta == 0U) {
+ /* current point to the first alarm at the beginning */
+ register CounterObjectType current = to_fire;
+ /* previous: Is a temporary copy of the index used as utility */
+ register CounterObjectType previous;
+
+ do {
+ /* Now I will use previous to hold the previous checked alarm */
+ previous = current;
+ current = EE_oo_counter_object_RAM[current].next;
+ } while ((current != INVALID_COUNTER_OBJECT) &&
+ (EE_oo_counter_object_RAM[current].delta == 0U));
+
+ /* I set the end of handled queue */
+ EE_oo_counter_object_RAM[previous].next = INVALID_COUNTER_OBJECT;
+
+ /* I set the head of the alarm queue to the current value (maybe -1) */
+ EE_counter_RAM[CounterID].first = current;
+
+ /* If not empty I decrement the first alarm delta in queue */
+ if (current != INVALID_COUNTER_OBJECT) {
+ --EE_oo_counter_object_RAM[current].delta;
+ }
+
+ /* Handle the alarm queue active at this tick */
+ do {
+ /* Select which handler call */
+ switch (EE_oo_counter_object_ROM[to_fire].kind) {
+#if (defined(EE_MAX_ALARM)) && (EE_MAX_ALARM > 0U)
+ case EE_ALARM:
+ EE_oo_handle_action(&EE_oo_action_ROM[EE_alarm_ROM[
+ EE_oo_counter_object_ROM[to_fire].spec_id].action_id]);
+ break;
+#endif /* EE_MAX_ALARM > 0 */
+#ifdef EE_AS_SCHEDULETABLES__
+#if (defined(EE_MAX_SCHEDULETABLE)) && (EE_MAX_SCHEDULETABLE > 0)
+ case EE_SCHEDULETABLE:
+ EE_as_handle_schedule_table(EE_oo_counter_object_ROM[to_fire].
+ spec_id);
+ break;
+#endif /* EE_MAX_SCHEDULETABLE > 0 */
+#endif /* EE_AS_SCHEDULETABLES__ */
+ default:
+ /* Invalid counter object kind: this should never happen, as
+ * `counter object` is initialized by RT-Druid */
+ break;
+ }
+
+ /* Save the actual alarm in previous and get the next to be executed */
+ previous = to_fire;
+ to_fire = EE_oo_counter_object_RAM[to_fire].next;
+
+ /* The previous alarm is cyclic? */
+ if (EE_oo_counter_object_RAM[previous].cntcycle > 0U) {
+ /* Enqueue it again */
+ EE_oo_counter_object_insert(previous,
+ (EE_oo_counter_object_RAM[previous].cntcycle - 1U));
+ } else {
+ /* Counter Object no more used! */
+ EE_oo_counter_object_RAM[previous].used = EE_FALSE;
+ }
+ } while (to_fire != INVALID_COUNTER_OBJECT);
+ } else {
+ /* I do not handle any alarm but I have to decrement the first delta */
+ --EE_oo_counter_object_RAM[to_fire].delta;
+ }
+ }
+ }
+
+ /* Flag from wich index software counters starts */
+#ifdef EE_MAX_COUNTER_HW
+#define EE_SOFT_COUNTERS_START EE_MAX_COUNTER_HW
+#else
+#define EE_SOFT_COUNTERS_START 0
+#endif /* EE_MAX_COUNTER_HW */
+
+ /* Internal primitive */
+ StatusType EE_oo_IncrementCounterHardware(CounterType CounterID)
+ {
+ /* Error Value */
+ register StatusType ev;
+ /* Start Critical Section */
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* This function can be call only inside the Kernel */
+ if (EE_as_execution_context != Kernel_Context) {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#if (EE_SOFT_COUNTERS_START > 0)
+ if (CounterID >= (CounterType)EE_SOFT_COUNTERS_START) {
+ ev = E_OS_ID;
+ } else
+#endif /* (EE_SOFT_COUNTERS_START > 0) */
+ {
+ EE_oo_IncrementCounterImplementation(CounterID);
+ ev = E_OK;
+ }
+ /* This if statement is not always necessary */
+#if (defined(EE_SERVICE_PROTECTION__)) || (EE_SOFT_COUNTERS_START > 0)
+ if (ev != E_OK) {
+#endif
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_service(OSId_Kernel, ev);
+ /* XXX: This is in any case a Kernel Bug it should never happens */
+#if (defined(EE_SERVICE_PROTECTION__)) || (EE_SOFT_COUNTERS_START > 0)
+ }
+#endif
+
+ EE_hal_end_nested_primitive(flag);
+ return ev;
+ }
+
+#ifndef __PRIVATE_INCREMENTCOUNTER__
+ /* [OS399]: IncrementCounter */
+ StatusType EE_oo_IncrementCounter(CounterType CounterID)
+ {
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_INCREMENTCOUNTER);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* IncrementCounter is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if ((defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))) \
+ || (defined(__OO_EXTENDED_STATUS__))
+#ifdef EE_AS_RPC__
+ /* [OS589]: All functions that are not allowed to operate cross core shall
+ * return E_OS_CORE in extended status if called with parameters that
+ * require a cross core operation. (BSW4080013) */
+ if (EE_AS_ID_REMOTE(CounterID)) {
+ ev = E_OS_CORE;
+ } else
+#endif /* EE_AS_RPC__ */
+ /* [OS285]: If the input parameter CounterID in a call of IncrementCounter()
+ * is not valid OR the counter is a hardware counter, IncrementCounter()
+ * shall return E_OS_ID. */
+ if (
+#if (EE_SOFT_COUNTERS_START > 0)
+ (CounterID < (CounterType)EE_SOFT_COUNTERS_START) ||
+#endif /* (EE_SOFT_COUNTERS_START > 0) */
+ (CounterID >= EE_MAX_COUNTER)) {
+ ev = E_OS_ID;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (EE_COUNTER_ACCESS_ERR(CounterID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ */
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ {
+ /* Call to function that actually increment the counter */
+ EE_oo_IncrementCounterImplementation(CounterID);
+
+ /* After all counter updates check if I'm not in a ISR2 and then
+ * execute rescheduling. */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ EE_oo_preemption_point();
+ }
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_IncrementCounter(CounterID, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_INCREMENTCOUNTER);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+ }
+#endif /* __PRIVATE_INCREMENTCOUNTER__ */
+
+#endif /* EE_MAX_COUNTER > 0 */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_chaintas.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_chaintas.c
new file mode 100644
index 0000000..f93df20
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_chaintas.c
@@ -0,0 +1,215 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_chaintas.c,v 1.3 2005/07/19 14:01:16 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* ChainTask:
+ * - activate a task
+ * - The task is moved from the running state to the suspended state
+ * and the other is activated (it can be the same task)
+ * - automatic release of internal resource
+ * - Rescheduling is issued
+ * - returns
+ * E_OS_LIMIT if too many activations
+ * Extended status
+ * E_OS_ID if the task id is invalid
+ * E_OS_RESOURCE if the task still occupy resources
+ * E_OS_CALLLEVEL if called at interrupt level
+ */
+
+#ifndef __OO_NO_CHAINTASK__
+#ifndef __PRIVATE_CHAINTASK__
+StatusType EE_oo_ChainTask(TaskType TaskID)
+{
+ register TaskType current;
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CHAINTASK);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* ChainTask can be callable only by Task */
+ /* Check for a call at interrupt level: This must be the FIRST check! */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U) || (current == EE_NIL)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_SERVICE_PROTECTION__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+#ifndef __OO_NO_RESOURCES__
+ /* check for busy resources */
+ if (EE_th_resource_last[current] != EE_UREG_MINUS1) {
+ ev = E_OS_RESOURCE;
+ } else
+#endif /* !__OO_NO_RESOURCES__ */
+
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* [OS612] In extended status TerminateTask / ChainTask shall return with an
+ * error (E_OS_SPINLOCK), which can be evaluated in the application.
+ * (BSW4080021) */
+ if (EE_as_has_spinlocks_locked(current)) {
+ ev = E_OS_SPINLOCK;
+ } else
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#endif /* __OO_EXTENDED_STATUS__ */
+
+#if (defined(__RN_TASK__)) || (defined(EE_AS_RPC__))
+ if (EE_IS_TID_REMOTE(TaskID)) {
+#ifdef EE_AS_RPC__
+ /* Tmp Tid (introduced to meet MISRA requirements) */
+ EE_TID tmp_tid;
+
+ EE_os_param unmarked_tid;
+ /* Two steps macro assignment to meet MISRA 10.3 required rule */
+ tmp_tid = EE_UNMARK_REMOTE_TID(TaskID);
+ unmarked_tid.value_param = (EE_UREG)tmp_tid;
+ /* Forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_ChainTask, unmarked_tid,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM);
+ /* Like in TerminateTask, we do not have to activate any other task */
+ EE_th_terminate_nextask[current] = EE_NIL;
+#else /* EE_AS_RPC__ */
+ EE_TYPERN_PARAM par;
+ par.pending = 1U;
+ /* Forward the request to another CPU */
+ (void)EE_rn_send((EE_SREG)EE_MARK_REMOTE_TID(TaskID),
+ EE_RN_TASK, par);
+ /* Like in TerminateTask, we do not have to activate any other task */
+ EE_th_terminate_nextask[current] = EE_NIL;
+ ev = E_OK;
+#endif /* EE_AS_RPC__ */
+ } else {
+#endif /* __RN_TASK__ || EE_AS_RPC__ */
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* Check if the TASK Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_TASK_ACCESS_ERR(TaskID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* Check if the TASK Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ /* Check for pending activations; works also if the task passed as
+ * parameter inside ChainTask is the calling task;
+ * see MODISTARC Test 9 */
+ if ((TaskID != current) && (EE_th_rnact[TaskID] == 0U)) {
+ ev = E_OS_LIMIT;
+ } else {
+ /* [SWS_Os_00469]: The Operating System module shall start an
+ * OsTaskTimeFrame when a task is activated successfully.
+ * (SRS_Os_11008) */
+ /* [SWS_Os_00466]: If an attempt is made to activate a task before the
+ * end of an OsTaskTimeFrame then the Operating System module shall not
+ * perform the activation AND shall call the ProtectionHook()
+ * with E_OS_PROTECTION_ARRIVAL. */
+ /* Check Interarrival Frame */
+ if (EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(TaskID))) {
+ /* Note: the decrement is done now, not in the endcycle! */
+ --EE_th_rnact[TaskID];
+ /* We have to activate another TASK... */
+ EE_th_terminate_nextask[current] = TaskID;
+ }
+ ev = E_OK;
+ }
+#if (defined(__RN_TASK__)) || (defined(EE_AS_RPC__))
+}
+#endif /* __RN_TASK__ || EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_ChainTask(TaskID, ev);
+ } else {
+ /* The following won't never return */
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHAINTASK);
+ EE_hal_terminate_task(current);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CHAINTASK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_CHAINTASK__ */
+#endif /* __OO_NO_CHAINTASK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evclear.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evclear.c
new file mode 100644
index 0000000..e292fa6
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evclear.c
@@ -0,0 +1,128 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_evclear.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* ClearEvent:
+ * - can be called from an extended task
+ * - clear the events for the task
+ * - returns (only extended state)
+ * E_OS_CALLEVEL call at interrupt level
+ * E_OS_ACCESS if the task is not an extended task
+ */
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+#ifndef __PRIVATE_CLEAREVENT__
+
+StatusType EE_oo_ClearEvent(EventMaskType Mask)
+{
+ register EE_TID current;
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_CLEAREVENT);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * invalid value of the service. (BSW11009, BSW11013) */
+ /* ClearEvent can be callable only by Task */
+ /* Check for a call at interrupt level; This must be the FIRST check! */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U) || (current == EE_NIL)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_SERVICE_PROTECTION__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+ /* Check if the task Id is valid */
+ if (EE_th_is_extended[current] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* clear the event */
+ EE_th_event_active[current] &= ~Mask;
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_ClearEvent(Mask, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_CLEAREVENT);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_CLEAREVENT__ */
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evget.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evget.c
new file mode 100644
index 0000000..f5a2fdc
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evget.c
@@ -0,0 +1,163 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_evget.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* GetEvent:
+ * - can be called from a task, from ISR, from error, pre e post taskhook
+ * - clear the events for the task
+ * - returns (only extended state)
+ * E_OS_ID task id invalid
+ * E_OS_ACCESS if the task is not an extended task
+ * E_OS_STATE the task id is in the suspended state
+ */
+
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+#ifndef __PRIVATE_GETEVENT__
+
+StatusType EE_oo_GetEvent(TaskType TaskID,
+ EventMaskRefType Event)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETEVENT);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * invalid value of the service. (BSW11009, BSW11013) */
+ /* GetEvent is callable by Task, ISR2, ErrorHook Pre and Post TaskHook */
+ if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != PreTaskHook_Context) &&
+ (EE_as_execution_context != PostTaskHook_Context)) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+#ifdef EE_AS_RPC__
+ /* [OS589] All functions that are not allowed to operate cross core shall
+ * return E_OS_CORE in extended status if called with parameters that
+ * require a cross core operation. (BSW4080013) */
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ ev = E_OS_CORE;
+ } else
+#endif /* EE_AS_RPC__ */
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_TASK_ACCESS_ERR(TaskID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+#ifdef EE_AS_RPC__
+ /* [OS589]: All functions that are not allowed to operate cross core shall
+ * return E_OS_CORE in extended status if called with parameters that
+ * require a cross core operation. (BSW4080013) */
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ ev = E_OS_CORE;
+ } else
+#endif /* EE_AS_RPC__ */
+ /* Check if the TASK ID is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ if (EE_th_is_extended[TaskID] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else if (EE_th_status[TaskID] == SUSPENDED) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ if (Event == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051] If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Event, sizeof(*Event)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ {
+ /* XXX: This SHALL be atomic. Check this architectures other than TriCore */
+ *Event = EE_th_event_active[TaskID];
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_VALUE((EE_UREG)TaskID);
+ EE_OS_ERROR_PARAMETERS_PARAM2_REF(event_ref, Event);
+
+ EE_os_notify_error_from_us(OSServiceId_GetEvent, &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETEVENT);
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETEVENT);
+ }
+
+ return ev;
+}
+
+#endif /* __PRIVATE_GETEVENT__ */
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evset.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evset.c
new file mode 100644
index 0000000..781c6e9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evset.c
@@ -0,0 +1,202 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_evset.c,v 1.4 2005/11/03 09:39:48 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* SetEvent:
+ * - can be called from ISR and from task level
+ * - if the task was waiting for one of the events -> wake up it!
+ * - returns (only extended state)
+ * E_OS_ID if task id is invalid
+ * E_OS_ACCESS if the referenced task is not an extended task
+ * E_OS_STATE events cannot be set because the task is in the
+ * suspended state
+ *
+ * Note: The implementation of this function can be a little bit
+ * optimized. That is, we should check in which queue the task really
+ * goes, then eventually inserting it into the ready queue...
+ *
+ * Note: part of this code is present also in altick.c!
+ */
+
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+#ifndef __PRIVATE_SETEVENT__
+
+StatusType EE_oo_SetEvent(TaskType TaskID,
+ EventMaskType Mask)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SETEVENT);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* SetEvent is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__RN_EVENT__)) || (defined(EE_AS_RPC__))
+ if (EE_IS_TID_REMOTE(TaskID)) {
+#ifdef EE_AS_RPC__
+ /* Tmp Tid (introduced to meet MISRA requirements) */
+ EE_TID tmp_tid;
+
+ EE_os_param unmarked_tid;
+ EE_os_param as_mask;
+
+ /* Two steps macro assignment to meet MISRA 10.3 required rule */
+ tmp_tid = EE_UNMARK_REMOTE_TID(TaskID);
+ unmarked_tid.value_param = (EE_UREG)tmp_tid;
+ as_mask.value_param = Mask;
+
+ /* Forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_SetEvent, unmarked_tid, as_mask,
+ EE_OS_INVALID_PARAM);
+#else /* EE_AS_RPC__ */
+ /* Forward the request to another CPU when the task does
+ * not belong to the current CPU */
+ register EE_TYPERN_PARAM par;
+ par.ev = Mask;
+ (void)EE_rn_send((EE_SREG)EE_MARK_REMOTE_TID(TaskID),
+ EE_RN_EVENT, par);
+ ev = E_OK;
+#endif /* EE_AS_RPC__ */
+ } else {
+#endif /* __RN_EVENT__ || EE_AS_RPC__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_TASK_ACCESS_ERR(TaskID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* Check if the TASK Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+#if defined(__OO_EXTENDED_STATUS__)
+ if (EE_th_is_extended[TaskID] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else if (EE_th_status[TaskID] == SUSPENDED) {
+ ev = E_OS_STATE;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* Set the event mask only if the task is not suspended */
+ EE_th_event_active[TaskID] |= Mask;
+
+ /* Check if the TASK was waiting for an event we just set
+ *
+ * WARNING:
+ * the test with status==WAITING is FUNDAMENTAL to avoid double
+ * insertion of the task in the ready queue!!! Example, when I call
+ * two times the same setevent... the first time the task must go in
+ * the ready queue, the second time NOT!!!
+ */
+ if (((EE_th_event_waitmask[TaskID] & Mask) != 0U) &&
+ (EE_th_status[TaskID] == WAITING)) {
+ /* [SWS_Os_00472] The Operating System module shall start an
+ * OsTaskTimeFrame when a task is released successfully.
+ * (SRS_Os_11008) */
+ /* [SWS_Os_00467] If an attempt is made to release a task before
+ * the end of an OsTaskTimeFrame then the Operating System module
+ * shall not perform the release AND shall call the
+ * ProtectionHook() with E_OS_PROTECTION_ARRIVAL AND the EVENT
+ * SHALL BE SET. */
+ if (EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(TaskID))) {
+ /* If yes, the task must go back into the READY state */
+ EE_th_status[TaskID] = READY;
+ /* Insert the task in the ready queue... */
+ EE_rq_insert(TaskID);
+
+ /* If I am at task level, check for preemption... */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ /* We are inside a task */
+ EE_oo_preemption_point();
+ }
+ }
+ }
+ ev = E_OK;
+ }
+#if (defined(__RN_EVENT__)) || (defined(EE_AS_RPC__))
+}
+#endif /* __RN_EVENT__ || EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_SetEvent(TaskID, Mask, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SETEVENT);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_SETEVENT__ */
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evwait.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evwait.c
new file mode 100644
index 0000000..88eb376
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_evwait.c
@@ -0,0 +1,178 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_evwait.c,v 1.3 2006/05/03 05:59:55 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* WaitEvent:
+ * - can be called from an extended task only
+ * - the task state is put to wait until an event in the mask has been set
+ * - if the task blocks -> reschedulig + internal resource released
+ * - returns (only extended state)
+ * E_OS_RESOURCE task occupies a resource
+ * E_OS_ACCESS if the task is not an extended task
+ * E_OS_CALLEVEL called at interrupt level
+ */
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+#ifndef __PRIVATE_WAITEVENT__
+
+StatusType EE_oo_WaitEvent(EventMaskType Mask)
+{
+ register TaskType current;
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_WAITEVENT);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* Check for a call at interrupt level:
+ * Note: this must be the FIRST error check!!! */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U) || (current == EE_NIL)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_SERVICE_PROTECTION__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+#ifndef __OO_NO_RESOURCES__
+ /* Check for busy resources */
+ if (EE_th_resource_last[current] != EE_UREG_MINUS1) {
+ ev = E_OS_RESOURCE;
+ } else
+#endif /* __OO_NO_RESOURCES__ */
+ /* Check if the task is an extended TASK */
+ if (EE_th_is_extended[current] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* [OS622]: The AUTOSAR Operating System WaitEvent API service shall check if
+ * it has been called while the calling TASK has occupied a spinlock.
+ * In extended status an error E_OS_SPINLOCK shall be returned and the TASK
+ * shall not enter the wait state. (BSW4080021) */
+ if (EE_as_has_spinlocks_locked(current)) {
+ ev = E_OS_SPINLOCK;
+ } else
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#endif /* __OO_EXTENDED_STATUS__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(__EE_MEMORY_PROTECTION__))
+#if (defined(EE_SYSCALL_NR)) && (defined(EE_MAX_SYS_SERVICEID)) \
+ && (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+ /* If a TASK is inside CallTrustedFunction() and TASK
+ * rescheduling takes place within the same OSApplication scheduling of
+ * other TASKs which belong to the same OS-Application as the caller needs
+ * to be restricted.
+ * EG:To assure that I CANNOT let WAIT take place in a
+ * Trusted Function Call!!! */
+ if (EE_as_Application_RAM[EE_as_active_app].
+ TrustedFunctionCallsCounter != 0U) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ */
+ /* Check if we have to wait */
+ if ((EE_th_event_active[current] & Mask) == 0U) {
+ /* Set the waiting mask */
+ EE_th_event_waitmask[current] = Mask;
+
+ /* Prepare current TASK to block */
+ EE_oo_prepare_to_block();
+
+ /* The TASK is not inserted in any queue! it will be woken
+ * up by a SetEvent using a EE_hal_stkchange... */
+
+ /* Reschedule next TASK:
+ * check if there is to schedule a ready thread or pop a preempted
+ * thread */
+ EE_oo_reschedule_on_block();
+
+ /* Reset the waiting mask */
+ EE_th_event_waitmask[current] = 0U;
+
+ ev = E_OK;
+ } else {
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_WaitEvent(Mask, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_WAITEVENT);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* __PRIVATE_WAITEVENT__ */
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_force_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_force_schedule.c
new file mode 100644
index 0000000..6c4f1e2
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_force_schedule.c
@@ -0,0 +1,127 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_force_schedule.c,v 1.2 2006/06/08 20:40:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* Force Scheduling:
+ *
+ * - This is an internal function that has been inserted in the OO
+ * implementation because it is also needed because counters relies
+ * on such a rescheduling point when the counter increment is
+ * called inside a task (a call to this function is not needed when
+ * calling the counter increment inside an interrupt handler.
+ *
+ * - no checks are done at all; it is the user responsibility to take
+ * care that this function is called in the proper place.
+ *
+ * - the typical behavior of this function is -nothing-. It will just
+ * implement a preemption point for the functions that need it and
+ * that have not a preemption point hardwired in their code.
+ *
+ * - return values:
+ * Standard status: nothing
+ * Extended status: E_OS_CALLEVEL, if it was called at interrupt level
+ *
+ */
+
+#ifndef __PRIVATE_FORCESCHEDULE__
+
+StatusType EE_oo_ForceSchedule(void)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_FORCESCHEDULE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* check for a call at interrupt level: This must be the FIRST check!*/
+ if ((EE_hal_get_IRQ_nesting_level() != 0U)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_AS_SERVICE_PROTECTION_ */
+ {
+ EE_oo_preemption_point();
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_service(OSServiceId_ForceSchedule, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_FORCESCHEDULE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return E_OK;
+}
+
+#endif /* __PRIVATE_FORCESCHEDULE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getcountervalue.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getcountervalue.c
new file mode 100644
index 0000000..e3089e3
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getcountervalue.c
@@ -0,0 +1,164 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2011 Errico Guidieri
+ */
+
+#include "ee_internal.h"
+
+/***************************************************************************
+* AS 4.0 OS SWS 8.4.17 GetCounterValue
+***************************************************************************/
+
+#ifndef __PRIVATE_GETCOUNTERVALUE__
+StatusType EE_oo_GetCounterValue(CounterType CounterID,
+ TickRefType Value)
+{
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETCOUNTERVALUE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * “invalid value” of the service. (BSW11009, BSW11013) */
+ /* GetCounterValue is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL.
+ +
+ + MISRA dictate NULL check for pointers always. */
+
+ if (Value == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app, Value,
+ sizeof(*Value)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(CounterID)) {
+ EE_os_param as_value;
+ EE_os_param unmarked_alarm_id;
+
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(CounterID);
+ as_value.tick_ref = Value;
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_GetCounterValue, unmarked_alarm_id,
+ as_value, EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If counters are not defined cut everything */
+#if (defined(EE_MAX_COUNTER)) && (EE_MAX_COUNTER > 0U)
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (CounterID >= EE_MAX_COUNTER) {
+ ev = E_OS_ID;
+ } else if (EE_COUNTER_ACCESS_ERR(CounterID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* OS376: If the input parameter <CounterID> in a call of GetElapsedValue()
+ * is not valid GetElapsedValue() shall return E_OS_ID.
+ * <Only in Extended Status: look at Return value in specification table> */
+ if (CounterID >= EE_MAX_COUNTER) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ {
+ /* [OS377]: If the input parameter <CounterID> in a call of
+ * GetCounterValue() is valid, GetCounterValue() shall return the current
+ * tick value of the counter via <Value> and return E_OK.
+ * [OS531]: ... for counters of OsCounterType = SOFTWARE the current
+ * “software” tick value is returned. */
+ *Value = EE_counter_RAM[CounterID].value;
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_COUNTER > 0 */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_COUNTER > 0 */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_GetCounterValue(CounterID, Value, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETCOUNTERVALUE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* __PRIVATE_GETCOUNTERVALUE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getelapsedvalue.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getelapsedvalue.c
new file mode 100644
index 0000000..6956248
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_getelapsedvalue.c
@@ -0,0 +1,169 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2011 Errico Guidieri
+ */
+
+#include "ee_internal.h"
+
+/***************************************************************************
+* AS 4.0 OS SWS 8.4.18 GetElapsedValue
+***************************************************************************/
+
+#ifndef __PRIVATE_GETELAPSEDVALUE__
+
+StatusType EE_oo_GetElapsedValue(CounterType CounterID,
+ TickRefType Value,
+ TickRefType ElapsedValue)
+{
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETELAPSEDVALUE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * invalid value of the service. (BSW11009, BSW11013) */
+ /* GetElapsedValue is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ if ((Value == NULL) || (ElapsedValue == NULL)) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if ((!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Value, sizeof(*Value)))) ||
+ (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ ElapsedValue, sizeof(*ElapsedValue))))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_AS_ID_REMOTE(CounterID)) {
+ EE_os_param as_value, as_elapsed_value;
+ EE_os_param unmarked_alarm_id;
+ unmarked_alarm_id.value_param = EE_AS_UNMARK_REMOTE_ID(CounterID);
+ as_value.tick_ref = Value;
+ as_elapsed_value.tick_ref = ElapsedValue;
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc(OSServiceId_GetElapsedValue, unmarked_alarm_id, as_value,
+ as_elapsed_value);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+ /* If counters are not defined cut everything */
+#if (defined(EE_MAX_COUNTER)) && (EE_MAX_COUNTER > 0U)
+ /* [OS381]: If the input parameter <CounterID> in a call of
+ * GetElapsedValue() is not Valid GetElapsedValue() shall return
+ * E_OS_ID. */
+ if (CounterID >= EE_MAX_COUNTER) {
+ ev = E_OS_ID;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ if (EE_COUNTER_ACCESS_ERR(CounterID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ */
+ if (*Value > EE_counter_ROM[CounterID].maxallowedvalue) {
+ ev = E_OS_VALUE;
+ } else {
+ /* [OS382]: If the input parameters in a call of GetElapsedValue() are
+ * valid, GetElapsedValue() shall return the number of elapsed ticks
+ * since the given <Value> value via <ElapsedValue> and shall return
+ * E_OK.
+ * [OS533]: Caveats of GetCounterValue():If the timer already passed the
+ * <Value> value a second (or multiple) time, the result returned is wrong.
+ * The reason is that the service can not detect such a relative overflow.
+ */
+ *ElapsedValue = (EE_counter_RAM[CounterID].value >= *Value) ?
+ /* Timer did not pass the <value> yet */
+ (EE_counter_RAM[CounterID].value - *Value) :
+ /* Timer already passed the <value> */
+ ((EE_counter_ROM[CounterID].maxallowedvalue -
+ (*Value - EE_counter_RAM[CounterID].value)) + 1U);
+
+ ev = E_OK;
+ }
+#else /* EE_MAX_COUNTER > 0 */
+ {
+ ev = E_OS_ID;
+ }
+#endif /* EE_MAX_COUNTER > 0 */
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_GetElapsedValue(CounterID, Value, ElapsedValue,
+ ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETELAPSEDVALUE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_GETELAPSEDVALUE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskid.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskid.c
new file mode 100644
index 0000000..5a289d4
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskid.c
@@ -0,0 +1,119 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2004 Paolo Gai
+ * CVS: $Id: ee_gettaskid.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+/* This file is ONLY compiled when makking a BINARY DISTRIBUTION */
+
+#include "ee_internal.h"
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/* 13.2.3.5: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETTASKID__
+StatusType EE_oo_GetTaskID(TaskRefType TaskID)
+{
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETTASKID);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetTaskID is callable by Task, ISR2, ErrorHook, ProtectionHook, Pre and
+ * Post TaskHook */
+ if (EE_as_execution_context > PostTaskHook_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL.
+ +
+ + MISRA dictate NULL check for pointers always. */
+ if (TaskID == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ TaskID, sizeof(*TaskID)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && EE_SERVICE_PROTECTION__ &&
+ * __EE_MEMORY_PROTECTION__ */
+ {
+ /* XXX: This SHALL be atomic. Check this architectures other than TriCore */
+ *TaskID = EE_stk_queryfirst();
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_REF(task_ref, TaskID);
+
+ EE_os_notify_error_from_us(OSServiceId_GetTaskID, &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETTASKID);
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETTASKID);
+ }
+
+ return ev;
+}
+#endif /* __PRIVATE_GETTASKID__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskstate.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskstate.c
new file mode 100644
index 0000000..99b1a89
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_gettaskstate.c
@@ -0,0 +1,156 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2004 Paolo Gai
+ * CVS: $Id: ee_gettaskstate.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/***************************************************************************
+* 13.2 Task management
+***************************************************************************/
+
+/* 13.2.3.6: BCC1, BCC2, ECC1, ECC2 */
+#ifndef __PRIVATE_GETTASKSTATE__
+
+StatusType EE_oo_GetTaskState(TaskType TaskID,
+ TaskStateRefType State)
+{
+ register StatusType ev;
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETTASKSTATE);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetTaskID is callable by Task, ISR2, ErrorHook, ProtectionHook, Pre and
+ * Post TaskHook */
+ if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != PreTaskHook_Context) &&
+ (EE_as_execution_context != PostTaskHook_Context)) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* [OS566]: The Operating System API shall check in extended mode all pointer
+ * argument for NULL pointer and return OS_E_PARAMETER_POINTER
+ * if such argument is NULL.
+ +
+ + MISRA dictate NULL check for pointers always. */
+ if (State == NULL) {
+ ev = E_OS_PARAM_POINTER;
+ } else
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__)) \
+ && (defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ State, sizeof(*State)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && EE_SERVICE_PROTECTION__ &&
+ * __EE_MEMORY_PROTECTION__ */
+
+#ifdef EE_AS_RPC__
+ if (EE_IS_TID_REMOTE(TaskID)) {
+ /* Tmp Tid (introduced to meet MISRA requirements) */
+ EE_TID tmp_tid;
+ EE_os_param as_state;
+ EE_os_param unmarked_tid;
+ /* Two steps macro assignment to meet MISRA 10.3 required rule */
+ tmp_tid = EE_UNMARK_REMOTE_TID(TaskID);
+ unmarked_tid.value_param = (EE_UREG)tmp_tid;
+ as_state.task_state_ref = State;
+
+ /* forward the request to another CPU in synchronous way */
+ ev = EE_as_rpc_from_us(OSServiceId_GetTaskState, unmarked_tid, as_state,
+ EE_OS_INVALID_PARAM);
+ } else {
+#endif /* EE_AS_RPC__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else if (EE_TASK_ACCESS_ERR(TaskID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* check if the task Id is valid */
+ if ((TaskID < 0) || (TaskID >= EE_MAX_TASK)) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+ {
+ /* XXX: This SHALL be atomic. Check this architectures other than TriCore */
+ *State = EE_th_status[TaskID];
+ ev = E_OK;
+ }
+#ifdef EE_AS_RPC__
+}
+#endif /* EE_AS_RPC__ */
+
+ if (ev != E_OK) {
+ EE_OS_ERROR_PARAMETERS();
+ EE_OS_ERROR_PARAMETERS_PARAM1_REF(task_state_ref, State);
+
+ EE_os_notify_error_from_us(OSServiceId_GetTaskState, &error_parameters, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETTASKSTATE);
+ } else {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETTASKSTATE);
+ }
+
+ return ev;
+}
+#endif /* __PRIVATE_GETTASKSTATE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_iparam.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_iparam.c
new file mode 100644
index 0000000..6b05b66
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_iparam.c
@@ -0,0 +1,53 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2015 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2015 Paolo Gai
+ * CVS: $Id: ee_startos.c,v 1.5 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* Invalid parameter for macros, see ee_oo_common.h */
+/* To be used as place holder when an API doesn't have a parameter */
+/* it is in a separate file to avoid wrong inclusions */
+const EE_os_param EE_os_invalid_param = {
+ EE_UREG_MINUS1
+};
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_irqendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_irqendin.c
new file mode 100644
index 0000000..c9157bb
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_irqendin.c
@@ -0,0 +1,240 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_irqendin.c,v 1.2 2006/01/24 10:21:14 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#if (defined(__OO_ISR2_RESOURCES__)) || (defined(EE_AS_USER_SPINLOCKS__))
+/* Index used to give ISR2 Temporary TID value and to access at
+ * EE_isr2_nesting_level array */
+EE_UREG EE_isr2_index = EE_UREG_MINUS1;
+
+/* Assign a fake TID to an ISR2 to eventually handle resources clean-up */
+EE_TID EE_oo_assign_TID_to_ISR2(void)
+{
+ EE_UREG const actual_nesting = EE_hal_get_IRQ_nesting_level();
+
+ if (EE_isr2_index == EE_UREG_MINUS1) {
+ EE_isr2_index = 0U;
+ EE_isr2_nesting_level[0] = actual_nesting;
+ } else if (EE_isr2_nesting_level[EE_isr2_index] < actual_nesting) {
+ ++EE_isr2_index;
+ EE_isr2_nesting_level[EE_isr2_index] = actual_nesting;
+ } else {
+ /* Nothing to do added just for MISRA 2004 Required Rule 14.10 */
+ }
+
+ return EE_MAX_TASK + (EE_TID)EE_isr2_index;
+}
+
+/* [OS369]: If a Category 2 OsIsr calls GetResource() and ends (returns)
+ * without calling the corresponding ReleaseResource(), the Operating System
+ * shall perform the ReleaseResource() call and shall call the ErrorHook()
+ * (if configured) with the status E_OS_RESOURCE. */
+static void EE_IRQ_release_all_items(void);
+static void EE_IRQ_release_all_items(void)
+{
+ /* Check if the index is valid -> at least one ISR2 got a resource */
+ if (EE_isr2_index != EE_UREG_MINUS1) {
+ /* N.B This method MUST be called at the end of IRQ post-stub but BEFORE
+ * decrementing nesting. */
+ EE_UREG const actual_nesting = EE_hal_get_IRQ_nesting_level();
+
+ /* Check if this is the right level where do clean-up */
+ if (EE_isr2_nesting_level[EE_isr2_index] == actual_nesting) {
+ EE_TID current_isr2_tid = (EE_TID)EE_isr2_index + EE_MAX_TASK;
+#ifdef __OO_ISR2_RESOURCES__
+ /* OS369 */
+ if (EE_oo_release_all_resources(current_isr2_tid) != EE_UREG_MINUS1) {
+ EE_ORTI_set_lasterror(E_OS_RESOURCE);
+ EE_oo_notify_error_service(OSId_ISR2Body, E_OS_RESOURCE);
+ }
+#endif /* __OO_ISR2_RESOURCES__ */
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* Force Spinlock Release */
+ if (EE_as_release_all_spinlocks(current_isr2_tid) !=
+ INVALID_SPINLOCK) {
+ EE_ORTI_set_lasterror(E_OS_SPINLOCK);
+ EE_oo_notify_error_service(OSId_ISR2Body, E_OS_SPINLOCK);
+ }
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+ /* Decrement ISR2 index (from 0U to EE_UREG_MINUS1 is handled by
+ * unsigned wraparound) */
+ --EE_isr2_index;
+ }
+ }
+}
+#else /* __OO_ISR2_RESOURCES__ || EE_AS_USER_SPINLOCKS__ */
+__INLINE__ void __ALWAYS_INLINE__ EE_IRQ_release_all_items(void);
+__INLINE__ void __ALWAYS_INLINE__ EE_IRQ_release_all_items(void)
+{
+}
+#endif /* __OO_ISR2_RESOURCES__ || EE_AS_USER_SPINLOCKS__ */
+
+#ifndef __PRIVATE_IRQ_END_INSTANCE__
+
+static void EE_IRQ_run_next_task(void);
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+static void EE_IRQ_run_next_task(void)
+{
+ register EE_TID tnext;
+
+ tnext = EE_rq2stk_exchange();
+ if (EE_th_waswaiting[tnext]) {
+ EE_th_waswaiting[tnext] = EE_FALSE;
+ EE_oo_call_PreTaskHook();
+ EE_hal_IRQ_stacked(tnext);
+ } else {
+ EE_hal_IRQ_ready(tnext);
+ }
+}
+#else /* __OO_ECC1__ || __OO_ECC2__ */
+static void EE_IRQ_run_next_task(void)
+{
+ EE_hal_IRQ_ready(EE_rq2stk_exchange());
+}
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ handler.
+ * If the HAL allow IRQ nesting the C_end_instance should work as follows:
+ * - it must implement the preemption test only if it is the last IRQ on the
+ * stack
+ * - if there are other interrupts on the stack the IRQ end_instance should do
+ * nothing
+ */
+void EE_IRQ_end_instance(void)
+{
+ register EE_TID rqfirst, current;
+
+ rqfirst = EE_rq_queryfirst();
+ current = EE_stk_queryfirst();
+
+ if ((rqfirst != EE_NIL) && (EE_sys_ceiling < EE_th_ready_prio[rqfirst])) {
+ /* We have to schedule a READY thread */
+
+ if (current != EE_NIL) {
+ /* There is a post task hook only if a TASK that was RUNNING */
+ EE_oo_call_PostTaskHook();
+ /* The RUNNING TASK is now preempted-> READY status + still in stacked
+ * queue */
+ EE_th_status[current] = READY;
+ }
+
+ /* Another TASK is put into the RUNNING state */
+ EE_th_status[rqfirst] = RUNNING;
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[rqfirst];
+
+ EE_ORTI_set_th_eq_dispatch_prio(rqfirst);
+
+ /* "Press TP start for the first time" for this new activation or realese
+ * from wait of the TASK */
+ EE_as_tp_active_start_on_TASK_stacking(rqfirst);
+ /* Set the next running TASK, it doesn't directly RUN it */
+ EE_IRQ_run_next_task();
+ } else {
+ if (current == EE_NIL) {
+ /* We are switching back to the Idle loop */
+ EE_as_set_execution_context(Idle_Context);
+ EE_as_tp_active_start_idle();
+ } else {
+ /* We are switching back to a preempted TASK */
+ EE_as_set_execution_context(TASK_Context);
+ /* Enable the Task Timing Protection Set */
+ EE_as_tp_active_set_from_TASK(current);
+ }
+ /* Set the Context Switch up, it doesn't directly switch */
+ EE_hal_IRQ_stacked(current);
+ }
+}
+
+/* This primitive shall be atomic.
+ * This primitive shall be inserted as the last function in an IRQ post-stub.
+ * This primitive do needed clean-up as resetting kernel interrupt nested
+ * counter and release gotten resources if application forget to do that as
+ * specified by Autosar standard.
+ */
+void EE_IRQ_end_post_stub(void)
+{
+ /* [OS368]: If a Category 2 OsIsr calls DisableAllInterupts()/
+ * SuspendAllInterrupts()/SuspendOSInterrupts() and ends (returns)
+ * without calling the corresponding EnableAllInterrupts()/
+ * ResumeAllInterrupts() / ResumeOSInterrupts(),
+ * the Operating System shall perform the missing service and shall call
+ * the ErrorHook() (if configured) with the status E_OS_DISABLEDINT. */
+
+ /* Only check and reset ISR flags an counters because ISR re-enabling is done
+ * in CPU layer */
+ if (EE_oo_check_disableint_error()) {
+ EE_ORTI_set_lasterror(E_OS_DISABLEDINT);
+ EE_oo_notify_error_service(OSId_ISR2Body, E_OS_DISABLEDINT);
+ /* Reset ISRs counter */
+ EE_oo_IRQ_disable_count = 0U;
+ }
+
+ /* [SWS_Os_00474] The Operating System module shall reset an ISR's
+ * OsIsrExecutionBudget when the ISR returns control to the OS or terminates.
+ * (SRS_Os_11008) */
+ /* Reset ALL TP Budgets, safest approach */
+ EE_as_tp_active_reset_budgets();
+
+ /* [OS369]: If a Category 2 OsIsr calls GetResource() and ends (returns)
+ * without calling the corresponding ReleaseResource(), the Operating System
+ * shall perform the ReleaseResource() call and shall call the ErrorHook()
+ * (if configured) with the status E_OS_RESOURCE. */
+ /* [OS109]: If the Operating System module forcibly terminates an interrupt
+ * service routine, it clears the interrupt request, aborts the interrupt
+ * service routine (The interrupt source stays in the current state.)
+ * and releases all OSEK resources the interrupt service routine has
+ * allocated and calls EnableAllInterrupts() / ResumeOSInterrupts() /
+ * ResumeAllInterrupts() if the interrupt called DisableAllInterrupts() /
+ * SuspendOSInterrupts() / SuspendAllInterrupts() before without the
+ * corresponding EnableAllInterrupts() / ResumeOSInterrupts() /
+ * ResumeAllInterrupts() call. */
+ EE_IRQ_release_all_items();
+}
+#endif /* __PRIVATE_IRQ_END_INSTANCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lockres.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lockres.c
new file mode 100644
index 0000000..e366e20
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lockres.c
@@ -0,0 +1,227 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_lockres.c,v 1.2 2006/02/08 11:37:31 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#if (defined(RTDRUID_CONFIGURATOR_NUMBER)) \
+ && (RTDRUID_CONFIGURATOR_NUMBER >= RTDRUID_CONFNUM_NO_ORTI_VARS)
+
+/* ORTI variables */
+
+#ifdef __OO_ORTI_PRIORITY__
+EE_TYPEPRIO EE_ORTI_resource_oldpriority[EE_MAX_RESOURCE];
+#endif /* __OO_ORTI_PRIORITY__ */
+
+#ifdef __OO_ORTI_RES_LOCKER_TASK__
+static EE_TID EE_ORTI_res_locker[EE_MAX_RESOURCE];
+#endif /* __OO_ORTI_RES_LOCKER_TASK__ */
+
+#endif /* RTDRUID_CONFIGURATOR_NUMBER */
+
+/* GetResource:
+ * - lock a resource
+ * - lock/unlock on the same function level
+ * - no point of rescheduling inside critical sections!!!
+ * - returns (only extended state)
+ * E_OS_ID if resource number is invalid
+ * E_OS_ACCESS if resource already locked or interrupt routine
+ * greater than the ceiling priority
+ *
+ * Extended Status: Count for locked resources!!!!
+ */
+
+#ifndef __PRIVATE_GETRESOURCE__
+
+StatusType EE_oo_GetResource(ResourceType ResID)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Variable */
+#if (!defined(__EE_MEMORY_PROTECTION__)) || (defined(__OO_ISR2_RESOURCES__))
+ register EE_FREG flag;
+#endif /* !__EE_MEMORY_PROTECTION__ || __OO_ISR2_RESOURCES__ */
+#ifdef __MSRP__
+ register EE_UREG isGlobal;
+#endif /* __MSRP__ */
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ORTI_PRIORITY__)) \
+ || (defined(__OO_ISR2_RESOURCES__))
+ register TaskType current = EE_stk_queryfirst();
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ORTI_PRIORITY__ ||
+ * __OO_ISR2_RESOURCES__ */
+#ifdef __OO_EXTENDED_STATUS__
+ /* To cache inside task info */
+ register EE_TYPEBOOL inside_task = (EE_hal_get_IRQ_nesting_level() == 0U);
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ /* Primitive Lock Variable */
+ EE_OS_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETRESOURCE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef __MSRP__
+ isGlobal = EE_oo_isGlobal(ResID);
+ ResID = ResID & ~EE_GLOBAL_MUTEX;
+#endif /* __MSRP__ */
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* GetResource is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* no comparison for ResID < 0, the type is unsigned! */
+ if (ResID >= EE_MAX_RESOURCE) {
+ ev = E_OS_ID;
+ } else if (EE_RESOURCE_ACCESS_ERR(ResID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* no comparison for ResID < 0, the type is unsigned! */
+ if (ResID >= EE_MAX_RESOURCE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+#ifdef __OO_EXTENDED_STATUS__
+ if (EE_resource_locked[ResID] != EE_FALSE) {
+ /* Check if the resource is already gotten */
+ ev = E_OS_ACCESS;
+ } else if ((inside_task != EE_FALSE) && ((current == EE_NIL) ||
+ (EE_th_ready_prio[current] > EE_resource_ceiling[ResID]))) {
+ /* If I'm in a Task check invalid task and ceiling */
+ ev = E_OS_ACCESS;
+ } else
+#ifdef __OO_ISR2_RESOURCES__
+ if ((inside_task == EE_FALSE) &&
+ (EE_hal_check_int_prio_if_higher(EE_resource_isr2_priority[ResID]) !=
+ 0U)) {
+ ev = E_OS_ACCESS;
+ } else
+#else /* __OO_ISR2_RESOURCES__ */
+ if (inside_task == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* __OO_ISR2_RESOURCES__ */
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* Handle, if needed, resource sharing with ISR2 */
+#ifdef __OO_ISR2_RESOURCES__
+ /* Save old priority to restore it when release the resource */
+ EE_isr2_oldpriority[ResID] = EE_hal_get_int_prio();
+ /* Raise ISR2 priority if needed */
+ flag = EE_hal_raise_int_prio_if_less(EE_resource_isr2_priority[ResID],
+ flag);
+
+ /* If actually we are inside an ISR2 assign a fake TID to access stack */
+ if (EE_hal_get_IRQ_nesting_level() > 0U) {
+ current = EE_oo_assign_TID_to_ISR2();
+ }
+#endif /* __OO_ISR2_RESOURCES__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ISR2_RESOURCES__))
+ /* insert the resource into the data structure */
+ EE_resource_stack[ResID] = EE_th_resource_last[current];
+ EE_th_resource_last[current] = ResID;
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ISR2_RESOURCES__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ORTI_RES_ISLOCKED__))
+ EE_resource_locked[ResID] = EE_TRUE;
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ORTI_RES_ISLOCKED__ */
+
+#ifdef __OO_ORTI_RES_LOCKER_TASK__
+ EE_ORTI_res_locker[ResID] = (EE_TID)current;
+#endif /* __OO_ORTI_RES_LOCKER_TASK__ */
+
+ EE_resource_oldceiling[ResID] = EE_sys_ceiling;
+ EE_sys_ceiling |= EE_resource_ceiling[ResID];
+
+#ifdef __OO_ORTI_PRIORITY__
+ EE_ORTI_resource_oldpriority[ResID] = EE_ORTI_th_priority[current];
+ if (EE_ORTI_th_priority[current] < EE_resource_ceiling[ResID]) {
+ EE_ORTI_th_priority[current] = EE_resource_ceiling[ResID];
+ }
+#endif /* __OO_ORTI_PRIORITY__ */
+
+#ifdef __MSRP__
+ /* if this is a global resource, lock the others CPUs */
+ if (isGlobal) {
+ EE_hal_spin_in((EE_TYPESPIN)ResID);
+ }
+#endif /* __MSRP__ */
+
+ /* Start TP Lock Budget, if needed */
+ EE_as_tp_active_activate_budget(EE_RESOURCE_LOCK_BUDGET, ResID, EE_FALSE);
+
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_GetResource(ResID, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETRESOURCE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_GETRESOURCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lookup.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lookup.c
new file mode 100644
index 0000000..8d42360
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_lookup.c
@@ -0,0 +1,129 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_lookup.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#if (defined(__OO_HAS_ERRORHOOK__)) && (!defined(__OO_ERRORHOOK_NOMACROS__))
+#ifndef __MSRP__
+OSServiceIdType EE_oo_ErrorHook_ServiceID;
+EE_oo_ErrorHook_parameters EE_oo_ErrorHook_data;
+#elif (defined(EE_CURRENTCPU)) && (EE_CURRENTCPU == 0)
+OSServiceIdType EE_SHARED_UDATA EE_oo_ErrorHook_ServiceID[EE_MAX_CPU];
+EE_oo_ErrorHook_parameters EE_SHARED_UDATA EE_oo_ErrorHook_data[EE_MAX_CPU];
+#endif /* !__MSRP__ && (EE_CURRENTCPU != 0) */
+#endif /* __OO_HAS_ERRORHOOK__ && !__OO_ERRORHOOK_NOMACROS__ */
+
+/* used for nested interrupt enabling/disabling */
+EE_UREG EE_oo_IRQ_disable_count;
+
+/***************************************************************************
+* The simbol EE_OLD_HAL marks architecture that do not implement new
+* HAL APIs (MUST be defined in the header ee_cpu.h of these architectures)
+***************************************************************************/
+#ifndef EE_OLD_HAL
+EE_FREG EE_oo_IRQ_suspend_status;
+#endif /* EE_OLD_HAL */
+
+#if (defined(__OO_HAS_ERRORHOOK__)) && (!defined(__OO_ERRORHOOK_NOMACROS__))
+EE_TYPEBOOL EE_ErrorHook_nested_flag;
+#endif /* __OO_HAS_ERRORHOOK__ && !__OO_ERRORHOOK_NOMACROS__ */
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+
+const EE_INT8 EE_rq_lookup[] = {
+ -1, 0, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+#ifdef __EE_MEMORY_PROTECTION__
+void EE_oo_notify_error_from_us_internal(OSServiceIdType ServiceID,
+ const EE_oo_ErrorHook_parameters *const error_parameters_ref,
+ StatusType Error)
+{
+ if (error_parameters_ref != NULL) {
+ EE_os_notify_error(ServiceID, error_parameters_ref->param1,
+ error_parameters_ref->param2, error_parameters_ref->param3, Error);
+ }
+}
+#endif /* __EE_MEMORY_PROTECTION__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_exchg.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_exchg.c
new file mode 100644
index 0000000..37c5891
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_exchg.c
@@ -0,0 +1,111 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_rq_exchg.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_ECC1__))
+EE_TID EE_rq2stk_exchange(void)
+{
+ EE_TID temp;
+
+ temp = EE_rq_first;
+
+ /* extract the first task from the ready queue */
+ EE_rq_first = EE_th_next[temp];
+ /* insert the extracted task on the topo of the stack */
+ EE_th_next[temp] = EE_stkfirst;
+ EE_stkfirst = temp;
+
+ return temp;
+}
+#endif
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+EE_TID EE_rq2stk_exchange(void)
+{
+ EE_INT8 x; /* the first non-empty queue */
+ EE_TID temp; /* the TID to be inserted in the top of the stack */
+ EE_TYPEPAIR y; /* used to free the descriptor */
+
+#if defined(__OO_ECC2__)
+ /* lookup at bits 15-9 */
+ x = EE_rq_lookup[(EE_rq_bitmask & 0xFF00U) >> 8];
+ if (x == (EE_INT8)-1) {
+ x = EE_rq_lookup[EE_rq_bitmask];
+ } else {
+ x += (EE_INT8)8;
+ }
+#else
+ x = EE_rq_lookup[EE_rq_bitmask];
+#endif
+
+ /* now x contains the highest priority non-empty queue number */
+
+ /* get the TID to insert in the stacked queue */
+ temp = EE_rq_pairs_tid[EE_rq_queues_head[x]];
+
+ /* free the descriptor */
+ y = EE_rq_queues_head[x];
+ EE_rq_queues_head[x] = EE_rq_pairs_next[EE_rq_queues_head[x]];
+ EE_rq_pairs_next[y] = EE_rq_free;
+ EE_rq_free = y;
+
+ if (EE_rq_queues_head[x] == (EE_SREG)-1) {
+ EE_rq_queues_tail[x] = -1;
+ /* reset the (x)th bit in the bitfield; casts are for MISRA compliance */
+ EE_rq_bitmask &= (EE_TYPE_RQ_MASK) ~((EE_TYPE_RQ_MASK)((EE_TYPE_RQ_MASK)1U << x));
+ }
+
+ /* insert the extracted task on the top of the stack */
+ EE_th_next[temp] = EE_stkfirst;
+ EE_stkfirst = temp;
+
+ return temp;
+}
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_first.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_first.c
new file mode 100644
index 0000000..998fc37
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_first.c
@@ -0,0 +1,76 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_rq_first.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ2STK_EXCHANGE__
+
+#if defined(__OO_BCC2__) || defined(__OO_ECC2__)
+EE_TID EE_rq_queryfirst(void)
+{
+ EE_INT8 x;
+
+#if defined(__OO_ECC2__)
+ /* lookup at bits 15-9 */
+ x = EE_rq_lookup[(EE_rq_bitmask & 0xFF00U) >> 8];
+ if (x == (EE_INT8)-1) {
+ x = EE_rq_lookup[EE_rq_bitmask];
+ } else {
+ x += (EE_INT8)8;
+ }
+#else
+ x = EE_rq_lookup[EE_rq_bitmask];
+#endif
+
+ /* now x contains the highest priority non-empty queue number */
+ if (x == (EE_INT8)-1) {
+ return EE_NIL;
+ } else {
+ return EE_rq_pairs_tid[EE_rq_queues_head[x]];
+ }
+}
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_inser.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_inser.c
new file mode 100644
index 0000000..68cce2e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_rq_inser.c
@@ -0,0 +1,104 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_rq_inser.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_RQ_INSERT__
+
+#if (defined(__OO_BCC1__)) || (defined(__OO_ECC1__))
+/* this function inserts a task into the ready queue */
+void EE_rq_insert(EE_TID t)
+{
+ EE_TYPEPRIO prio;
+ EE_TID p, q;
+
+ p = EE_NIL;
+ q = EE_rq_first;
+ prio = EE_th_ready_prio[t];
+
+ while ((q != EE_NIL) && (prio <= EE_th_ready_prio[q])) {
+ p = q;
+ q = EE_th_next[q];
+ }
+
+ if (p != EE_NIL) {
+ EE_th_next[p] = t;
+ } else {
+ EE_rq_first = t;
+ }
+
+ EE_th_next[t] = q;
+}
+#endif
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+void EE_rq_insert(EE_TID t)
+{
+ EE_TYPEPAIR temp;
+ EE_TYPEPRIO p;
+
+ p = EE_rq_link[t];
+
+ /* take a free pair */
+ temp = EE_rq_free;
+ EE_rq_free = EE_rq_pairs_next[EE_rq_free];
+
+ /* fill it with the TID */
+ EE_rq_pairs_tid[temp] = t;
+ EE_rq_pairs_next[temp] = -1;
+
+ /* put it at the tail of its priority queue */
+ if (EE_rq_queues_tail[p] == (EE_SREG)-1) {
+ /* no tasks in this priority queue */
+ /* set the bit field to say that a task is in the right queue */
+ EE_rq_bitmask |= (EE_TYPE_RQ_MASK)EE_th_ready_prio[t];
+ EE_rq_queues_head[p] = temp;
+ } else {
+ EE_rq_pairs_next[EE_rq_queues_tail[p]] = temp;
+ }
+ EE_rq_queues_tail[p] = temp;
+}
+#endif
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_schedule.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_schedule.c
new file mode 100644
index 0000000..1264c80
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_schedule.c
@@ -0,0 +1,212 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_schedule.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* Schedule:
+ * - the internal resource is released;
+ * - no check if resources are still used by the task
+ * - then rescheduling takes place
+ * - and then the internal resource is taken again
+ * - returns
+ * Extended status
+ * E_OS_CALLLEVEL if called at interrupt level
+ * E_OS_RESOURCE if the calling task occupies resources
+ */
+
+#ifndef __PRIVATE_SCHEDULE__
+
+StatusType EE_oo_Schedule(void)
+{
+ register EE_TID current, rq;
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SCHEDULE);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+ rq = EE_rq_queryfirst();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* check for a call at interrupt level */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U) || (current == EE_NIL)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_SERVICE_PROTECTION__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+#ifndef __OO_NO_RESOURCES__
+ /* check for busy resources */
+ if (EE_th_resource_last[current] != EE_UREG_MINUS1) {
+ ev = E_OS_RESOURCE;
+ } else
+#endif /* __OO_NO_RESOURCES__ */
+
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* [OS624]: The AUTOSAR Operating System Schedule API service shall check if it
+ * has been called while the calling TASK has occupied a spinlock. In
+ * extended status an error E_OS_SPINLOCK shall be returned and the scheduler
+ * shall not be called. (BSW4080021) */
+ if (EE_as_has_spinlocks_locked(current)) {
+ ev = E_OS_SPINLOCK;
+ } else
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+#endif /* __OO_EXTENDED_STATUS__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(__EE_MEMORY_PROTECTION__))
+#if (defined(EE_SYSCALL_NR)) && (defined(EE_MAX_SYS_SERVICEID)) && \
+ (EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID)
+ /* If a TASK is inside CallTrustedFunction() and TASK
+ * rescheduling takes place within the same OSApplication scheduling of
+ * other TASKs which belong to the same OS-Application as the caller needs
+ * to be restricted.
+ * EG: To Assure that I CANNOT let a TASK release internal resource, if this
+ * means schedule a TASK of the same OSApplication, unless the
+ * OSApplication is TRUSTED. */
+ if ((EE_as_active_app == EE_th_app[rq + 1]) &&
+ (EE_as_Application_RAM[EE_as_active_app].
+ TrustedFunctionCallsCounter != 0U) &&
+ (EE_as_Application_ROM[EE_as_active_app].Mode != EE_MEMPROT_TRUST_MODE)
+ ) {
+ ev = E_OK;
+ } else
+#endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ */
+ /* Check if there is a preemption */
+ if (rq != EE_NIL) {
+ /* The standard says that "Schedule enables a processor assignment
+ * to other TASKs with lower priority than the ceiling priority of
+ * the internal resource and higher priority than the priority of
+ * the calling TASK". That means that only TASKs currently in the
+ * ready queue with the ready priority > than the ready priority
+ * of the running TASK can be executed... */
+ if (EE_th_ready_prio[current] < EE_th_ready_prio[rq]) {
+ EE_oo_call_PostTaskHook();
+ /* release the internal resource */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+
+ /* set the ready priority bit. In that way we prevent preemption
+ * from all the tasks with lower priority than the current task.
+ *
+ * NOTE: Setting the ready priority is legal because if the task
+ * has been scheduled it must be that the system_ceiling <
+ * ready_priority, and so (system_ceiling &ready_priority)=0!!!
+ * after a task has been put in execution, the dispatch priority
+ * is set. no other bits are set when this function is called
+ * (all the resources must be unlocked, and all the task that
+ * preempts the running task must have been finished!.
+ */
+ EE_sys_ceiling |= EE_th_ready_prio[current];
+
+ /* we have to put the task in the ready status */
+ EE_th_status[current] = READY;
+ /* but not in the ready queue!!!
+ * the task remains into the stacked queue!
+ */
+
+ /* get the new internal resource */
+ EE_sys_ceiling |= EE_th_dispatch_prio[rq];
+ /* put the task in running state */
+ EE_th_status[rq] = RUNNING;
+
+ EE_ORTI_set_th_eq_dispatch_prio(current);
+ EE_ORTI_set_th_eq_dispatch_prio(rq);
+
+ /* Execute context SWITCH, this method return when we have a switch
+ * back on the previous TASK contest. */
+ EE_oo_run_next_task();
+
+ /* release the ready priority bit and... */
+ EE_sys_ceiling &= ~EE_th_ready_prio[current];
+ /* ...get again the internal resource */
+ EE_sys_ceiling |= EE_th_dispatch_prio[current];
+
+ EE_ORTI_set_th_eq_dispatch_prio(current);
+ }
+ ev = E_OK;
+ } else {
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_service(OSServiceId_Schedule, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SCHEDULE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_SCHEDULE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semgetvalue.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semgetvalue.c
new file mode 100644
index 0000000..00fad3f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semgetvalue.c
@@ -0,0 +1,116 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_semwait.c,v 1.2 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_GETVALUESEM__
+int EE_oo_GetValueSem(const SemType *Sem)
+{
+ /* Error Value */
+ register StatusType ev;
+ int returnvalue = EE_NIL;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_GETVALUESEM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ returnvalue = -1;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ if (Sem != NULL) {
+#if defined(__EE_MEMORY_PROTECTION__) && defined(EE_SERVICE_PROTECTION__)
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Sem, sizeof(*Sem)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ returnvalue = -1;
+ } else {
+#else /* __EE_MEMORY_PROTECTION__ && EE_SERVICE_PROTECTION__ */
+ {
+#endif /* __EE_MEMORY_PROTECTION__ && EE_SERVICE_PROTECTION__ */
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ if (Sem->first == EE_NIL) {
+ returnvalue = (int)(Sem->count);
+ } else {
+ returnvalue = -1;
+ }
+#else /* __OO_ECC1__ || __OO_ECC2__ */
+ returnvalue = (int)(Sem->count);
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+ ev = E_OK;
+ }
+ } else {
+ ev = E_OS_PARAM_POINTER;
+ returnvalue = -1;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_PARAM(os_sem);
+ EE_OS_PARAM_REF(os_sem, sem_ref, (SemRefType)Sem);
+ EE_os_notify_error(OSServiceId_GetValueSem, os_sem,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_GETVALUESEM);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return returnvalue;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_sempost.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_sempost.c
new file mode 100644
index 0000000..9f5167d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_sempost.c
@@ -0,0 +1,208 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_sempost.c,v 1.3 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* PostSem:
+ * - This primitive can be called from ISRs, Tasks, and from the background
+ * (main) task.
+ * - for BCC1 and BCC2, a smaller reduced version is provided.
+ * - The primitive implements the traditional counting Semaphore post operation.
+ * - If there are tasks blocked on the Semaphore, then one of these tasks is
+ * awaken. In that case, the call enforces rescheduling.
+ * If there are no tasks blocked on the Semaphore, the semaphore counter is
+ * incremented.
+ * - Error value returned
+ * Standard: No error, E_OK
+ * E_OS_VALUE Semaphore counter has the maximum value
+ *
+ * Conformance:
+ * - BCC1, BCC2 (without wakeup)
+ * - ECC1, ECC2 (with wakeup)
+ */
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#ifndef __PRIVATE_POSTSEM__
+
+StatusType EE_oo_PostSem(SemRefType Sem)
+{
+ /* Error Value */
+ register StatusType ev;
+ register TaskType unlocked_tmp;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_POSTSEM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* check if the post on the semaphore wakes up someone */
+ if ((Sem != NULL) && (Sem->first != EE_NIL)) {
+ /* update the semaphore queue */
+ unlocked_tmp = Sem->first;
+ if ((Sem->first = EE_th_next[unlocked_tmp]) == EE_NIL) {
+ Sem->last = EE_NIL;
+ }
+
+ /* if yes, the task must go back into the READY state */
+ EE_th_status[unlocked_tmp] = READY;
+ /* insert the task in the ready queue */
+ EE_rq_insert(unlocked_tmp);
+
+ /* and if I am at task level, check for preemption... */
+ if (EE_hal_get_IRQ_nesting_level() == 0U) {
+ /* we are inside a task */
+ EE_oo_preemption_point();
+ }
+ ev = E_OK;
+ } else if (Sem != NULL) {
+#if defined(EE_AS_OSAPPLICATIONS__) && (defined(EE_SERVICE_PROTECTION__) && \
+ defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Sem, sizeof(*Sem)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ if (Sem->count == EE_MAX_SEM_COUNTER) {
+ ev = E_OS_VALUE;
+ } else {
+ Sem->count++;
+ ev = E_OK;
+ }
+ } else {
+ ev = E_OS_PARAM_POINTER;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_PARAM(os_sem);
+ EE_OS_PARAM_REF(os_sem, sem_ref, Sem);
+ EE_os_notify_error(OSServiceId_PostSem, os_sem,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_POSTSEM);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_POSTSEM__ */
+#endif /* ECC1/ECC2 */
+
+
+/* This is a simplified version of PostSem */
+
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__)
+#ifndef __PRIVATE_POSTSEM__
+
+StatusType EE_oo_PostSem(SemRefType Sem)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_POSTSEM);
+
+ /* the wake up check is removed because there is no blocking wait! */
+ if (Sem != NULL) {
+#if defined(EE_AS_OSAPPLICATIONS__) && (defined(EE_SERVICE_PROTECTION__) && \
+ defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Sem, sizeof(*Sem)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ if (Sem->count == EE_MAX_SEM_COUNTER) {
+ ev = E_OS_VALUE;
+ } else {
+ Sem->count++;
+ ev = E_OK;
+ }
+ } else {
+ ev = E_OS_PARAM_POINTER;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_PARAM(os_sem);
+ EE_OS_PARAM_REF(os_sem, sem_ref, Sem);
+ EE_os_notify_error(OSServiceId_PostSem, os_sem,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_POSTSEM);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_POSTSEM__ */
+#endif /* BCC1/BCC2 */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semtrywait.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semtrywait.c
new file mode 100644
index 0000000..96c528e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semtrywait.c
@@ -0,0 +1,126 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_semtrywait.c,v 1.1 2006/05/03 05:59:55 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* TryWaitSem:
+ * - can be called from ISR2, basic and extended tasks, and the main task
+ * - If the semaphore counter is 0, the primitive returns a non-zero value.
+ * - If the semaphore counter has a value greater than 0, then the counter is decremented and the primitive returns 0.
+ * - This primitive never blocks the calling task, and it never issues
+ * a rescheduling.
+ */
+
+
+#ifndef __PRIVATE_TRYWAITSEM__
+int EE_oo_TryWaitSem(SemRefType Sem)
+{
+ /* Error Value */
+ register StatusType ev;
+ int returnvalue = EE_NIL;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_TRYWAITSEM);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+ /* check if we have to wait */
+ if (Sem != NULL) {
+#if defined(EE_AS_OSAPPLICATIONS__) && (defined(EE_SERVICE_PROTECTION__) && \
+ defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Sem, sizeof(*Sem)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ returnvalue = -1;
+ } else {
+#else /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ {
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ if (Sem->count) {
+ Sem->count--;
+ returnvalue = 0;
+ } else {
+ returnvalue = 1;
+ }
+ ev = E_OK;
+ }
+ } else {
+ ev = E_OS_PARAM_POINTER;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_PARAM(os_sem);
+ EE_OS_PARAM_REF(os_sem, sem_ref, Sem);
+ EE_os_notify_error(OSServiceId_TryWaitSem, os_sem,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_TRYWAITSEM);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return returnvalue;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semwait.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semwait.c
new file mode 100644
index 0000000..04be701
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_semwait.c
@@ -0,0 +1,173 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_semwait.c,v 1.2 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* WaitSem:
+ * - can be called from an extended task only
+ * - the task state is put to wait until a call to PostSem wakes it up
+ * - if the task blocks -> reschedulig + internal resource released
+ * - returns (only extended status)
+ * E_OS_RESOURCE task occupies a resource
+ * E_OS_ACCESS if the task is not an extended task
+ * E_OS_CALLEVEL called at interrupt level
+ */
+
+
+#if defined(__OO_ECC1__) || defined(__OO_ECC2__)
+#ifndef __PRIVATE_WAITSEM__
+
+StatusType EE_oo_WaitSem(SemRefType Sem)
+{
+ /* Error Value */
+ register StatusType ev;
+ TaskType current;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_WAITSEM);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if defined(__OO_EXTENDED_STATUS__) || defined(EE_SERVICE_PROTECTION__)
+ /* check for a call at interrupt level:
+ * Note: this must be the FIRST error check!!! */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U) || (current == EE_NIL) ||
+ (EE_as_get_execution_context() > TASK_Context)) {
+ ev = E_OS_CALLEVEL;
+ } else
+#ifndef __OO_NO_RESOURCES__
+ /* check for busy resources */
+ if (EE_th_resource_last[current] != EE_UREG_MINUS1) {
+ ev = E_OS_RESOURCE;
+ } else
+#endif /* __OO_NO_RESOURCES__ */
+
+ /* check if the task is an extended task */
+ if (EE_th_is_extended[current] == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ */
+
+ /* handle a local semaphore queue */
+ /* check if we have to wait */
+ if (Sem != NULL) {
+#if defined(EE_AS_OSAPPLICATIONS__) && (defined(EE_SERVICE_PROTECTION__) && \
+ defined(__EE_MEMORY_PROTECTION__))
+ /* [SWS_Os_00051]: If an invalid address (address is not writable by this
+ * OS-Application) is passed as an out-parameter to an Operating System
+ * service, the Operating System module shall return the status code
+ * E_OS_ILLEGAL_ADDRESS. (SRS_Os_11009, SRS_Os_11013) */
+ if (!OSMEMORY_IS_WRITEABLE(EE_hal_get_app_mem_access(EE_as_active_app,
+ Sem, sizeof(*Sem)))) {
+ ev = E_OS_ILLEGAL_ADDRESS;
+ returnvalue = -1;
+ } else {
+#else /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ {
+#endif /* EE_AS_OSAPPLICATIONS__ && __EE_MEMORY_PROTECTION__ &&
+ * EE_SERVICE_PROTECTION__ */
+ if (Sem->count != 0U) {
+ Sem->count--;
+ } else {
+ /* Prepare current Task to block */
+ EE_oo_prepare_to_block();
+
+ /* queue the task inside the semaphore queue */
+ if (Sem->first != EE_NIL) {
+ /* the semaphore queue is not empty */
+ EE_th_next[Sem->last] = current;
+ } else {
+ /* the semaphore queue is empty */
+ Sem->first = current;
+ }
+
+ Sem->last = current;
+ EE_th_next[current] = EE_NIL;
+
+ /* then, the task will be woken up by a PostSem using a EE_hal_stkchange... */
+
+ /* Reschedule next task:
+ * check if there is to schedule a ready thread or pop a preempted
+ * thread
+ */
+ EE_oo_reschedule_on_block();
+ }
+ ev = E_OK;
+ }
+ } else {
+ ev = E_OS_PARAM_POINTER;
+ }
+
+ if (ev != E_OK) {
+ EE_OS_PARAM(os_sem);
+ EE_OS_PARAM_REF(os_sem, sem_ref, Sem);
+ EE_os_notify_error(OSServiceId_WaitSem, os_sem,
+ EE_OS_INVALID_PARAM, EE_OS_INVALID_PARAM, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_WAITSEM);
+
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_WAITSEM__ */
+#endif /* defined(__OO_ECC1__) || defined(__OO_ECC2__) */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_shtdown.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_shtdown.c
new file mode 100644
index 0000000..dba9a5c
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_shtdown.c
@@ -0,0 +1,239 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_shtdown.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* ShutdownOS
+ *
+ * - This function simply calls ShutdownHook.
+ *
+ * - NOTE: it is not specified into the standard if the ShutdownHook
+ * have to be called with interrupts disabled or not. The behavior I
+ * chose is the same for the StartupHook.
+ *
+ * - It seems that the only thing that this function has to do is to call
+ * the ShutdownHook... In any case, if the ShutdownHook returns, a system
+ * reset is issued!
+ *
+ */
+
+
+#ifndef __PRIVATE_SHUTDOWNOS__
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+static void EE_oo_shutdown(void);
+
+static void EE_oo_shutdown(void)
+{
+ EE_oo_started = 0U;
+ for (;; ) {
+ ;
+ }
+}
+
+#ifdef __OO_HAS_SHUTDOWNHOOK__
+static void EE_oo_call_ShutdownHook(StatusType Error);
+
+static void EE_oo_call_ShutdownHook(StatusType Error)
+{
+ /* Set the context excution at ShutdownHook */
+ EE_as_set_execution_context(ShutdownHook_Context);
+ ShutdownHook(Error);
+}
+#else
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_ShutdownHook(StatusType Error);
+
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_ShutdownHook(StatusType Error)
+{
+}
+#endif
+
+void EE_oo_ShutdownOS_internal(StatusType Error)
+{
+ /* [OS071]: If the PostTaskHook() is configured, the Operating System shall
+ * not call the hook if ShutdownOS() is called. */
+#if 0
+ EE_oo_call_PostTaskHook();
+#endif
+
+ /* Definitely stop the timing protection. I cannot use EE_as_tp_active_stop,
+ * because it will restart Reclamation Time Frames Budget */
+ EE_hal_tp_stop();
+ EE_as_tp_active_set(INVALID_TIMING_PROTECTION);
+
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* [OS620]: ShutdownOS shall release all spinlocks which are occupied by the
+ * calling core. (BSW4080021) */
+ {
+ register EE_TYPESPIN spinlock_id;
+
+ spinlock_id = EE_as_spinlocks_last[EE_CURRENTCPU];
+ while (spinlock_id != INVALID_SPINLOCK) {
+ /* Remove the last entry from the data structure */
+ EE_as_spinlocks_last[EE_CURRENTCPU] = EE_as_spinlocks_stack[spinlock_id];
+
+ /* Free the spinlock */
+ EE_as_spinlocks_locker_core[spinlock_id] = INVALID_CORE_ID;
+ EE_as_spinlocks_locker_task_or_isr2[spinlock_id] = EE_NIL;
+
+ /* Release the lock */
+ EE_hal_spin_out(spinlock_id);
+
+ spinlock_id = EE_as_spinlocks_last[EE_CURRENTCPU];
+ }
+ }
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* [OS586]: During the shutdown, the OS-Application specific ShutdownHook
+ * shall be called on the core on which the corresponding OS-Application
+ * is bound. (BSW4080007) */
+ {
+ register ApplicationType i;
+ /* Set the context execution at ShutdownHook Context */
+ EE_as_set_execution_context(ShutdownHook_Context);
+ /* ApplID 0 is always reserved by the Kernel */
+ for (i = 1U; i < EE_MAX_APP; ++i) {
+ register EE_STATUSHOOKTYPE shutdown_hook =
+ EE_as_Application_shutdownhook[i];
+
+ if (shutdown_hook != 0U) {
+ /* [OS225]: The Operating System module shall execute an
+ * application-specific shutdown hook with the access rights of the
+ * associated OS-Application. */
+ EE_hal_call_app_status_hook(Error, shutdown_hook, i);
+ }
+ }
+ }
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#ifdef EE_AS_RPC__
+ {
+ register EE_TYPESPIN spinlock_id = EE_as_core_spinlocks[EE_CURRENTCPU];
+
+ /* Check global ShutdownAllCores flag in a critical section */
+ EE_hal_spin_in(spinlock_id);
+
+ if (EE_as_shutdown_all_cores_flag != 0U) {
+ /* Release this core spinlock */
+ EE_hal_spin_out(spinlock_id);
+
+ /* [OS587]: Before calling the global ShutdownHook, all cores shall be
+ * synchronized. (BSW4080007) */
+ EE_hal_sync_barrier(&EE_shutdownos_barrier, &EE_as_shutdown_mask);
+ } else {
+ /* Remove this core from the waiting mask: this core has already reached
+ * the barrier */
+ EE_as_shutdown_mask &= (~((EE_UREG)1U << EE_CURRENTCPU));
+
+ /* Release this core spinlock */
+ EE_hal_spin_out(spinlock_id);
+ }
+ }
+#endif /* EE_AS_RPC__ */
+
+ /* [OS588]: The global ShutdownHook shall be called on all cores.
+ * (BSW4080007) */
+ EE_oo_call_ShutdownHook(Error);
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SHUTDOWNOS);
+
+ EE_oo_shutdown();
+}
+
+void EE_oo_ShutdownOS(StatusType Error)
+{
+ /* Primitive Lock Procedure */
+ EE_OS_FOREVER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_SHUTDOWNOS);
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* ShutdownOS is callable by Task and ISR2, ErrorHook and StartupHook */
+ if (EE_oo_check_disableint_error()) {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SHUTDOWNOS);
+ } else if ((EE_as_execution_context > ErrorHook_Context) &&
+ (EE_as_execution_context != StartupHook_Context)) {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SHUTDOWNOS);
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* [OS054]: The Operating System module shall ignore calls to ShutdownOS()
+ * from non-trusted OS-Applications. */
+ if (EE_as_Application_ROM[EE_as_active_app].Mode != EE_MEMPROT_TRUST_MODE) {
+ EE_ORTI_set_service_out(EE_SERVICETRACE_SHUTDOWNOS);
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ */
+ {
+ /* This won't never return... */
+ EE_oo_ShutdownOS_internal(Error);
+ }
+
+ return;
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __PRIVATE_SHUTDOWNOS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_startos.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_startos.c
new file mode 100644
index 0000000..ca1f215
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_startos.c
@@ -0,0 +1,531 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_startos.c,v 1.5 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/*
+ * ORTI variables
+ */
+#if (defined(RTDRUID_CONFIGURATOR_NUMBER)) \
+ && (RTDRUID_CONFIGURATOR_NUMBER >= RTDRUID_CONFNUM_NO_ORTI_VARS)
+
+#ifdef __OO_ORTI_SERVICETRACE__
+/* This shall belong to ee_api_bss the section mapping is done inside header
+ * file to be portable to DIAB compiler */
+volatile EE_UINT8 EE_ORTI_servicetrace;
+#endif /* __OO_ORTI_SERVICETRACE__ */
+
+#ifdef __OO_ORTI_LASTERROR__
+StatusType EE_ORTI_lasterror;
+#endif /* __OO_ORTI_LASTERROR__ */
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_START_SEC_CODE
+/* Put the following variables in ee_kernel_bss, needed for EE_oo_start_os */
+#define OS_START_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#ifdef __OO_ORTI_PRIORITY__
+EE_TYPEPRIO EE_ORTI_th_priority[EE_MAX_TASK];
+#endif /* __OO_ORTI_PRIORITY__ */
+
+#endif /* RTDRUID_CONFIGURATOR_NUMBER */
+
+#ifdef __OO_ORTI_RUNNINGISR2__
+volatile EE_ORTI_runningisr2_type EE_ORTI_runningisr2;
+#endif /* __OO_ORTI_RUNNINGISR2__ */
+
+
+
+
+
+/* StartOS
+ *
+ * - called to start the operating system in a specific Application
+ * mode
+ * - it does not need to return to the caller
+ */
+#ifndef __PRIVATE_STARTOS__
+
+#ifdef __OO_AUTOSTART_TASK__
+
+static EE_TID compute_task_tid(const EE_TID task_id_vec[],
+ EE_UREG t);
+static void EE_oo_autostart_tasks(AppModeType Mode);
+
+
+static EE_TID compute_task_tid(const EE_TID task_id_vec[],
+ EE_UREG t)
+{
+ EE_TID res = EE_NIL;
+
+ if (task_id_vec != NULL) {
+ res = task_id_vec[t];
+ }
+
+ return res;
+}
+
+static void EE_oo_autostart_tasks(AppModeType Mode)
+{
+ register EE_UREG ntask, t;
+
+ ntask = EE_oo_autostart_task_data[Mode].nt;
+ for (t = 0U; t < ntask; t++) {
+ /* Insert the TID in Ready Queue */
+ EE_TID tid = compute_task_tid(*EE_oo_autostart_task_data[Mode].task, t);
+ EE_oo_task_in_ready_queue(tid);
+ }
+}
+#else /* __OO_AUTOSTART_TASK__ */
+#define EE_oo_autostart_tasks(Mode) ((void)0)
+#endif /* __OO_AUTOSTART_TASK__ */
+
+#ifdef __OO_AUTOSTART_ALARM__
+
+static EE_TYPEALARM compute_alarm_id(const EE_TYPEALARM alarm_id_vec[],
+ EE_UREG t);
+
+static void EE_oo_autostart_alarms(AppModeType Mode);
+
+static EE_TYPEALARM compute_alarm_id(const EE_TYPEALARM alarm_id_vec[],
+ EE_UREG t)
+{
+ EE_TYPEALARM res = (EE_TYPEALARM)EE_NIL;
+
+ if (alarm_id_vec != NULL) {
+ res = alarm_id_vec[t];
+ }
+
+ return res;
+}
+
+static void EE_oo_autostart_alarms(AppModeType Mode)
+{
+ register EE_UREG nalarm, t;
+
+ nalarm = EE_oo_autostart_alarm_data[Mode].na;
+ for (t = 0U; t < nalarm; t++) {
+ EE_TYPEALARM alarm_temp = compute_alarm_id(
+ *EE_oo_autostart_alarm_data[Mode].alarm, t);
+ EE_oo_handle_rel_counter_object_insertion(alarm_temp,
+ EE_oo_autostart_alarm_increment[alarm_temp],
+ EE_oo_autostart_alarm_cycle[alarm_temp]);
+ }
+}
+#else /* __OO_AUTOSTART_ALARM__ */
+#define EE_oo_autostart_alarms(Mode) ((void)0)
+#endif /* __OO_AUTOSTART_ALARM__ */
+
+#ifdef EE_AS_AUTOSTART_SCHEDULETABLE__
+
+static const EE_as_schedule_table_autostart_data *
+get_schedule_table_autostart_data(const EE_as_schedule_table_autostart_data
+ scheduletable_data[],
+ EE_UREG t)
+{
+ const EE_as_schedule_table_autostart_data *res = NULL;
+
+ if (scheduletable_data != NULL) {
+ res = &scheduletable_data[t];
+ }
+
+ return res;
+}
+
+static void EE_oo_autostart_schedule_tables(AppModeType Mode)
+{
+ register EE_UREG n, t;
+
+ n = EE_as_schedule_table_autostart[Mode].n;
+ for (t = 0U; t < n; t++) {
+ const EE_as_schedule_table_autostart_data *sched_data_ref =
+ get_schedule_table_autostart_data(EE_as_schedule_table_autostart[Mode].
+ autostart_schedule_tables, t);
+ if (sched_data_ref != NULL) {
+ switch (sched_data_ref->start_kind) {
+ case EE_ST_START_ABSOLUTE:
+ EE_as_StartScheduleTableAbs(sched_data_ref->scheduletable_id,
+ sched_data_ref->start_value);
+ break;
+ case EE_ST_START_RELATIVE:
+ EE_as_StartScheduleTableRel(sched_data_ref->scheduletable_id,
+ sched_data_ref->start_value);
+ break;
+ case EE_ST_START_SYNCHRON:
+ /* XXX: Not implement yet */
+ /* EE_as_StatusType StartScheduleTableSynchron(sched_data_ref->
+ * scheduletable_id) */
+ break;
+ default:
+ /* THIS CANNOT HAPPENS, CONFIGURATION ERROR */
+ break;
+ }
+ }
+ }
+}
+#else /* EE_AS_AUTOSTART_SCHEDULETABLE__ */
+#define EE_oo_autostart_schedule_tables(Mode) ((void)0)
+#endif /* EE_AS_AUTOSTART_SCHEDULETABLE__ */
+
+#if (defined(__OO_AUTOSTART_TASK__)) || (defined(__OO_AUTOSTART_ALARM__)) \
+ || (defined(EE_AS_AUTOSTART_SCHEDULETABLE__))
+
+static void EE_oo_autostart_os(AppModeType Mode);
+
+static void EE_oo_autostart_os(AppModeType Mode)
+{
+ if (Mode < EE_MAX_APPMODE) {
+ EE_oo_autostart_tasks(Mode);
+ EE_oo_autostart_alarms(Mode);
+ EE_oo_autostart_schedule_tables(Mode);
+ }
+}
+#else /* __OO_AUTOSTART_TASK__ || __OO_AUTOSTART_ALARM__ ||\
+ * EE_AS_AUTOSTART_SCHEDULETABLE__ */
+#define EE_oo_autostart_os(Mode) ((void)0);
+#endif /* __OO_AUTOSTART_TASK__ || __OO_AUTOSTART_ALARM__ ||\
+ * EE_AS_AUTOSTART_SCHEDULETABLE__ */
+
+#ifdef __OO_HAS_STARTUPHOOK__
+static void EE_oo_call_StartupHook(void);
+static void EE_oo_call_StartupHook(void)
+{
+ StartupHook();
+}
+#else /* __OO_HAS_STARTUPHOOK__ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_StartupHook(void);
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_call_StartupHook(void)
+{
+}
+#endif /* __OO_HAS_STARTUPHOOK__ */
+
+/** @brief Flag that the OS is started */
+EE_UREG volatile EE_oo_started;
+
+#if defined(__OO_STARTOS_OLD__)
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_start_os(void);
+
+/*
+ * If __OO_STARTOS_OLD__ is defined, the StartOS() returns,
+ * (this is the old behaviour before the Autosar compliance).
+ */
+__INLINE__ void __ALWAYS_INLINE__ EE_oo_start_os(void)
+{
+}
+#else /* __OO_STARTOS_OLD__ */
+static void EE_oo_start_os(void);
+
+
+/*
+ * If __OO_STARTOS_OLD__ is not defined the system behaves
+ * like Autosar requires: infinite loop (do not return).
+ * This is the standard solution.
+ */
+static void EE_oo_start_os(void)
+{
+ /*
+ * This assignment prevents from MISRA 14.2/FlexeLint 522:
+ * lacks side-effects
+ */
+ EE_oo_started = 1U;
+
+ for (;; ) {
+ ;
+ }
+}
+#endif /* __OO_STARTOS_OLD__ && !__MSRP__ */
+
+#if (!defined(EE_MASTER_CPU))
+#if (!defined(EE_CURRENTCPU)) || (EE_CURRENTCPU == 0)
+/* Used as short-cut for previous condition */
+#define EE_MASTER_CPU
+#endif /* EE_CURRENTCPU == 0 */
+#endif /* !EE_MASTER_CPU */
+
+StatusType EE_oo_StartOS(AppModeType Mode)
+{
+#if (defined(__MSRP__)) && (!defined(EE_AS_MULTICORE_NO_SYNC))
+ /* The following contains cores application modes */
+ extern AppModeType volatile EE_as_os_application_mode[];
+ /* Mask for Autosar cores started */
+ extern EE_UREG volatile EE_as_core_mask;
+ /* Index used to cycle on cores an OS-Applications */
+ register EE_UREG i;
+ /* Hold the value of application mode to be checked */
+ register AppModeType mode_to_check = DONOTCARE;
+#endif /* __MSRP__ && !EE_AS_MULTICORE_NO_SYNC */
+ /* Ready Queue Head Index */
+ register EE_TID rq;
+ /* Error Value */
+ register StatusType ev = E_OK;
+
+ /* Primitive Lock Procedure */
+ register EE_FREG const flag = EE_hal_begin_nested_primitive();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_STARTOS);
+
+ /* Check if this is the first time that I call StartOS */
+ if (EE_oo_started != 0U) {
+ ev = E_OS_STATE;
+ } else {
+#if (defined(OO_CPU_HAS_STARTOS_ROUTINE)) && (defined(EE_MASTER_CPU))
+ /* the CPU initialization can return an error; 0 if all ok */
+ if (EE_cpu_startos() != EE_FALSE) {
+ ev = E_OS_SYS_INIT;
+ } else
+#endif /* OO_CPU_HAS_STARTOS_ROUTINE && EE_MASTER_CPU */
+ {
+ /* Initialize ORTI variables, so the debugger can see their
+ * initial value */
+ EE_ORTI_set_runningisr2((EE_ORTI_runningisr2_type)NULL);
+
+ /* Multicore Startup */
+#if (defined(__MSRP__)) && (!defined(EE_AS_MULTICORE_NO_SYNC))
+ /* [OS609]: If StartOS is called with the AppMode "DONOTCARE" the
+ * application mode of the other core(s) (differing from "DONOTCARE")
+ * shall be used. (BSW4080006) */
+ /* [OS610]: At least one core shall define an AppMode other than
+ * "DONOTCARE". (BSW4080006) */
+
+ /* It is not allowed to call StartOS on Cores that are not started by
+ * StartCore AUTOSAR API.
+ * "In Multi-Core configurations, each slave core that is used by AUTOSAR
+ * MUST be activated before StartOS is entered on the core".
+ * XXX: The condition that a core enter in StartOS even if the core has not
+ * been started by a call to StartCore AUTOSAR API is
+ * "unspecified behavior" (See Paragraph 7.9.6 Cores which are not
+ * controlled by the AUTOSAR OS on AUSTOSAR specification
+ * (v 4.0 rev 3.0)).
+ * So I decide to handle it jumping in an endless loop. */
+ /* TODO: maybe we need a special macro to identify the master core */
+#if (defined(EE_CURRENTCPU)) && (EE_CURRENTCPU != 0)
+ if (((EE_as_core_mask & ((EE_UREG)1U << EE_CURRENTCPU)) == 0U)) {
+ /* Enter in an endless loop if it happened */
+ EE_oo_start_os();
+ }
+#endif /* EE_CURRENTCPU != 0 */
+
+ /* Set on current CPU position the actual application mode */
+ EE_as_os_application_mode[EE_CURRENTCPU] = Mode;
+
+ /* [OS580]: All cores that belong to the AUTOSAR system shall be
+ * synchronized within the StartOS before the global StartupHook is
+ * called. (BSW4080006) */
+ /* [OS581]: The global StartupHook shall be called on all cores
+ * immediately after the first synchronization point. (BSW4080006) */
+
+ /* Synchronize Cores in Startup. Extracted from AUSTOSAR 4.0 rev 3
+ * Specification paragraph 7.9.4 Multi-Core start-up concept:
+ * "This release of the AUTOSAR specification does not support timeouts
+ * during the synchronization phase. Cores that are activated with
+ * StartCore but do not call StartOS may cause the system to hang.
+ * It is in the responsibility of the integrator to avoid such
+ * behavior." */
+ EE_hal_sync_barrier(&EE_startos_before_hook_barrier, &EE_as_core_mask);
+
+ /* Initialize Slaves Hardware after First syncronization point:
+ * This assure that all the Master Initializations have been done. */
+#if defined(EE_CURRENTCPU) && (EE_CURRENTCPU != 0)
+#if defined(OO_CPU_HAS_STARTOS_ROUTINE)
+ /* the CPU initialization can return an error; 0 if all ok */
+ if (EE_cpu_startos()) {
+ /* Enter in an endless loop if it happened */
+ EE_oo_start_os();
+ }
+#endif /* OO_CPU_HAS_STARTOS_ROUTINE */
+#endif /* EE_CURRENTCPU != 0 */
+ /* [OS608]: If more than one core calls StartOS with an AppMode other than
+ * "DONOTCARE", the AppModes shall be the same. StartOS shall check this
+ * at the first synchronization point. In case of violation, StartOS
+ * shall not start the scheduling, shall not call any StartupHooks,
+ * and shall enter an endless loop on every core. (BSW4080006) */
+
+ for (i = 0U; i < (EE_UREG)EE_MAX_CPU; ++i) {
+ register AppModeType current_mode = EE_as_os_application_mode[i];
+ if (current_mode != DONOTCARE) {
+ if (mode_to_check == DONOTCARE) {
+ mode_to_check = current_mode;
+ } else if (mode_to_check != current_mode) {
+ /* Error condition specified by OS608 requirement: enter in an
+ * endless loop */
+ EE_oo_start_os();
+ } else {
+ /* Empty else statement to comply with MISRA 14.10 */
+ }
+ }
+ }
+
+ if (mode_to_check != DONOTCARE) {
+ /* Set mode for this core as mode_to_check */
+ Mode = mode_to_check;
+ } else {
+ /* XXX: It is not specified how to handle the condition that no cores
+ * defines an AppMode different from DONOTCARE. I choose to handle it
+ * using OSDEFAULTAPPMODE */
+ Mode = OSDEFAULTAPPMODE;
+ }
+#endif /* __MSRP__ && !EE_AS_MULTICORE_NO_SYNC */
+
+ /* Set EE_ApplicationMode for this core */
+ EE_ApplicationMode = Mode;
+
+ /* Set the StartOS flag after all error checks and before return to user
+ * code in StartupHook */
+ EE_oo_started = 1U;
+
+#if (defined(__OO_HAS_STARTUPHOOK__)) || (defined(__OO_AUTOSTART_TASK__)) \
+ || (defined(__OO_AUTOSTART_ALARM__)) || (defined(EE_AS_AUTOSTART_SCHEDULETABLE__))
+
+ /* Set the context execution at StartupHook */
+ EE_as_set_execution_context(StartupHook_Context);
+ EE_oo_call_StartupHook();
+ /* Set the context execution at Kernel */
+ EE_as_set_execution_context(Kernel_Context);
+
+ EE_oo_autostart_os(Mode);
+#endif /* __OO_HAS_STARTUPHOOK__ || __OO_AUTOSTART_TASK__ ||
+ * __OO_AUTOSTART_ALARM__ || EE_AS_AUTOSTART_SCHEDULETABLE__ */
+
+#ifdef EE_AS_OSAPPLICATIONS__
+ /* [OS582]: The OS-Application-specific StartupHooks shall be called
+ * after the global StartupHook but only on the cores to which the
+ * OS-Application is bound. (BSW4080006, BSW4080008) */
+ {
+ register ApplicationType i;
+ /* Set the context execution at StartupHook Context */
+ EE_as_set_execution_context(StartupHook_Context);
+ /* ApplID 0 is always reserved by the Kernel */
+ for (i = 1U; i < EE_MAX_APP; ++i) {
+ register EE_HOOKTYPE startup_hook = EE_as_Application_startuphook[i];
+ if (startup_hook != 0U) {
+ /* [OS226] The Operating System module shall execute an
+ * application-specific startup hook with the access rights of the
+ * associated OS-Application. */
+ EE_hal_call_app_hook(startup_hook, i);
+ }
+ }
+ /* Set the context execution at Kernel */
+ EE_as_set_execution_context(Kernel_Context);
+ }
+#endif /* EE_AS_OSAPPLICATIONS__ */
+
+#if (defined(__MSRP__)) && (!defined(EE_AS_MULTICORE_NO_SYNC))
+ /* [OS579]: All cores that belong to the AUTOSAR system shall be
+ * synchronized within the StartOS function before the scheduling is
+ * started and after the global StartupHook is called.
+ * (BSW4080001, BSW4080006) */
+ EE_hal_sync_barrier(&EE_startos_before_scheduling_barrier,
+ &EE_as_core_mask);
+#endif /* __MSRP__ && !EE_AS_MULTICORE_NO_SYNC */
+
+ /* Check if there is a preemption.
+ * This code is optimized for this case, but for code readability we
+ * could have been used EE_oo_preemption_point too. */
+ rq = EE_rq_queryfirst();
+ if (rq != EE_NIL) {
+ /* Get the internal resource */
+ EE_sys_ceiling |= EE_th_dispatch_prio[rq];
+ /* Put the task in running state */
+ EE_th_status[rq] = RUNNING;
+
+ EE_ORTI_set_th_eq_dispatch_prio(rq);
+
+ /* [SWS_Os_00469]: The Operating System module shall start an
+ * OsTaskTimeFrame when a task is activated successfully.
+ * (SRS_Os_11008) */
+ /* Enable the inter-arrival for the stacking TASK */
+ (void)EE_as_tp_handle_interarrival(EE_AS_TP_ID_FROM_TASK(rq));
+
+ /* "Press TP start for the first time" for this new activation of the
+ * TASK */
+ EE_as_tp_active_start_on_TASK_stacking(rq);
+
+ /* Since we are into the StartOS, the task was NOT previously on
+ * the stack... (we do not have to check the was stacked field)
+ * So the code is equal for basic and extended task
+ * (all classes: BCC1, BCC2, ECC1, ECC2 are equal here)
+ * Look at EE_oo_run_next_task in ee_internal.h to see the usual
+ * differences. */
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ } else {
+ /* Prepare to go in IDLE Loop */
+ EE_as_set_execution_context(Idle_Context);
+ EE_as_tp_active_start_idle();
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTOS);
+ /* In Case of StartOS first call that return (this means:
+ * __OO_STARTOS_OLD__ enabled) I have to enable IRQ. */
+ /* In any case enable IRQ before endless IDLE loop */
+ EE_hal_enableIRQ();
+ /* If __OO_STARTOS_OLD__ is defined -> return, otherwise endless cycle. */
+ EE_oo_start_os();
+ }
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_StartOS(Mode, ev);
+ EE_ORTI_set_service_out(EE_SERVICETRACE_STARTOS);
+ EE_hal_end_nested_primitive(flag);
+ }
+
+ return ev;
+}
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+/* Put the following code in ee_kernel_text */
+#define OS_STOP_SEC_CODE
+/* Put the following variables in ee_kernel_bss */
+#define OS_STOP_SEC_VAR_NOINIT
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif /* __PRIVATE_STARTOS__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_terminat.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_terminat.c
new file mode 100644
index 0000000..6da6445
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_terminat.c
@@ -0,0 +1,142 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_terminat.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* TerminateTask:
+ * - The task is moved from the running state to the suspended state
+ * - automatic release of internal resource
+ * - no check for pending resources left by the task
+ * - Rescheduling is issued
+ * - returns (only extended state)
+ * E_OS_RESOURCE if the task still occupy resources
+ * E_OS_CALLLEVEL if called at interrupt level
+ */
+
+#ifndef __PRIVATE_TERMINATETASK__
+StatusType EE_oo_TerminateTask(void)
+{
+ /* Error Value */
+ register StatusType ev;
+ /* Current TID */
+ register EE_TID current;
+
+ /* Primitive Lock Procedure */
+ EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_TERMINATETASK);
+
+ EE_as_monitoring_the_stack();
+
+ current = EE_stk_queryfirst();
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(EE_SERVICE_PROTECTION__))
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* check for a call at interrupt level
+ * This must be the FIRST Check!!!
+ */
+ if ((EE_hal_get_IRQ_nesting_level() != 0U)
+#if !defined(EE_SERVICE_PROTECTION__)
+ ) /* If EE_SERVICE_PROTECTION__ is not defined the succeeding
+ * check is always FALSE, hence it is not needed */
+#else
+ || (EE_as_get_execution_context() > TASK_Context))
+#endif
+ {
+ ev = E_OS_CALLEVEL;
+ } else
+#endif /* __OO_EXTENDED_STATUS__ || EE_SERVICE_PROTECTION__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+#ifndef __OO_NO_RESOURCES__
+ /* check for busy resources */
+ if (EE_th_resource_last[current] != EE_UREG_MINUS1) {
+ ev = E_OS_RESOURCE;
+ } else
+#endif /* __OO_NO_RESOURCES__ */
+
+#ifdef EE_AS_USER_SPINLOCKS__
+ /* [OS612]: In extended status TerminateTask / ChainTask shall return with an
+ * error (E_OS_SPINLOCK), which can be evaluated in the application.
+ * (BSW4080021) */
+ if (EE_as_has_spinlocks_locked(current)) {
+ ev = E_OS_SPINLOCK;
+ } else
+#endif /* EE_AS_USER_SPINLOCKS__ */
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+#ifndef __OO_NO_CHAINTASK__
+ EE_th_terminate_nextask[current] = EE_NIL;
+#endif /* __OO_NO_CHAINTASK__ */
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_service(OSServiceId_TerminateTask, ev);
+ } else {
+ /* The following won't never return */
+ EE_ORTI_set_service_out(EE_SERVICETRACE_TERMINATETASK);
+ EE_hal_terminate_task(current);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_TERMINATETASK);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+#endif /* __PRIVATE_TERMINATETASK__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_thendin.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_thendin.c
new file mode 100644
index 0000000..9b851c3
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_thendin.c
@@ -0,0 +1,193 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_thendin.c,v 1.3 2006/01/24 10:20:20 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_THREAD_END_INSTANCE__
+
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+static EE_BIT EE_thread_rnact_max(EE_TID current)
+{
+ return (EE_th_rnact[current] == EE_th_rnact_max[current]) ? 1U : 0U;
+}
+#else /* __OO_BCC2__ || __OO_ECC2__ */
+#define EE_thread_rnact_max(current) (1U)
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+static void EE_thread_endcycle_next(void);
+
+#if (defined(__OO_ECC1__)) || (defined(__OO_ECC2__))
+static void EE_thread_endcycle_next(void)
+{
+ register EE_TID nexttid;
+
+ nexttid = EE_rq2stk_exchange();
+ if (EE_th_waswaiting[nexttid]) {
+ EE_th_waswaiting[nexttid] = EE_FALSE;
+ EE_oo_call_PreTaskHook();
+ EE_hal_endcycle_stacked(nexttid);
+ } else {
+ EE_hal_endcycle_ready(nexttid);
+ }
+ /* Remember: after hal_endcycle_XXX there MUST be NOTHING!!! */
+}
+#else /* __OO_ECC1__ || __OO_ECC2__ */
+static void EE_thread_endcycle_next(void)
+{
+ EE_hal_endcycle_ready(EE_rq2stk_exchange());
+ /* Remember: after hal_endcycle_XXX there MUST be NOTHING!!! */
+}
+#endif /* __OO_ECC1__ || __OO_ECC2__ */
+
+void EE_thread_end_instance(void)
+{
+ EE_TID current, rqfirst;
+ EE_TID ntask;
+
+ current = EE_stk_queryfirst();
+
+ EE_oo_call_PostTaskHook();
+
+ /* [SWS_Os_00473] The Operating System module shall reset a task’s
+ * OsTaskExecutionBudget on a transition to the SUSPENDED or WAITING states.
+ * (SRS_Os_11008) */
+ /* Reset ALL TP Budgets, just in case */
+ EE_as_tp_active_reset_budgets();
+
+ /* Reset ISRs counters */
+ EE_oo_IRQ_disable_count = 0U;
+
+ /* Increase the remaining activations...*/
+ EE_th_rnact[current]++;
+
+#ifndef __OO_NO_CHAINTASK__
+ /* If we called a ChainTask,
+ * EE_th_terminate_nextask[current] != NIL */
+ ntask = EE_th_terminate_nextask[current];
+#else /* __OO_NO_CHAINTASK__ */
+ ntask = EE_NIL;
+#endif /* __OO_NO_CHAINTASK__ */
+
+ /* The task state switch from STACKED TO READY because it end its
+ * instance. Note that status=READY and
+ * rnact==maximum number of pending activations ==>> the task is
+ * SUSPENDED!!! */
+#if (defined(__OO_BCC2__)) || (defined(__OO_ECC2__))
+ if ((1U == EE_thread_rnact_max(current)) || (current == ntask)) {
+ EE_th_status[current] = SUSPENDED;
+ } else {
+ EE_th_status[current] = READY;
+ }
+#else /* __OO_BCC2__ || __OO_ECC2__ */
+ EE_th_status[current] = SUSPENDED;
+#endif /* __OO_BCC2__ || __OO_ECC2__ */
+
+ /* Reset the thread priority bit in the system_ceiling */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+
+ EE_ORTI_set_th_priority(current, 0U);
+
+ /* Extract the TASK from the stk queue and return the new head */
+ current = EE_stk_getfirst();
+
+#ifndef __OO_NO_CHAINTASK__
+ /* If we called a ChainTask,
+ * EE_th_terminate_nextask[current] != NIL */
+ if (ntask != EE_NIL) {
+ /* See also activate.c
+ * Put the task in the ready state:
+ * - if the task is basic/BCC1 or extended it can be here only because
+ * it had rnact=1 before the call, and so it is in suspended state
+ * - if the task is basic/BCC2 it can be that it is ready or
+ * running. In that case we have to check and queue it anyway */
+ EE_oo_set_th_status_ready(ntask);
+
+ /* insert the task in the ready queue */
+ EE_rq_insert(ntask);
+ }
+#endif /* __OO_NO_CHAINTASK__ */
+
+ /* Check if there is to schedule a ready thread or pop a preempted thread */
+ rqfirst = EE_rq_queryfirst();
+ if (rqfirst == EE_NIL) {
+ /* No threads in the ready queue, return to the preempted TASK
+ * (maybe Idle) */
+ if (current != EE_NIL) {
+ EE_th_status[current] = RUNNING;
+ EE_oo_call_PreTaskHook();
+ /* Enable the TASK Timing Protection Set */
+ EE_as_tp_active_set_from_TASK(current);
+ } else {
+ /* We are switching back to the Idle loop */
+ EE_as_set_execution_context(Idle_Context);
+ EE_as_tp_active_start_idle();
+ }
+ EE_hal_endcycle_stacked(current);
+ } else if (EE_sys_ceiling >= EE_th_ready_prio[rqfirst]) {
+ /* We have to schedule an interrupted thread (already on the stack!!!) */
+ EE_th_status[current] = RUNNING;
+ EE_oo_call_PreTaskHook();
+
+ /* Enable the TASK Timing Protection Set */
+ EE_as_tp_active_set_from_TASK(current);
+ /* Prepare to Context SWITCH, It doesn't do the switch by it self. */
+ EE_hal_endcycle_stacked(current);
+ } else {
+ /* We have to schedule a ready thread */
+ EE_th_status[rqfirst] = RUNNING;
+ EE_sys_ceiling |= EE_th_dispatch_prio[rqfirst];
+
+ EE_ORTI_set_th_eq_dispatch_prio(rqfirst);
+
+ /* "Press TP start for the first time" for this new activation or release
+ * from wait of the TASK */
+ EE_as_tp_active_start_on_TASK_stacking(rqfirst);
+
+ /* Prepare to Context SWITCH, It doesn't do the switch by it self. */
+ EE_thread_endcycle_next();
+ }
+ /* Remember: after hal_endcycle_XXX there MUST be NOTHING!!! */
+}
+#endif /* __PRIVATE_THREAD_END_INSTANCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tnterm.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tnterm.c
new file mode 100644
index 0000000..d23912b
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tnterm.c
@@ -0,0 +1,89 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2011 Errico Guidieri
+ */
+
+#include "ee_internal.h"
+
+/* EE_thread_not_terminated:
+ * - This is the function that is called if task body doesn't call correctly
+ * TerminateTask
+ * Needed tuo fulfill Autosar OS software requirements OS052 OS069 OS070 OS239
+ */
+
+#ifndef PRIVATE_THREANTERMINATED
+void EE_thread_not_terminated(void)
+{
+ register EE_TID current;
+
+ /* IRQ disabling for primitive atomicity (It doesn't make sense use
+ * EE_hal_begin_nested_primitive because at the end of the function I won't
+ * call EE_hal_end_nested_primitive) */
+ EE_hal_disableIRQ();
+
+ current = EE_stk_queryfirst();
+
+ /* [OS069]: If a task returns from its entry function without making a
+ * TerminateTask() or ChainTask() call AND the error hook is configured,
+ * the Operating System shall call the ErrorHook()
+ * (this is done regardless of whether the task causes other errors,
+ * e.g. E_OS_RESOURCE) with status E_OS_MISSINGEND before the task leaves
+ * the RUNNING state. */
+ EE_ORTI_set_lasterror(E_OS_MISSINGEND);
+ EE_oo_notify_error_service(OSId_TaskBody, E_OS_MISSINGEND);
+
+ /* [OS070]: If a task returns from the entry function without making a
+ * TerminateTask() or ChainTask() call and still holds OSEK Resources,
+ * the Operating System shall release them. */
+ (void)EE_oo_release_all_resources(current);
+
+ /* Force spinlocks release */
+#ifdef EE_AS_USER_SPINLOCKS__
+ (void)EE_as_release_all_spinlocks(current);
+#endif /* EE_AS_USER_SPINLOCKS__ */
+
+ /* [OS052], [OS239]: terminate task + call PostTaskHook + ISRs counters reset
+ * in EE_thread_end_instance. Interrupts enabling is done by
+ * EE_std_run_task_code (cpu/common ee_context.c) */
+ EE_hal_terminate_task(current);
+}
+#endif /* PRIVATE_THREANTERMINATED */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tstub.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tstub.c
new file mode 100644
index 0000000..956e5c4
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_tstub.c
@@ -0,0 +1,72 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002-2004 Paolo Gai
+ * CVS: $Id: ee_tstub.c,v 1.1 2005/07/16 12:23:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* TerminateStub:
+ * - This is the function that is called as the "real thread body" of
+ * an OO task.
+ * - This function is not called if a task use only a terminate_task at
+ * the end of the thread. In some architectures, this can lead
+ * to some stack savings...
+ */
+
+#ifndef __PRIVATE_THREADSTUB__
+void EE_oo_thread_stub(void)
+{
+ register EE_TID temp;
+
+ EE_oo_call_PreTaskHook();
+
+ temp = EE_stk_queryfirst();
+
+ EE_hal_terminate_savestk(temp);
+
+ /* NOTE:
+ * It is not specified if at this point the system runs or not
+ * with interrupts disabled.
+ */
+}
+#endif /* __PRIVATE_THREADSTUB__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockallres.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockallres.c
new file mode 100644
index 0000000..1040c28
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockallres.c
@@ -0,0 +1,119 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2011 Errico Guidieri
+ */
+
+#include "ee_internal.h"
+
+/*
+ * Method to Release All Resources locked by a Thread,
+ * used to fulfill AS requirement OS070
+ */
+
+#if ((defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ISR2_RESOURCES__))) \
+ && (!defined(__PRIVATE_RELEASEALLRESOURCE__))
+
+#if 0
+#ifdef __MSRP__
+#warning "MSRP multiprocessor kernel protocol is not completly supported!"
+static void EE_oo_unlock_others(EE_UREG ResID)
+{
+ /* TODO Understand what I need to do for global resources
+ * PSEUDO code:
+ * if(EE_oo_isGlobal(ResID))
+ * EE_hal_spin_out((EE_TYPESPIN)ResID);
+ * but i cannot rely on EE_GLOBAL_MUTEX flag!
+ * EG:
+ * Global resources are going to disappear!
+ */
+}
+#else
+#define EE_oo_unlock_others(ResID) ((void)0)
+#endif
+#endif
+
+EE_UREG EE_oo_release_all_resources(EE_TID tid)
+{
+ /* ALLERT! this method have to be called only inside a critical section
+ * (e.g. interrupt disabled) */
+ register EE_UREG curRes, ResID = EE_UREG_MINUS1;
+
+ curRes = EE_th_resource_last[tid];
+ while (curRes != EE_UREG_MINUS1) {
+ ResID = curRes;
+ /* remove the last entry from the data structure */
+ EE_th_resource_last[tid] =
+ EE_resource_stack[ResID];
+#ifdef __OO_EXTENDED_STATUS__
+ /* free the resource */
+ EE_resource_locked[ResID] = EE_FALSE;
+#endif /* __OO_EXTENDED_STATUS__ */
+ /* TODO choose the fate of global resources */
+#if 0
+ EE_oo_unlock_others(ResID);
+#endif
+
+ curRes = EE_th_resource_last[tid];
+ }
+
+ /* Check if at least one resource have been freed */
+ if (ResID != EE_UREG_MINUS1) {
+ /* Restore the sys-ceiling with the old value from the bottom of the
+ * resource stack */
+ EE_sys_ceiling = EE_resource_oldceiling[ResID];
+
+#ifdef __OO_ISR2_RESOURCES__
+ /* Restore the isr2 prio with the old value from the bottom of the
+ * resource stack */
+ EE_hal_set_int_prio(EE_isr2_oldpriority[ResID]);
+#endif /* __OO_ISR2_RESOURCES__ */
+
+#ifdef __OO_ORTI_PRIORITY__
+ /* Restore the ORTI priority with the old value from the bottom of the
+ * resource stack */
+ EE_ORTI_th_priority[tid] = EE_ORTI_resource_oldpriority[ResID];
+#endif /* __OO_ORTI_PRIORITY__ */
+ }
+ return ResID;
+}
+
+#endif /* __OO_EXTENDED_STATUS__&& !__PRIVATE_RELEASEALLRESOURCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockres.c b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockres.c
new file mode 100644
index 0000000..2387c65
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/oo/src/ee_ulockres.c
@@ -0,0 +1,216 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_ulockres.c,v 1.3 2006/12/03 22:07:50 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+/* ReleaseResource:
+ * - release a resource
+ * - lock/unlock on the same function level
+ * - no point of rescheduling inside critical sections!!!
+ * - returns (only extended state)
+ * E_OS_ID if resource number is invalid
+ * E_OS_ACCESS if resource already locked or interrupt routine
+ * greater than the ceiling priority
+ *
+ * Extended Status: Count for locked resources!!!!
+ */
+
+#ifndef __PRIVATE_RELEASERESOURCE__
+
+StatusType EE_oo_ReleaseResource(ResourceType ResID)
+{
+ /* Error Value */
+ register StatusType ev;
+
+ /* Primitive Lock Variable */
+#if (!defined(__EE_MEMORY_PROTECTION__)) || (defined(__OO_ISR2_RESOURCES__))
+ register EE_FREG flag;
+#endif /* !__EE_MEMORY_PROTECTION__ || __OO_ISR2_RESOURCES__ */
+#ifdef __MSRP__
+ register EE_UREG isGlobal;
+#endif /* __MSRP__ */
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ISR2_RESOURCES__)) \
+ || (defined(__OO_ORTI_PRIORITY__))
+ register EE_TID current = EE_stk_queryfirst();
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ISR2_RESOURCES__ ||
+ * __OO_ORTI_PRIORITY__ */
+ /* To cache inside task info */
+ register EE_TYPEBOOL inside_task = (EE_hal_get_IRQ_nesting_level() == 0U);
+ /* Primitive Lock Procedure */
+ EE_OS_ENTER_CRITICAL_SECTION();
+
+ EE_ORTI_set_service_in(EE_SERVICETRACE_RELEASERESOURCE);
+
+ EE_as_monitoring_the_stack();
+
+#ifdef __MSRP__
+ isGlobal = EE_oo_isGlobal(ResID);
+ ResID = ResID & ~EE_GLOBAL_MUTEX;
+#endif /* __MSRP__ */
+
+#ifdef __OO_ISR2_RESOURCES__
+ /* If actually we are inside an ISR2 get the fake TID to access stack */
+ if (inside_task == EE_FALSE) {
+ current = EE_oo_get_ISR2_TID();
+ }
+#endif /* __OO_ISR2_RESOURCES__ */
+
+#ifdef EE_SERVICE_PROTECTION__
+ /* [OS093]: If interrupts are disabled/suspended by a Task/OsIsr and the
+ * Task/OsIsr calls any OS service (excluding the interrupt services)
+ * then the Operating System shall ignore the service AND shall return
+ * E_OS_DISABLEDINT if the service returns a StatusType value. */
+ /* [OS088]: If an OS-Application makes a service call from the wrong context
+ * AND is currently not inside a Category 1 ISR the Operating System module
+ * shall not perform the requested action (the service call shall have no
+ * effect), and return E_OS_CALLEVEL (see [12], section 13.1) or the
+ * "invalid value" of the service. (BSW11009, BSW11013) */
+ /* ReleaseResource is callable by Task and ISR2 */
+ if (EE_as_execution_context > ISR2_Context) {
+ ev = E_OS_CALLEVEL;
+ } else if (EE_oo_check_disableint_error()) {
+ ev = E_OS_DISABLEDINT;
+ } else
+#endif /* EE_SERVICE_PROTECTION__ */
+
+#if (defined(EE_AS_OSAPPLICATIONS__)) && (defined(EE_SERVICE_PROTECTION__))
+ /* no comparison for ResID < 0, the type is unsigned! */
+ if (ResID >= EE_MAX_RESOURCE) {
+ ev = E_OS_ID;
+ } else if (EE_RESOURCE_ACCESS_ERR(ResID, EE_as_active_app)) {
+ ev = E_OS_ACCESS;
+ } else
+#elif defined(__OO_EXTENDED_STATUS__)
+ /* no comparison for ResID < 0, the type is unsigned! */
+ if (ResID >= EE_MAX_RESOURCE) {
+ ev = E_OS_ID;
+ } else
+#endif /* EE_AS_OSAPPLICATIONS__ || E_SERVICE_PROTECTION__ ||
+ * __OO_EXTENDED_STATUS__ */
+
+#ifdef __OO_EXTENDED_STATUS__
+ if ((EE_resource_locked[ResID] == EE_FALSE) ||
+ (EE_th_resource_last[current] != ResID)) {
+ ev = E_OS_NOFUNC;
+ } else if ((inside_task != EE_FALSE) && ((current == EE_NIL) ||
+ (EE_th_ready_prio[current] > EE_resource_ceiling[ResID]))) {
+ ev = E_OS_ACCESS;
+ } else
+#ifdef __OO_ISR2_RESOURCES__
+ /* Check if interrupt controller priority is greater than priority
+ * of resource to be realeased */
+ if ((inside_task == EE_FALSE) &&
+ (EE_hal_check_int_prio_if_higher(EE_resource_isr2_priority[ResID]) !=
+ 0U)) {
+ ev = E_OS_ACCESS;
+ } else
+#else /* __OO_ISR2_RESOURCES__ */
+ if (inside_task == EE_FALSE) {
+ ev = E_OS_ACCESS;
+ } else
+#endif /* __OO_ISR2_RESOURCES__ */
+#endif /* __OO_EXTENDED_STATUS__ */
+ {
+ /* Stop TP Lock Budget, if needed */
+ EE_as_tp_active_stop_budget(EE_RESOURCE_LOCK_BUDGET, ResID, EE_FALSE);
+
+#ifdef __OO_ISR2_RESOURCES__
+ /* Restore old ISR2 priority */
+ flag = EE_hal_change_int_prio(EE_isr2_oldpriority[ResID], flag);
+#endif /* __OO_ISR2_RESOURCES__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ISR2_RESOURCES__))
+ /* remove the last entry from the data structure */
+ EE_th_resource_last[current] =
+ EE_resource_stack[EE_th_resource_last[current]];
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ISR2_RESOURCES__ */
+
+#if (defined(__OO_EXTENDED_STATUS__)) || (defined(__OO_ORTI_RES_ISLOCKED__))
+ /* ok, we have to free that resource! */
+ EE_resource_locked[ResID] = EE_FALSE;
+#endif /* __OO_EXTENDED_STATUS__ || __OO_ORTI_RES_ISLOCKED__ */
+
+#ifdef __MSRP__
+ /* if this is a global resource, unlock the others CPUs */
+ if (isGlobal) {
+ EE_hal_spin_out((EE_TYPESPIN)ResID);
+ }
+#endif /* __MSRP__ */
+
+ /* there is no need to store that the resource has no more lockers,
+ * because we inserted an if expression into the ORTI File */
+#if 0
+#ifdef __OO_ORTI_RES_LOCKER_TASK__
+ EE_ORTI_res_locker[ResID] = EE_NIL;
+#endif
+#endif
+
+ EE_sys_ceiling = EE_resource_oldceiling[ResID];
+
+#ifdef __OO_ORTI_PRIORITY__
+ EE_ORTI_th_priority[current] = EE_ORTI_resource_oldpriority[ResID];
+#endif /* __OO_ORTI_PRIORITY__ */
+
+ /* Check if there is a preemption
+ * this test has to be done only if we are inside a task */
+ if (inside_task) {
+ /* we are inside a task */
+ EE_oo_preemption_point();
+ }
+ ev = E_OK;
+ }
+
+ if (ev != E_OK) {
+ EE_ORTI_set_lasterror(ev);
+ EE_oo_notify_error_ReleaseResource(ResID, ev);
+ }
+
+ EE_ORTI_set_service_out(EE_SERVICETRACE_RELEASERESOURCE);
+ EE_OS_EXIT_CRITICAL_SECTION();
+
+ return ev;
+}
+
+#endif /* __PRIVATE_RELEASERESOURCE__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/rn/cfg/cfg.mk
new file mode 100644
index 0000000..21cc1bf
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/cfg/cfg.mk
@@ -0,0 +1,47 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.2 2006/11/03 11:06:09 pj Exp $
+
+ifeq ($(call iseeopt, __RN__), yes)
+EE_SRCS += pkg/kernel/rn/src/ee_rn.c
+EE_SRCS += pkg/kernel/rn/src/ee_rnsend.c
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/doc/readme.txt b/src/bsp/hsm/os/erika2/pkg/kernel/rn/doc/readme.txt
new file mode 100644
index 0000000..54cfe3f
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/doc/readme.txt
@@ -0,0 +1,69 @@
+Remote notification internal documentation
+------------------------------------------
+
+This document was extracted from the document contained in the remote notification files.
+
+Remote Notification
+This library implements the remote notification procedure
+
+Note that the implementation subsumes the Janus Architecture:
+That is, interprocessor interrupts cannot be queued.
+
+Symbols to be defined to enable remote notification:
+__RN__ Remote Notification in general
+__RN_COUNTER__ Counter RN
+__RN_EVENT__ Event RN
+__RN_TASK__ Task RN
+__RN_FUNC__ Func RN
+__RN_SEM__ Sem RN
+
+Often it is useful to hide the fact that we are activating a remote
+or a local task using something like "ActivateTask(mytask);", where
+"mytask" is in general a symbol that refers to the task to activate
+if it is local, or to a remote notification that executes the task
+activation if it is remote. That feature is called "gateway".
+
+The way I chose to implement the gateway is:
+
+Local Tasks: local TID
+Global Tasks: remote notification | EE_REMOTE_TID
+Remote semaphores: a local semaphore must be created. s->first,
+ that usually contains the first task that is blocked on the
+ semaphore, will contain a remote notification number as used for
+ Global tasks. (note that that value is != NIL)
+
+Please note that in that way each remote task can have ONLY ONE
+Gateway. This usually works because basic tasks do not use events, and
+when using extended tasks the user can do both activations and event
+setting
+
+To reduce the time that the system runs with interrupt disabled and
+spin lock used, I decided to use a switch mechanism. Basically, two
+data structures exists. When a remote notification is sent, it is
+queued in one unused data structure pointed by the switch
+variable. When the interprocessor interrupt is raised, the two data
+structures are switched, and the pending notifications are executed in
+an environment that is equivalent to an ISR2. Thanks to the switch,
+the spin lock is released, and the remote processor can continue to
+queue its notifications, that will be executed at the next
+interprocessor interrupt.
+
+Constants to be defined by the application:
+- EE_MAX_RN - the total number of remote notifications
+- EE_MAX_CPU - the total number of CPUs
+
+Types defined in this file that can be modified by the application
+EE_TYPERN - a SIGNED integer - EE_INT8 should be enough in most cases
+EE_TYPERN_SWITCH - a bit field with at least 3 bits
+EE_TYPERN_NOTIFY - a bit field with at least 5 bits
+
+These types should be required by other parts of the Kernel...
+EE_UINT8
+EE_TYPECOUNTER
+EE_TYPEEVENTMASK
+EE_TID
+EE_ADDR
+EE_SEM
+EE_UREG
+EE_TYPESPIN
+
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn.h b/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn.h
new file mode 100644
index 0000000..506cbd1
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn.h
@@ -0,0 +1,237 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003- Paolo Gai
+ * 2011 Bernardo Dal Seno
+ */
+
+
+#ifndef __KERNEL_RN_RN_H__
+#define __KERNEL_RN_RN_H__
+
+#ifdef __MSRP__
+#define EE_MARK_REMOTE_TID(tid) ((tid) + (EE_TID)EE_REMOTE_TID)
+#define EE_UNMARK_REMOTE_TID(tid) ((tid) - (EE_TID)EE_REMOTE_TID)
+#define EE_IS_TID_REMOTE(tid) ((EE_UTID)(tid) & (EE_UTID)EE_REMOTE_TID)
+#else /* __MSRP__ */
+#define EE_MARK_REMOTE_TID(tid) (tid)
+#define EE_UNMARK_REMOTE_TID(tid) (tid)
+#define EE_IS_TID_REMOTE(tid) (0)
+#endif /* __MSRP__ */
+
+#ifdef __RN__
+
+/*
+ * Remote Notification
+ *
+ * This library implements the remote notification procedure
+ *
+ * Symbols to be defined to enable remote notification:
+ * __RN__ Remote Notification in general
+ * __RN_COUNTER__ Counter RN
+ * __RN_EVENT__ Event RN
+ * __RN_TASK__ Task RN
+ * __RN_FUNC__ Func RN
+ * __RN_BIND__ Bind RN, for FRSH
+ *
+ * Constants to be defined by the application:
+ * - EE_MAX_RN - the total number of remote notifications
+ * - EE_MAX_CPU - the total number of CPUs
+ *
+ * Types defined in this file that can be modified by the application
+ * EE_TYPERN - a SIGNED integer - EE_INT8 should be enough in most cases
+ * EE_TYPERN_SWITCH - a bit field with at least 3 bits
+ * EE_TYPERN_NOTIFY - a bit field with at least 5 bits
+ *
+ * These types should be required by other parts of the Kernel...
+ * EE_UINT8
+ * EE_TYPECOUNTER
+ * EE_TYPEEVENTMASK
+ * EE_TID
+ * EE_ADDR
+ * EE_UREG
+ * EE_TYPESPIN
+ *
+ */
+
+/* types */
+
+#ifndef EE_TYPERN
+#define EE_TYPERN EE_SREG
+#endif
+
+#ifndef EE_TYPERN_SWITCH
+#define EE_TYPERN_SWITCH EE_UREG
+#endif
+
+#ifndef EE_TYPERN_NOTIFY
+#define EE_TYPERN_NOTIFY EE_UREG
+#endif
+
+/* CPU numbers start from 0: 0,1,2,... */
+
+/* Notification types */
+#ifdef __RN_COUNTER__
+#define EE_RN_COUNTER ((EE_TYPERN_NOTIFY)1U)
+#endif
+
+#ifdef __RN_EVENT__
+#define EE_RN_EVENT ((EE_TYPERN_NOTIFY)2U)
+#endif
+
+#ifdef __RN_TASK__
+#define EE_RN_TASK ((EE_TYPERN_NOTIFY)4U)
+#endif
+
+#ifdef __RN_FUNC__
+#define EE_RN_FUNC ((EE_TYPERN_NOTIFY)8U)
+#endif
+
+#ifdef __RN_BIND__
+#define EE_RN_BIND ((EE_TYPERN_NOTIFY)16U)
+#endif
+
+#ifdef __RN_UNBIND__
+#define EE_RN_UNBIND ((EE_TYPERN_NOTIFY)32U)
+#endif
+
+
+/* For each RN: The CPU to which the RN is related to */
+#ifdef USE_PRAGMAS
+extern const EE_UINT8 EE_rn_cpu[];
+#else
+extern const EE_UINT8 EE_SHARED_CDATA EE_rn_cpu[];
+#endif
+
+/* For each RN: The type of notification that must be used
+ * initvalue: 0
+ */
+#ifdef USE_PRAGMAS
+extern EE_TYPERN_NOTIFY EE_rn_type[][2];
+#else
+extern EE_TYPERN_NOTIFY EE_SHARED_IDATA EE_rn_type[][2];
+#endif
+
+/* For each RN: The counter number if EE_RN_COUNTER, or -1 */
+#ifdef __RN_COUNTER__
+#ifdef USE_PRAGMAS
+extern const EE_TYPECOUNTER EE_rn_counter[];
+#else
+extern const EE_TYPECOUNTER EE_SHARED_CDATA EE_rn_counter[];
+#endif
+#endif
+
+/* For each RN, 2 times: all 0 (this data structures will contain the
+ * event mask set by rn_send */
+#ifdef __RN_EVENT__
+#ifdef USE_PRAGMAS
+extern EE_TYPEEVENTMASK EE_rn_event[][2];
+#else
+extern EE_TYPEEVENTMASK EE_SHARED_IDATA EE_rn_event[][2];
+#endif
+#endif
+
+/* For each RN: a TID */
+#if defined(__RN_EVENT__) || defined(__RN_TASK__) || defined(__RN_BIND__) || defined(__RN_UNBIND)
+#ifdef USE_PRAGMAS
+extern const EE_TID EE_rn_task[];
+#else
+extern const EE_TID EE_SHARED_CDATA EE_rn_task[];
+#endif
+#endif
+
+/* For each RN: EE_VRES_NIL */
+#if defined(__RN_BIND__)
+#ifdef USE_PRAGMAS
+extern EE_TYPECONTRACT EE_rn_vres[][2];
+#else
+extern EE_TYPECONTRACT EE_SHARED_IDATA EE_rn_vres[][2];
+#endif
+#endif
+
+/* For each RN: a function name if EE_RN_FUNC or -1 */
+#ifdef __RN_FUNC__
+#ifdef USE_PRAGMAS
+extern const EE_ADDR EE_rn_func[];
+#else
+extern const EE_ADDR EE_SHARED_CDATA EE_rn_func[];
+#endif
+#endif
+
+/* For each RN, 2 times: -1 */
+#ifdef USE_PRAGMAS
+extern EE_TYPERN EE_rn_next[][2];
+#else
+extern EE_TYPERN EE_SHARED_IDATA EE_rn_next[][2];
+#endif
+
+/* For each RN: Number of pending notifications. Init value all 0 */
+#ifdef USE_PRAGMAS
+extern EE_UREG EE_rn_pending[][2];
+#else
+extern EE_UREG EE_SHARED_IDATA EE_rn_pending[][2];
+#endif
+
+/* For each CPU: -1 */
+#ifdef USE_PRAGMAS
+extern EE_TYPERN EE_rn_first[][2];
+#else
+extern EE_TYPERN EE_SHARED_IDATA EE_rn_first[][2];
+#endif
+
+/* For each CPU: an index of the spin lock to use (may be different
+ * for each CPU, or may be the same; the value is a valid index that
+ * must work with EE_hal_spin_in/out */
+#ifdef USE_PRAGMAS
+extern const EE_TYPESPIN EE_rn_spin[];
+#else
+extern const EE_TYPESPIN EE_SHARED_CDATA EE_rn_spin[];
+#endif
+
+/* For each CPU: initialized to 0 */
+#ifdef USE_PRAGMAS
+extern EE_TYPERN_SWITCH EE_rn_switch[];
+#else
+extern EE_TYPERN_SWITCH EE_SHARED_IDATA EE_rn_switch[];
+#endif
+
+#endif /* __RN__ */
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn_internal.h b/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn_internal.h
new file mode 100644
index 0000000..bd7d44d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/inc/ee_rn_internal.h
@@ -0,0 +1,103 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003- Paolo Gai
+ * 2011 Bernardo Dal Seno
+ */
+
+
+#ifndef __KERNEL_RN_RN_INTERNAL_H__
+#define __KERNEL_RN_RN_INTERNAL_H__
+
+#include "kernel/rn/inc/ee_rn.h"
+
+#ifdef __RN__
+
+/* For each CPU: an index that says informations about the queuing data
+ * structure should be used by the rn_send function. Init value=0
+ * Flags:
+ * - bit 0 which copy of the data structures
+ * - bit 1 inside or not an interrupt handler
+ * - bit 2 a new remote notification arrived while inside an interrupt handler
+ */
+
+#define EE_RN_SWITCH_COPY ((EE_TYPERN_SWITCH)1U)
+#define EE_RN_SWITCH_INSIDEIRQ ((EE_TYPERN_SWITCH)2U)
+#define EE_RN_SWITCH_NEWRN ((EE_TYPERN_SWITCH)4U)
+
+
+
+/*
+ * this is used as parameter for EE_rn_send, to identify the behavior
+ * of the particular RN
+ *
+ * It is a bitmask. The bits are defined into ee_rn.h
+ */
+typedef union {
+ EE_UREG pending;
+#ifdef __RN_EVENT__
+ EE_TYPEEVENTMASK ev;
+#endif
+#ifdef __RN_BIND__
+ EE_TYPECONTRACT vres;
+#endif
+} EE_TYPERN_PARAM;
+
+/* This function can be used to send a remote notification
+ * Parameters: the remote notification (MUST BE >0)
+ * Returned values: >0 if there is an error
+ */
+#ifndef __PRIVATE_RN_SEND__
+extern int EE_rn_send(EE_TYPERN rn,
+ EE_TYPERN_NOTIFY t,
+ EE_TYPERN_PARAM par);
+#endif
+
+/* this function can be used into an interrupt handler to handle
+ * pending notifications. It will execute all the pending
+ * notification. Execution order may not respect the original
+ * notification order. */
+#ifndef __PRIVATE_RN_HANDLER__
+extern void EE_rn_handler(void);
+#endif
+
+#endif /* __RN__ */
+#endif /* __KERNEL_RN_RN_INTERNAL_H__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rn.c b/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rn.c
new file mode 100644
index 0000000..2ff115a
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rn.c
@@ -0,0 +1,249 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2011 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001, 2002 Paolo Gai
+ * 2001 Bernardo Dal Seno
+ */
+
+/* for ActivateTask() */
+#include "ee.h"
+
+#include "ee_internal.h"
+
+#ifdef __RN__
+
+/* this INTERNAL function is called to execute a notification procedure */
+#ifndef __PRIVATE_RN_EXECUTE__
+static void EE_rn_execute(EE_TYPERN rn,
+ EE_TYPERN_SWITCH sw)
+{
+#if defined(__RN_COUNTER__) || defined(__RN_TASK__) || defined(__RN_FUNC__)
+ register EE_UREG pend;
+#endif
+
+#ifdef __RN_COUNTER__
+ if (EE_rn_type[rn][sw] & EE_RN_COUNTER) {
+ for (pend = EE_rn_pending[rn][sw];
+ pend;
+ pend--) {
+#if (defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || defined(__OO_ECC2__)) && !defined(__OO_NO_ALARMS__)
+ EE_oo_IncrementCounterImplementation(EE_rn_counter[rn]);
+#endif
+#if defined(__ALARMS__)
+ EE_counter_tick(EE_rn_counter[rn]);
+#endif
+ }
+ EE_rn_pending[rn][sw] = 0;
+
+ EE_rn_type[rn][sw] &= ~EE_RN_COUNTER;
+ }
+#endif
+
+
+
+ /* Task before Events; in this way we can activate an extended task
+ * and then set events for it! */
+#ifdef __RN_TASK__
+ if (EE_rn_type[rn][sw] & EE_RN_TASK) {
+ for (pend = EE_rn_pending[rn][sw];
+ pend;
+ pend--) {
+#if defined(__FP__) || defined(__EDF__)
+ EE_fp_ActivateTask(EE_rn_task[rn]);
+#endif
+#if defined(__OO_BCC1__) || defined(__OO_BCC2__) || defined(__OO_ECC1__) || defined(__OO_ECC2__)
+ /* Any error is ignored and not reported back to the originating core */
+ (void)EE_oo_ActivateTask(EE_rn_task[rn]);
+#endif
+#if defined(__FRSH__)
+ EE_frsh_thread_activate(EE_rn_task[rn]);
+#endif
+ }
+ EE_rn_pending[rn][sw] = 0U;
+
+ EE_rn_type[rn][sw] &= ~EE_RN_TASK;
+ }
+#endif
+
+
+
+#ifdef __RN_EVENT__
+ if (EE_rn_type[rn][sw] & EE_RN_EVENT) {
+ if (EE_rn_event[rn][sw]) {
+ /* Any error is ignored and not reported back to the originating core */
+ (void)EE_oo_SetEvent(EE_rn_task[rn], EE_rn_event[rn][sw]);
+ /* we have to reset the event mask! */
+ EE_rn_event[rn][sw] = 0U;
+ }
+
+ EE_rn_type[rn][sw] &= ~EE_RN_EVENT;
+ }
+#endif
+
+
+
+#ifdef __RN_FUNC__
+ if (EE_rn_type[rn][sw] & EE_RN_FUNC) {
+ for (pend = EE_rn_pending[rn][sw];
+ pend;
+ pend--) {
+ ((void (*)(void))(EE_rn_func[rn]))();
+ }
+ EE_rn_pending[rn][sw] = 0;
+
+ EE_rn_type[rn][sw] &= ~EE_RN_FUNC;
+ }
+#endif
+
+
+
+#ifdef __RN_BIND__
+ if (EE_rn_type[rn][sw] & EE_RN_BIND) {
+ EE_frsh_BindTask(EE_rn_vres[rn][sw], EE_rn_task[rn]);
+ EE_rn_type[rn][sw] &= ~EE_RN_BIND;
+ }
+#endif
+
+
+
+#ifdef __RN_UNBIND__
+ if (EE_rn_type[rn][sw] & EE_RN_UNBIND) {
+ EE_frsh_UnbindTask(EE_rn_task[rn]);
+ EE_rn_type[rn][sw] &= ~EE_RN_UNBIND;
+ }
+#endif
+}
+#endif
+
+/* this function can be used into an interrupt handler to handle
+ * pending notifications. It will execute all the pending
+ * notifications. Execution order may not respect the original
+ * notification order. */
+#ifndef __PRIVATE_RN_HANDLER__
+void EE_rn_handler(void)
+{
+ /* Probably (I hope ;-) an interprocessor interrupt has been raised.
+ * That also means that (probably) there are pending notifications
+ * that have to be notified.
+ *
+ * Please note that we must disable interrupts in a way that the
+ * spin lock exits as soon as possible.
+ */
+
+ register EE_TYPERN current;
+ register EE_TYPERN_SWITCH sw;
+ register EE_FREG flag;
+ int redo = 0;
+
+ do {
+ sw = EE_rn_switch[EE_CURRENTCPU] & EE_RN_SWITCH_COPY;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ /* Spin Lock acquisition */
+ EE_hal_spin_in(EE_rn_spin[EE_CURRENTCPU]);
+
+ /* switch pending requests and set the inside irq flag */
+ EE_rn_switch[EE_CURRENTCPU] =
+ (EE_rn_switch[EE_CURRENTCPU] ^ EE_RN_SWITCH_COPY) |
+ EE_RN_SWITCH_INSIDEIRQ;
+
+ /* Spin Lock release */
+ EE_hal_spin_out(EE_rn_spin[EE_CURRENTCPU]);
+
+ EE_hal_end_nested_primitive(flag);
+
+
+ /* Note: from now on, we can assume that all the data structures
+ * indexed by sw can be accessed without need of interrupt
+ * disabling or spin locks. The only requirements that must be
+ * fulfilled is that this function cannot be interrupted again by
+ * itself (i.e., once an interprocessor interrupt is raised, it
+ * cannot be raised again until this function has completed. */
+
+ /* executing requests */
+ for (current = EE_rn_first[EE_CURRENTCPU][sw];
+ current != (EE_TYPERN)-1;
+ current = EE_rn_next[current][sw]) {
+ EE_rn_execute(current, sw);
+ }
+
+ EE_rn_first[EE_CURRENTCPU][sw] = -1;
+
+
+ /* now we have to guarantee that we can exit from the
+ * Interprocessor interrupt. That is, the other processor should
+ * not have queued any other request. to do that, we have to
+ * reaquire again the spin lock to check the appropriate
+ * conditions. Moreover, we have to do that with interrupt
+ * disabled, and we have to be sure that we will exit the
+ * handler with INTERRUPT DISABLED. */
+
+ flag = EE_hal_begin_nested_primitive();
+ EE_hal_spin_in(EE_rn_spin[EE_CURRENTCPU]);
+
+ /* if the other processor has queued another request */
+ if (EE_rn_switch[EE_CURRENTCPU] & EE_RN_SWITCH_NEWRN) {
+ /* reset the newrn flag */
+ EE_rn_switch[EE_CURRENTCPU] &= ~EE_RN_SWITCH_NEWRN;
+ /* redo the dispatching of the remote notifications */
+ redo = 1;
+ } else {
+ /* we can exit the interrupt! */
+ redo = 0;
+ /* set that we are no more inside the interrupt */
+ EE_rn_switch[EE_CURRENTCPU] &= ~EE_RN_SWITCH_INSIDEIRQ;
+
+ EE_hal_IRQ_interprocessor_served((EE_UINT8)EE_CURRENTCPU);
+ }
+
+ /* Spin Lock release */
+ EE_hal_spin_out(EE_rn_spin[EE_CURRENTCPU]);
+
+ /* note: we end the handler with interrupt disabled! */
+ if (redo) {
+ EE_hal_end_nested_primitive(flag);
+ }
+ } while (redo);
+}
+#endif /* __PRIVATE_RN_HANDLER__ */
+
+#endif /* __RN__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rnsend.c b/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rnsend.c
new file mode 100644
index 0000000..b1e77be
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/rn/src/ee_rnsend.c
@@ -0,0 +1,180 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2001, 2002 Paolo Gai
+ * CVS: $Id: ee_rnsend.c,v 1.9 2006/06/08 20:40:42 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifdef __RN__
+
+/* This function can be used to send a remote notification.
+ * Parameters: the remote notification. MUST BE >0
+ * Returned values: 1 in case of error, 0 otherwise
+ *
+ * Errors currently only happen when using FRSH and trying to bind/unbind
+ */
+
+#ifndef __PRIVATE_RN_SEND__
+/* This function is called inside a primitive so I don't need to handle
+ * interrupts here */
+int EE_rn_send(EE_TYPERN rn,
+ EE_TYPERN_NOTIFY t,
+ EE_TYPERN_PARAM par)
+{
+ register EE_UINT8 cpu;
+ register EE_TYPERN_SWITCH sw;
+ register int newIRQ;
+ int retvalue = 0;
+
+ /* here we suppose that inter-processor interrupts can not preempt
+ * this function. For that reason, it is not necessary to lock the
+ * spin lock here. That is, only one entity for each processor can
+ * use the notification data structure at a time, and the
+ * interprocessor interrupt always find the spin lock used by a task
+ * on another CPU or it find it free. */
+
+ cpu = EE_rn_cpu[rn];
+
+ if (cpu == (EE_UINT8)EE_CURRENTCPU) {
+ /* THIS SHOULD NEVER HAPPEN!!!
+ * Local notification not allowed
+ * CHECK YOUR CONFIGURATION FOR THE REMOTE NOTIFICATIONS!!!
+ * should we return an error?
+ */
+ return 1;
+ } else {
+ /* Remote notification */
+
+ /* Spin Lock acquisition */
+ EE_hal_spin_in(EE_rn_spin[cpu]);
+
+ /* Note: sw must be read inside the spin-lock because its value
+ * can be changed by the other CPU! */
+ sw = EE_rn_switch[cpu] & EE_RN_SWITCH_COPY;
+
+ /* Check if we should raise a new Interprocessor Interrupt
+ *
+ * That is, the target CPU is not inside the IIRQ interrupt handler, and
+ * nothing is already queued on the current data structure
+ */
+ newIRQ = ((EE_rn_switch[cpu] & EE_RN_SWITCH_INSIDEIRQ) == 0U) &&
+ (EE_rn_first[cpu][sw] == (EE_TYPERN)-1);
+
+ /* the interrupt handler have to do the cycle again */
+ if (EE_rn_switch[cpu] & EE_RN_SWITCH_INSIDEIRQ) {
+ EE_rn_switch[cpu] |= EE_RN_SWITCH_NEWRN;
+ }
+
+ /* Queuing request */
+ if (EE_rn_type[rn][sw] == 0U) {
+ /* request was not queued before */
+
+ /* insert it into the pending requests */
+ EE_rn_next[rn][sw] = EE_rn_first[cpu][sw];
+ EE_rn_first[cpu][sw] = rn;
+ }
+
+ /* process the remote notification */
+
+ /* if it is an event, count the event */
+#ifdef __RN_EVENT__
+ if (t & EE_RN_EVENT) {
+ EE_rn_event[rn][sw] |= par.ev;
+ } else
+#endif
+
+ /* if it is a bind, set the bind value, or error */
+#ifdef __RN_BIND__
+ if (t & EE_RN_BIND) {
+ if (EE_rn_type[rn][sw] & (EE_RN_BIND | EE_RN_UNBIND)) {
+ retvalue = 1;
+ } else {
+ EE_rn_vres[rn][sw] = par.vres;
+ retvalue = 0;
+ }
+ } else
+#endif
+
+ /* if it is an unbind, set the unbind flag, or error */
+#ifdef __RN_UNBIND__
+ if (t & EE_RN_UNBIND) {
+ if (EE_rn_type[rn][sw] & (EE_RN_BIND | EE_RN_UNBIND)) {
+ retvalue = 1;
+ } else {
+ retvalue = 0;
+ }
+ } else
+#endif
+ {
+ /* if it is counter, task, func */
+ /* increase the pending counter */
+ EE_rn_pending[rn][sw] += par.pending;
+ }
+
+
+ /* set the type in the remote notification */
+ EE_rn_type[rn][sw] |= t;
+
+
+ /* Spin Lock release */
+ EE_hal_spin_out(EE_rn_spin[cpu]);
+
+ /* Inter-processor interrupt
+ *
+ * We raise an interprocessor interrupt only if there is not a
+ * similar interrupt pending Note that the irq is raised before
+ * releasing the spin lock, anyway the instructions that are
+ * still to execute are only a little. In reality, the
+ * interprocessor interrupt is needed only when rn_first[cpu] !=
+ * -1. anyway, it's not worth to add this test on the Janus
+ * architecture.
+ */
+ if (newIRQ) {
+ EE_hal_IRQ_interprocessor(cpu);
+ }
+ }
+
+ return retvalue;
+}
+#endif /* !__PRIVATE_RN_SEND__ */
+#endif /* __RN__ */
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/kernel/sem/cfg/cfg.mk
new file mode 100644
index 0000000..fc2afe5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/cfg/cfg.mk
@@ -0,0 +1,54 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.3 2006/11/03 11:06:09 pj Exp $
+
+ifeq ($(call iseeopt, __SEM__), yes)
+
+ifeq ($(call iseeopt, __MONO__), yes)
+$(error Semaphores and Mono Stack HAL are not compatible!!!)
+endif
+
+EE_SRCS += pkg/kernel/sem/src/ee_swait.c
+EE_SRCS += pkg/kernel/sem/src/ee_spost.c
+EE_SRCS += pkg/kernel/sem/src/ee_sgetvalue.c
+EE_SRCS += pkg/kernel/sem/src/ee_strywait.c
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_api.h b/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_api.h
new file mode 100644
index 0000000..951e5bf
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_api.h
@@ -0,0 +1,75 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: Paolo Gai
+ * CVS: $Id: ee_api.h,v 1.4 2006/12/03 22:09:16 pj Exp $
+ */
+
+
+#ifndef __INCLUDE_KERNEL_SEM_EE_API__
+#define __INCLUDE_KERNEL_SEM_EE_API__
+
+
+#ifdef __SEM__
+
+#ifndef InitSem
+#define InitSem EE_sem_InitSem
+#endif
+
+#ifndef WaitSem
+#define WaitSem EE_sem_WaitSem
+#endif
+
+#ifndef TryWaitSem
+#define TryWaitSem EE_sem_TryWaitSem
+#endif
+
+#ifndef PostSem
+#define PostSem EE_sem_PostSem
+#endif
+
+#ifndef GetValueSem
+#define GetValueSem EE_sem_GetValueSem
+#endif
+
+#endif /* __SEM__ */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_sem.h b/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_sem.h
new file mode 100644
index 0000000..6823f40
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/inc/ee_sem.h
@@ -0,0 +1,96 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_sem.h,v 1.6 2006/12/31 10:24:00 pj Exp $
+ */
+
+#ifndef __INCLUDE_KERNEL_SEM_SEM_H__
+#define __INCLUDE_KERNEL_SEM_SEM_H__
+
+/* Semaphores
+ * ----------
+ *
+ * These file declares the Erika enterprise Semaphore API
+ * A semaphore is contained in a data structure called EE_SEM.
+ * That structure can be initialized statically (recommended), or
+ * dynamically using the macro sem_init.
+ *
+ * These functions can ONLY be used with a multistack HAL or similar,
+ * because these semaphore primitives are BLOCKING primitives.
+ */
+
+/* The semaphore descriptor */
+typedef struct {
+ int count;
+ EE_TID first;
+ EE_TID last;
+} SemType;
+
+typedef SemType *SemRefType;
+
+#define STATICSEM(value) { (value), EE_NIL, EE_NIL }
+
+#ifndef __PRIVATE_SEM_INIT__
+#define EE_sem_InitSem(s, value) \
+ (s).count = (value), \
+ (s).first = EE_NIL, \
+ (s).last = EE_NIL
+#endif
+
+#ifndef __PRIVATE_SEM_WAIT__
+void EE_sem_WaitSem(SemRefType s);
+#endif
+
+#ifndef __PRIVATE_SEM_TRYWAIT__
+/* returns 1 if the counter is decremented, 0 if not */
+int EE_sem_TryWaitSem(SemRefType s);
+#endif
+
+#ifndef __PRIVATE_SEM_POST__
+void EE_sem_PostSem(SemRefType s);
+#endif
+
+#ifndef __PRIVATE_SEM_GETVALUE__
+int EE_sem_GetValueSem(SemRefType s);
+#endif
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_sgetvalue.c b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_sgetvalue.c
new file mode 100644
index 0000000..32659dd
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_sgetvalue.c
@@ -0,0 +1,67 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_sgetvalue.c,v 1.5 2006/12/31 10:24:00 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SEM_GETVALUE__
+/* returns -1 or the value of the semaphore */
+int EE_sem_GetValueSem(SemRefType s)
+{
+ register int value;
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (s->first == EE_NIL) {
+ value = s->count;
+ } else {
+ value = -1;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+ return value;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_spost.c b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_spost.c
new file mode 100644
index 0000000..7dc52b5
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_spost.c
@@ -0,0 +1,99 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_spost.c,v 1.7 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SEM_POST__
+void EE_sem_PostSem(SemRefType s)
+{
+ register EE_FREG flag;
+ EE_TID newthread;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (s->first != EE_NIL) {
+ newthread = s->first;
+
+ /* wake up blocked thread */
+ if ((s->first = EE_th_next[newthread]) == EE_NIL) {
+ s->last = EE_NIL;
+ }
+
+ /* check for preemption */
+#if defined(__FP__)
+ if (!EE_hal_get_IRQ_nesting_level() &&
+ EE_sys_ceiling < EE_th_ready_prio[newthread]) {
+#else
+ if (!EE_hal_get_IRQ_nesting_level() &&
+ (EE_stk_queryfirst() == EE_NIL || /* main task! */
+ ((EE_STIME)(EE_th_absdline[EE_stk_queryfirst()] - EE_th_absdline[newthread]) > 0
+ && EE_sys_ceiling < EE_th_ready_prio[newthread])
+ )
+ ) {
+#endif
+ /* we have to schedule th blocked thread */
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[newthread] = EE_STACKED;
+#endif
+ EE_sys_ceiling |= EE_th_dispatch_prio[newthread];
+
+ /* insert the extracted task on the topo of the stack */
+ EE_th_next[newthread] = EE_stk_queryfirst();
+ EE_stkfirst = newthread;
+
+ EE_hal_stkchange(newthread);
+ } else {
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[newthread] = EE_READY | EE_WASSTACKED;
+#endif
+ EE_rq_insert(newthread);
+ }
+ } else {
+ s->count++;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_strywait.c b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_strywait.c
new file mode 100644
index 0000000..ce8f296
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_strywait.c
@@ -0,0 +1,68 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_strywait.c,v 1.5 2006/12/31 10:24:00 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SEM_TRYWAIT__
+/* returns 1 if the counter is decremented, 0 if not */
+int EE_sem_TryWaitSem(SemRefType s)
+{
+ register int result;
+ register EE_FREG flag;
+
+ flag = EE_hal_begin_nested_primitive();
+
+ if (s->count) {
+ s->count--;
+ result = 0;
+ } else {
+ result = 1;
+ }
+
+ EE_hal_end_nested_primitive(flag);
+
+ return result;
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_swait.c b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_swait.c
new file mode 100644
index 0000000..68e4fb9
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/kernel/sem/src/ee_swait.c
@@ -0,0 +1,146 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2002 Paolo Gai
+ * CVS: $Id: ee_swait.c,v 1.6 2007/06/14 10:27:12 pj Exp $
+ */
+
+#include "ee_internal.h"
+
+#ifndef __PRIVATE_SEM_WAIT__
+void EE_sem_WaitSem(SemRefType s)
+{
+ EE_TID current;
+
+ register EE_FREG np_flags;
+
+ np_flags = EE_hal_begin_nested_primitive();
+
+ if (s->count) {
+ s->count--;
+ } else {
+ /* The running task blocks:
+ * - it must be removed from the stacked queue
+ * - and then it must be inserted into the blocked queue */
+
+ /* get the running task */
+ current = EE_stk_queryfirst();
+
+ /* extract the task from the stk data structure */
+ EE_stk_getfirst();
+
+ /* The task state switch from STACKED TO BLOCKED */
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[current] = EE_BLOCKED;
+#endif
+
+ /* reset the thread priority bit in the system_ceiling */
+ EE_sys_ceiling &= ~EE_th_dispatch_prio[current];
+
+ if (s->first != EE_NIL) {
+ /* the semaphore queue is not empty */
+ EE_th_next[s->last] = current;
+ } else {
+ /* the semaphore queue is empty */
+ s->first = current;
+ }
+
+ s->last = current;
+ EE_th_next[current] = EE_NIL;
+
+#if defined(__FP__)
+ /* check if there is to schedule a ready thread or pop a preempted
+ * thread
+ */
+ if (EE_rq_queryfirst() == EE_NIL ||
+ EE_sys_ceiling >= EE_th_ready_prio[EE_rq_queryfirst()])
+#else
+ /*
+ * check if there is to schedule a ready thread or pop a preempted thread
+ * th_absdline[stk_queryfirst()] <= th_absdline[rq_queryfirst()]
+ *
+ * see also src/srpt/thendin.c
+ *
+ * note that this test work also for the main task!
+ */
+ if (EE_rq_queryfirst() == EE_NIL ||
+ (EE_stk_queryfirst() != EE_NIL &&
+ (
+ (EE_STIME)(EE_th_absdline[EE_stk_queryfirst()] -
+ EE_th_absdline[EE_rq_queryfirst()]) <= 0
+ || EE_sys_ceiling >= EE_th_ready_prio[EE_rq_queryfirst()]
+ )
+ )
+ )
+#endif
+ {
+ /* we have to schedule an interrupted thread that is on the top
+ * of its stack; the state is already STACKED! */
+ EE_hal_stkchange(EE_stk_queryfirst());
+ } else {
+ /* we have to schedule a ready thread that may be not yet stacked */
+#if defined(__MULTI__)
+ register int flag;
+
+ flag = EE_th_status[EE_rq_queryfirst()] & EE_WASSTACKED;
+#endif
+
+#if defined(__MULTI__) || defined(__WITH_STATUS__)
+ EE_th_status[EE_rq_queryfirst()] = EE_STACKED;
+#endif
+
+ EE_sys_ceiling |= EE_th_dispatch_prio[EE_rq_queryfirst()];
+
+#if defined(__MULTI__)
+ if (flag) {
+ EE_hal_stkchange(EE_rq2stk_exchange());
+ } else {
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+ }
+#else
+ EE_hal_ready2stacked(EE_rq2stk_exchange());
+#endif
+ }
+ }
+
+ EE_hal_end_nested_primitive(np_flags);
+}
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/test/assert/cfg/cfg.mk b/src/bsp/hsm/os/erika2/pkg/test/assert/cfg/cfg.mk
new file mode 100644
index 0000000..06f921d
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/test/assert/cfg/cfg.mk
@@ -0,0 +1,46 @@
+# ###*B*###
+# ERIKA Enterprise - a tiny RTOS for small microcontrollers
+#
+# Copyright (C) 2002-2008 Evidence Srl
+#
+# This file is part of ERIKA Enterprise.
+#
+# ERIKA Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation,
+# (with a special exception described below).
+#
+# Linking this code statically or dynamically with other modules is
+# making a combined work based on this code. Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this code with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module. An independent module is a module which is not derived from
+# or based on this library. If you modify this code, you may extend
+# this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this
+# exception statement from your version.
+#
+# ERIKA Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License version 2 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with ERIKA Enterprise; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+# ###*E*###
+
+## Author: 2004 Paolo Gai
+## CVS: $Id: cfg.mk,v 1.2 2006/11/03 11:04:39 pj Exp $
+
+ifeq ($(call iseeopt, __ASSERT__), yes)
+EE_SRCS += pkg/test/assert/src/ee_assert.c
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/test/assert/inc/ee_assert.h b/src/bsp/hsm/os/erika2/pkg/test/assert/inc/ee_assert.h
new file mode 100644
index 0000000..dfcab63
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/test/assert/inc/ee_assert.h
@@ -0,0 +1,215 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*###
+ */
+
+/*
+ * Author: 2003 Paolo Gai
+ * CVS: $Id: ee_assert.h,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+/* EE Test Assertions
+ *
+ * This component provides a set of macros/functions which allow to
+ * simplify the debug of a generic EE component using an automatic
+ * tool. The paradigm of the testing is a "black box" testing. That
+ * is, assertions are inserted into the code OUTSIDE the component
+ * code, and the test will test the behavior of the system seen by an
+ * external observer.
+ *
+ * To debug a component, a set of test cases have to be produced and
+ * verified.
+ *
+ * Each test case is composed by:
+ *
+ * - a set of tasks, resources, ..., with their properties and init values
+ *
+ * - a sequence of calls, ISRs and assertions that constitute a
+ * typical execution of the test case
+ *
+ * Definition: The test case is said to be successful if a run
+ * of the application respects the sequence.
+ *
+ * To check if a test case is successful, the automatic tool runs the
+ * test case. When the test case ends (i.e., it stops at a predefined
+ * breackpoint), the debugger (or the user) have to check that the
+ * final assertion is verified. If it is verified, the test is passed.
+ *
+ * Implementation details
+ * ----------------------
+ *
+ * Assertion internal structure:
+ *
+ * Assertion Data
+ *
+ * - Assertions are identified by an identifier (index in an
+ * array). Index 0 is reserved for the final result that says if the
+ * test case is successful or not.
+ *
+ * - The data structure for an assertion is an array of integers
+ * filled with 0s. The array contains a structure with a field
+ * "value" that is 0 if the assertion has not yet been evaluated, ASSERT_NO
+ * if the assertion has failed, ASSERT_YES if the assertion was
+ * successful.
+ *
+ * Assertion functions
+ *
+ * - Assertions can run with interrupts enabled. Please notice that if a
+ * preemption by an interrupt or another task occurs during the execution of
+ * an assertion, and the preempting task/interrupt modifies the same
+ * assertion, the check for a double use of an assertion may fail.
+ *
+ * - The assertion functions should not work as a normal
+ * primitive. Every assertion basically should work with a dedicated
+ * entry in the array. That is, there can not exist two assertions with
+ * the same identifier.
+ *
+ * - Assertions can rely on other assertion identifiers to implement
+ * precedence constraints. It is guaranteed that an assertion function
+ * will read the value field only once, to avoid problems due to the
+ * fact that assertion runs with interrupts enabled.
+ *
+ * Types that have to be defined in types.h
+ *
+ * - EE_TYPEASSERT is the type used for the assertion index.
+ * MUST BE SIGNED!!!
+ *
+ * - EE_TYPEASSERTVALUE contains at least 3 values:
+ * 0, EE_ASSERT_NO, EE_ASSERT_YES
+ * The type EE_INT8 should work for most architectures.
+ */
+
+#ifndef __ASSERT_ASSERT_H__
+#define __ASSERT_ASSERT_H__
+
+#include "ee.h"
+
+
+/* types.h */
+#ifndef EE_TYPEASSERT
+#define EE_TYPEASSERT EE_SREG
+#endif
+
+#ifndef EE_TYPEASSERTVALUE
+#define EE_TYPEASSERTVALUE EE_INT8
+#endif
+
+
+
+
+/* this is an invalid value for the index */
+#define EE_ASSERT_NIL ((EE_TYPEASSERT)(-1))
+
+/* these are the results of each assertion test */
+#define EE_ASSERT_INITVALUE ((EE_TYPEASSERTVALUE)0)
+#define EE_ASSERT_YES ((EE_TYPEASSERTVALUE)1)
+#define EE_ASSERT_NO ((EE_TYPEASSERTVALUE)2)
+#define EE_ASSERT_ALREADYUSED ((EE_TYPEASSERTVALUE)3)
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_START_SEC_VAR_NOINIT
+#define API_START_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+/* the assertion array */
+extern EE_TYPEASSERTVALUE EE_assertions[];
+
+/* This is the simplest assertion that can be made:
+ *
+ * the assertion "id" become YES if the test is true and the prev
+ * assertion is YES.
+ *
+ * If no PREVious assertion has to be checked, the prev parameter
+ * should be EE_ASSERT_NIL.
+ *
+ * The return value is either YES or NO depending on the result.
+ */
+#ifndef __PRIVATE_ASSERT__
+EE_TYPEASSERTVALUE EE_assert(EE_TYPEASSERT id,
+ int test,
+ EE_TYPEASSERT prev);
+#endif
+
+/* These are a simple or/and assertion:
+ *
+ * the assertion "id" become YES if the prev1 or/and prev2
+ * assertions are YES.
+ */
+#ifndef __PRIVATE_ASSERT_OR__
+EE_TYPEASSERTVALUE EE_assert_or(EE_TYPEASSERT id,
+ EE_TYPEASSERT prev1,
+ EE_TYPEASSERT prev2);
+#endif
+
+#ifndef __PRIVATE_ASSERT_AND__
+EE_TYPEASSERTVALUE EE_assert_and(EE_TYPEASSERT id,
+ EE_TYPEASSERT prev1,
+ EE_TYPEASSERT prev2);
+#endif
+
+/* This is a range assertion, typically used as last assertion.
+ *
+ * the assertion "id" become YES if ALL the assertions between begin
+ * and end are YES.
+ */
+
+#ifndef __PRIVATE_ASSERT_RANGE__
+EE_TYPEASSERTVALUE EE_assert_range(EE_TYPEASSERT id,
+ EE_TYPEASSERT begin,
+ EE_TYPEASSERT end);
+#endif
+
+/* This is the last assertion. It simply does nothing, and must be
+ * included in all the examples with the purpose of setting a
+ * breakpoint there.
+ */
+#ifndef __PRIVATE_ASSERT_LAST__
+EE_TYPEASSERTVALUE EE_assert_last(void);
+#endif
+
+/* If MemMap.h support is enabled (i.e. because memory protection): use it */
+#ifdef EE_SUPPORT_MEMMAP_H
+#define API_STOP_SEC_VAR_NOINIT
+#define API_STOP_SEC_CODE
+#include "MemMap.h"
+#endif /* EE_SUPPORT_MEMMAP_H */
+
+#endif
diff --git a/src/bsp/hsm/os/erika2/pkg/test/assert/makefile b/src/bsp/hsm/os/erika2/pkg/test/assert/makefile
new file mode 100644
index 0000000..792579e
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/test/assert/makefile
@@ -0,0 +1,18 @@
+LOCAL_PATH := $(call cur-dir)
+
+ifeq ($(OS_ERIKA2), true)
+
+LOCAL_MODULE := os_erika_test_assert
+
+EE_SRCS :=
+
+ifeq ($(call iseeopt, __ASSERT__), yes)
+EE_SRCS += ./src/ee_assert.c
+endif
+
+EE_INCS := ./inc
+
+ALL_SRCS += $(foreach SRC, $(EE_SRCS:./%=%), $(addprefix $(LOCAL_PATH)/, $(SRC)))
+ALL_INCDIRS += $(foreach INC, $(EE_INCS), $(addprefix $(LOCAL_PATH)/, $(INC)))
+
+endif
diff --git a/src/bsp/hsm/os/erika2/pkg/test/assert/src/ee_assert.c b/src/bsp/hsm/os/erika2/pkg/test/assert/src/ee_assert.c
new file mode 100644
index 0000000..5da9946
--- /dev/null
+++ b/src/bsp/hsm/os/erika2/pkg/test/assert/src/ee_assert.c
@@ -0,0 +1,151 @@
+/* ###*B*###
+ * ERIKA Enterprise - a tiny RTOS for small microcontrollers
+ *
+ * Copyright (C) 2002-2008 Evidence Srl
+ *
+ * This file is part of ERIKA Enterprise.
+ *
+ * ERIKA Enterprise is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation,
+ * (with a special exception described below).
+ *
+ * Linking this code statically or dynamically with other modules is
+ * making a combined work based on this code. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this code with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module. An independent module is a module which is not derived from
+ * or based on this library. If you modify this code, you may extend
+ * this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ *
+ * ERIKA Enterprise is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with ERIKA Enterprise; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ * ###*E*### */
+
+/*
+ * Author: 2003-2004 Paolo Gai
+ * CVS: $Id: ee_assert.c,v 1.1.1.1 2004/11/05 16:03:03 pj Exp $
+ */
+
+#include "test/assert/inc/ee_assert.h"
+
+#ifndef __PRIVATE_ASSERT__
+EE_TYPEASSERTVALUE EE_assert(EE_TYPEASSERT id,
+ int test,
+ EE_TYPEASSERT prev)
+{
+ /* I can use id into an assertion only once */
+ if (EE_assertions[id] != EE_ASSERT_INITVALUE) {
+ EE_assertions[id] = EE_ASSERT_ALREADYUSED;
+ return EE_ASSERT_ALREADYUSED;
+ }
+
+ if (test) {
+ if (prev != EE_ASSERT_NIL) {
+ if (EE_assertions[prev] == EE_ASSERT_YES) {
+ /* test is true and the prev assertion is YES */
+ EE_assertions[id] = EE_ASSERT_YES;
+ return EE_ASSERT_YES;
+ } else {
+ /* test is true but the prev assertion is != YES */
+ EE_assertions[id] = EE_ASSERT_NO;
+ return EE_ASSERT_NO;
+ }
+ } else {
+ /* test is true and prev is EE_ASSERT_NIL */
+ EE_assertions[id] = EE_ASSERT_YES;
+ return EE_ASSERT_YES;
+ }
+ } else {
+ /* test is false */
+ EE_assertions[id] = EE_ASSERT_NO;
+ return EE_ASSERT_NO;
+ }
+}
+#endif
+
+#ifndef __PRIVATE_ASSERT_OR__
+EE_TYPEASSERTVALUE EE_assert_or(EE_TYPEASSERT id,
+ EE_TYPEASSERT prev1,
+ EE_TYPEASSERT prev2)
+{
+ /* I can use id into an assertion only once */
+ if (EE_assertions[id] != EE_ASSERT_INITVALUE) {
+ EE_assertions[id] = EE_ASSERT_ALREADYUSED;
+ return EE_ASSERT_ALREADYUSED;
+ }
+
+ if ((EE_assertions[prev1] == EE_ASSERT_YES) ||
+ (EE_assertions[prev2] == EE_ASSERT_YES)) {
+ EE_assertions[id] = EE_ASSERT_YES;
+ return EE_ASSERT_YES;
+ } else {
+ EE_assertions[id] = EE_ASSERT_NO;
+ return EE_ASSERT_NO;
+ }
+}
+#endif
+
+#ifndef __PRIVATE_ASSERT_AND__
+EE_TYPEASSERTVALUE EE_assert_and(EE_TYPEASSERT id,
+ EE_TYPEASSERT prev1,
+ EE_TYPEASSERT prev2)
+{
+ /* I can use id into an assertion only once */
+ if (EE_assertions[id] != EE_ASSERT_INITVALUE) {
+ EE_assertions[id] = EE_ASSERT_ALREADYUSED;
+ return EE_ASSERT_ALREADYUSED;
+ }
+
+ if ((EE_assertions[prev1] == EE_ASSERT_YES) &&
+ (EE_assertions[prev2] == EE_ASSERT_YES)) {
+ EE_assertions[id] = EE_ASSERT_YES;
+ return EE_ASSERT_YES;
+ } else {
+ EE_assertions[id] = EE_ASSERT_NO;
+ return EE_ASSERT_NO;
+ }
+}
+#endif
+
+#ifndef __PRIVATE_ASSERT_RANGE__
+EE_TYPEASSERTVALUE EE_assert_range(EE_TYPEASSERT id,
+ EE_TYPEASSERT begin,
+ EE_TYPEASSERT end)
+{
+ EE_TYPEASSERT i;
+
+ for (i = begin; i <= end; i++) {
+ if (EE_assertions[i] != EE_ASSERT_YES) {
+ EE_assertions[id] = EE_ASSERT_NO;
+ return EE_ASSERT_NO;
+ }
+ }
+
+ EE_assertions[id] = EE_ASSERT_YES;
+ return EE_ASSERT_YES;
+}
+#endif
+
+#ifndef __PRIVATE_ASSERT_ALL__
+EE_TYPEASSERTVALUE EE_assert_last(void)
+{
+ return EE_assertions[0];
+}
+#endif