]> rtime.felk.cvut.cz Git - arc.git/blobdiff - system/kernel/init.c
EcuM: More EcuM fixes.
[arc.git] / system / kernel / init.c
index 8a2a1d4fec59baa28b81b9e456bd9dbedcf4c47e..fe5f9da4878662cff751d209e7b83d9d903bf205 100644 (file)
-/* -------------------------------- Arctic Core ------------------------------
- * Arctic Core - the open source AUTOSAR platform http://arccore.com
- *
- * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
- *
- * This source code 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; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
- *
- * This program 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.
- * -------------------------------- Arctic Core ------------------------------*/
-
-
-#include "Os.h"
-#include "sys.h"
-#include <stdlib.h>
-#include <string.h>
-#include "ext_config.h"
-//#include "Pool.h"
-//#include "ppc_asm.h"
-#include "arch.h"
-#include "kernel.h"
-#include "swap.h"
-#include "hooks.h"
-#include "task_i.h"
-#include "alarm_i.h"
-#include "sched_table_i.h"
-#include "Trace.h"
-
-
-extern void Oil_GetInterruptStackInfo( stack_t *stack );
-extern uint32_t McuE_GetSystemClock( void );
-extern OsTickType OsTickFreq;
-
-sys_t os_sys;
-
-/**
- * Initialize alarms and schedule-tables for the counters
- */
-static void os_counter_init( void ) {
-       counter_obj_t *counter;
-       alarm_obj_t *alarm_obj;
-       sched_table_t *sched_obj;
-       /* Create a list from the counter to the alarms */
-       for(int i=0; i < Oil_GetCounterCnt() ; i++) {
-               counter = Oil_GetCounter(i);
-               // Alarms
-               SLIST_INIT(&counter->alarm_head);
-               for(int j=0; j < Oil_GetAlarmCnt(); j++ ) {
-                       alarm_obj = Oil_GetAlarmObj(j);
-                       // Add the alarms
-                       SLIST_INSERT_HEAD(&counter->alarm_head,alarm_obj, alarm_list);
-               }
-               // Schedule tables
-               SLIST_INIT(&counter->sched_head);
-               for(int j=0; j < Oil_GetSchedCnt(); j++ ) {
-                       sched_obj = Oil_GetSched(j);
-                       // Add the alarms
-                       SLIST_INSERT_HEAD(&counter->sched_head,
-                                                               sched_obj,
-                                                               sched_list);
-               }
-
-
-       }
-}
-
-/**
- * Copy rom pcb data(r_pcb) to ram data
- *
- * @param      pcb             ram data
- * @param      r_pcb   rom data
- */
-
-static void os_pcb_rom_copy( pcb_t *pcb, rom_pcb_t *r_pcb ) {
-
-#if 0 //?????
-       // Check to that the memory is ok
-       {
-               int cnt = sizeof(pcb_t);
-               for(int i=0;i<cnt;i++) {
-                       if( *((unsigned char *)pcb) != 0 ) {
-                               while(1);
-                       }
-               }
-       }
-#endif
-
-//     memset(pcb,sizeof(pcb_t),0);
-       pcb->pid = r_pcb->pid;
-       pcb->prio = r_pcb->prio;
-       pcb->application = Oil_GetApplObj(r_pcb->application_id);
-       pcb->entry = r_pcb->entry;
-       pcb->proc_type = r_pcb->proc_type;
-       pcb->autostart =  r_pcb->autostart;
-       pcb->stack= r_pcb->stack;
-       pcb->pcb_rom_p = r_pcb;
-       pcb->resource_int_p = r_pcb->resource_int_p;
-       pcb->scheduling = r_pcb->scheduling;
-//     pcb->app = &app_list[r_pcb->app];
-//     pcb->app_mask = app_mask[r_pcb->app];
-       strncpy(pcb->name,r_pcb->name,16);
-}
-
-static _Bool init_os_called = 0;
-
-/**
- * Initialization of kernel structures and start of the first
- * task.
- */
-
-void InitOS( void ) {
-       int i;
-       pcb_t *tmp_pcb;
-       stack_t int_stack;
-
-       init_os_called = 1;
-
-       DEBUG(DEBUG_LOW,"os_init");
-
-       /* Clear sys */
-       memset(&os_sys,0,sizeof(sys_t));
-
-       os_arch_init();
-
-       // Assign pcb list and init ready queue
-       os_sys.pcb_list = pcb_list;
-       TAILQ_INIT(& os_sys.ready_head);
-       TAILQ_INIT(& os_sys.pcb_head);
-
-       // Calc interrupt stack
-       Oil_GetInterruptStackInfo(&int_stack);
-       os_sys.int_stack = int_stack.top + int_stack.size - 16;         // TODO: 16 is arch dependent
-
-       // Init counter.. with alarms and schedule tables
-       os_counter_init();
-       os_stbl_init();
-
-       // Put all tasks in the pcb list
-       // Put the one that belong in the ready queue there
-       // TODO: we should really hash on priority here to get speed, but I don't care for the moment
-       // TODO: Isn't this just EXTENED tasks ???
-       for( i=0; i < Oil_GetTaskCnt(); i++) {
-               tmp_pcb = os_get_pcb(i);
-               assert(tmp_pcb->prio<=OS_TASK_PRIORITY_MAX);
-               os_pcb_rom_copy(tmp_pcb,os_get_rom_pcb(i));
-               if( !(tmp_pcb->proc_type & PROC_ISR) ) {
-                       os_pcb_make_virgin(tmp_pcb);
-               }
-
-               os_add_task(tmp_pcb);
-
-               DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmp_pcb->pid,tmp_pcb->name,tmp_pcb->prio);
-       }
-
-       // Now all tasks should be created.
-}
-
-static void os_start( void ) {
-       pcb_t *tmp_pcb;
-
-       assert(init_os_called);
-
-       /* find highest prio process and run it */
-       tmp_pcb = os_find_top_prio_proc();
-
-       /* TODO: fix ugly */
-       /* Call the startup hook */
-       extern struct os_conf_global_hooks_s os_conf_global_hooks;
-       os_sys.hooks = &os_conf_global_hooks;
-       if( os_sys.hooks->StartupHook!=NULL ) {
-               os_sys.hooks->StartupHook();
-       }
-
-       /* handle autostart */
-       for(int j=0; j < Oil_GetAlarmCnt(); j++ ) {
-               alarm_obj_t *alarmPtr;
-               alarmPtr = Oil_GetAlarmObj(j);
-               if(alarmPtr->autostart.active) {
-                       alarm_autostart_t *autoPtr = &alarmPtr->autostart;
-
-                       SetAbsAlarm(j,autoPtr->alarmtime, autoPtr->cycletime);
-               }
-       }
-
-       // Activate the systick interrupt
-       {
-               uint32_t sys_freq = McuE_GetSystemClock();
-               Frt_Init();
-               Frt_Start(sys_freq/OsTickFreq);
-       }
-
-
-       // Swap in prio proc.
-       {
-               // FIXME: Do this in a more structured way.. setting os_sys.curr_pcb manually is not the way to go..
-               os_sys.curr_pcb = tmp_pcb;
-               // NOTE! We don't go for os_swap_context() here..
-               // first arg(NULL) is dummy only
-               os_swap_context_to(NULL,tmp_pcb);
-               // We should not return here
-               assert(0);
-       }
-}
-#if 0
-static void os_start( void ) {
-
-}
-#endif
-
-#define TEST_DATA  12345
-int test_data = TEST_DATA;
-int test_bss = 0;
-
-
-void noooo( void ) {
-       while(1);
-}
-
-extern void EcuM_Init();
-int main( void )
-{
-       EcuM_Init();
-
-}
-
-/**
- * Starts the OS
- *
- * @param Mode - Application mode to start in
- *
- */
-void StartOS( AppModeType Mode ) {
-
-       /* Check link file */
-       if( TEST_DATA != test_data ) {
-               noooo();
-       }
-
-       if( test_bss != 0 ) {
-               noooo();
-       }
-
- os_start();
-
-}
-
-/**
- * OS shutdown
- *
- * @param Error - Reason for shutdown
- */
-
-void ShutdownOS( StatusType Error ) {
-
-       if( os_sys.hooks->ShutdownHook != NULL ) {
-               os_sys.hooks->ShutdownHook(Error);
-       }
-       /* TODO: */
-       while(1) {
-
-       }
-
-}
-
-
-
+/* -------------------------------- Arctic Core ------------------------------\r
+ * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
+ *\r
+ * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
+ *\r
+ * This source code is free software; you can redistribute it and/or modify it\r
+ * under the terms of the GNU General Public License version 2 as published by the\r
+ * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+ * for more details.\r
+ * -------------------------------- Arctic Core ------------------------------*/\r
+\r
+/* ----------------------------[includes]------------------------------------*/\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include "Os.h"\r
+#include "internal.h"\r
+#include "arc.h"\r
+#include "debug.h"\r
+#include "task_i.h"\r
+#include "sys.h"\r
+#include "isr.h"\r
+#include "counter_i.h"\r
+#include "application.h"\r
+#include "sched_table_i.h"\r
+#include "alarm_i.h"\r
+#include "arch.h"\r
+\r
+/* ----------------------------[private define]------------------------------*/\r
+/* ----------------------------[private macro]-------------------------------*/\r
+#define OS_VALIDATE(_a,_b)   if((_a)!=(_b) ) { \\r
+                                                               assert(#_a  #_b); \\r
+                                                         }\r
+/* ----------------------------[private typedef]-----------------------------*/\r
+/* ----------------------------[private function prototypes]-----------------*/\r
+/* ----------------------------[private variables]---------------------------*/\r
+Os_SysType Os_Sys;\r
+\r
+Os_IntCounterType Os_IntDisableAllCnt;\r
+Os_IntCounterType Os_IntSuspendAllCnt;\r
+Os_IntCounterType Os_IntSuspendOsCnt;\r
+\r
+OsErrorType os_error;\r
+\r
+/* ----------------------------[private functions]---------------------------*/\r
+\r
+\r
+static void Os_CfgValidate(void ) {\r
+#if (OS_COUNTER_CNT!=0)\r
+       OS_VALIDATE(OS_COUNTER_CNT,ARRAY_SIZE(counter_list));\r
+#endif\r
+#if (OS_RESOURCE_CNT!=0)\r
+       OS_VALIDATE(OS_RESOURCE_CNT,ARRAY_SIZE(resource_list));\r
+#endif\r
+       OS_VALIDATE(OS_TASK_CNT ,ARRAY_SIZE( Os_TaskConstList));\r
+#if (OS_ALARM_CNT!=0)\r
+       OS_VALIDATE(OS_ALARM_CNT,ARRAY_SIZE(alarm_list));\r
+#endif\r
+#if (OS_SCHTBL_CNT!=0)\r
+       OS_VALIDATE(OS_SCHTBL_CNT, ARRAY_SIZE(sched_list));\r
+#endif\r
+}\r
+\r
+/* ----------------------------[public functions]----------------------------*/\r
+\r
+extern uint32_t McuE_GetSystemClock( void );\r
+\r
+\r
+/**\r
+ * Copy rom pcb data(r_pcb) to ram data\r
+ *\r
+ * @param      pcb             ram data\r
+ * @param      r_pcb   rom data\r
+ */\r
+\r
+static void copyPcbParts( OsTaskVarType *pcb, const OsTaskConstType *r_pcb ) {\r
+       assert(r_pcb->prio<=OS_TASK_PRIORITY_MAX);\r
+       pcb->activePriority = r_pcb->prio;\r
+       pcb->stack= r_pcb->stack;\r
+       pcb->constPtr = r_pcb;\r
+}\r
+\r
+static _Bool init_os_called = 0;\r
+\r
+/**\r
+ * Initialization of kernel structures and start of the first\r
+ * task.\r
+ */\r
+\r
+void InitOS( void ) {\r
+       int i;\r
+       OsTaskVarType *tmpPcbPtr;\r
+       OsIsrStackType intStack;\r
+\r
+       init_os_called = 1;\r
+\r
+       Os_CfgValidate();\r
+\r
+       DEBUG(DEBUG_LOW,"os_init");\r
+\r
+       /* Clear sys */\r
+       memset(&Os_Sys,0,sizeof(Os_SysType));\r
+\r
+       Os_ArchInit();\r
+\r
+       /* Get the numbers defined in the editor */\r
+       Os_Sys.isrCnt = OS_ISR_CNT;\r
+\r
+       // Assign pcb list and init ready queue\r
+       Os_Sys.pcb_list = Os_TaskVarList;\r
+       TAILQ_INIT(& Os_Sys.ready_head);\r
+//     TAILQ_INIT(& Os_Sys.pcb_head);\r
+#if defined(USE_KERNEL_EXTRA)\r
+       TAILQ_INIT(& Os_Sys.timerHead);\r
+#endif\r
+\r
+       // Calc interrupt stack\r
+       Os_IsrGetStackInfo(&intStack);\r
+       // TODO: 16 is arch dependent\r
+       Os_Sys.intStack = (void *)((size_t)intStack.top + (size_t)intStack.size - 16);\r
+\r
+       // Init counter.. with alarms and schedule tables\r
+#if OS_COUNTER_CNT!=0\r
+       Os_CounterInit();\r
+#endif\r
+#if OS_SCHTBL_CNT!=0\r
+       Os_SchTblInit();\r
+#endif\r
+\r
+       // Put all tasks in the pcb list\r
+       // Put the one that belong in the ready queue there\r
+       // TODO: we should really hash on priority here to get speed, but I don't care for the moment\r
+       // TODO: Isn't this just EXTENED tasks ???\r
+       for( i=0; i < OS_TASK_CNT; i++) {\r
+               tmpPcbPtr = Os_TaskGet(i);\r
+\r
+               copyPcbParts(tmpPcbPtr,&Os_TaskConstList[i]);\r
+               Os_TaskContextInit(tmpPcbPtr);\r
+               TAILQ_INIT(&tmpPcbPtr->resourceHead);\r
+\r
+#if 0\r
+               Os_AddTask(tmpPcbPtr);\r
+#endif\r
+\r
+               DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmpPcbPtr->pid,tmpPcbPtr->name,tmpPcbPtr->prio);\r
+       }\r
+\r
+       Os_ResourceInit();\r
+\r
+       // Now all tasks should be created.\r
+}\r
+\r
+static void os_start( void ) {\r
+       uint16_t i;\r
+       OsTaskVarType *tmpPcbPtr = NULL;\r
+\r
+       // We will be setting up interrupts,\r
+       // but we don't want them to fire just yet\r
+       Irq_Disable();\r
+\r
+       assert(init_os_called);\r
+\r
+       /* TODO: fix ugly */\r
+       /* Call the startup hook */\r
+       extern struct OsHooks os_conf_global_hooks;\r
+       Os_Sys.hooks = &os_conf_global_hooks;\r
+       if( Os_Sys.hooks->StartupHook!=NULL ) {\r
+               Os_Sys.hooks->StartupHook();\r
+       }\r
+\r
+\r
+#if    (OS_USE_APPLICATIONS == STD_ON)\r
+       /* Start applications */\r
+       Os_ApplStart();\r
+#endif\r
+\r
+\r
+       /* Alarm autostart */\r
+#if OS_ALARM_CNT!=0\r
+       Os_AlarmAutostart();\r
+#endif\r
+\r
+#if OS_SCHTBL_CNT!=0\r
+       Os_SchTblAutostart();\r
+#endif\r
+\r
+       // Set up the systick interrupt\r
+       {\r
+               uint32_t sys_freq = McuE_GetSystemClock();\r
+               Os_SysTickInit();\r
+               Os_SysTickStart(sys_freq/OsTickFreq);\r
+       }\r
+\r
+       /* Find highest Autostart task */\r
+       {\r
+               OsTaskVarType *iterPcbPtr;\r
+               OsPriorityType topPrio = -1;\r
+\r
+               for(i=0;i<OS_TASK_CNT;i++) {\r
+                       iterPcbPtr = Os_TaskGet(i);\r
+                       if(     iterPcbPtr->constPtr->autostart ) {\r
+                               if( iterPcbPtr->activePriority > topPrio ) {\r
+                                       tmpPcbPtr = iterPcbPtr;\r
+                                       topPrio = iterPcbPtr->activePriority;\r
+                               }\r
+                       }\r
+               }\r
+#if 0\r
+               TAILQ_FOREACH(iterPcbPtr,& Os_Sys.pcb_head,pcb_list) {\r
+                       if(     iterPcbPtr->constPtr->autostart ) {\r
+                               if( iterPcbPtr->activePriority > topPrio ) {\r
+                                       tmpPcbPtr = iterPcbPtr;\r
+                                       topPrio = iterPcbPtr->activePriority;\r
+                               }\r
+                       }\r
+               }\r
+#endif\r
+       }\r
+\r
+       // Swap in prio proc.\r
+       {\r
+               // FIXME: Do this in a more structured way.. setting Os_Sys.currTaskPtr manually is not the way to go..\r
+               Os_Sys.currTaskPtr = tmpPcbPtr;\r
+#if    (OS_USE_APPLICATIONS == STD_ON)\r
+               /* Set current application */\r
+               Os_Sys.currApplId = tmpPcbPtr->constPtr->applOwnerId;\r
+#endif\r
+\r
+               // register this auto-start activation\r
+               assert(tmpPcbPtr->activations < tmpPcbPtr->constPtr->activationLimit);\r
+               tmpPcbPtr->activations++;\r
+\r
+               // NOTE! We don't go for os_swap_context() here..\r
+               // first arg(NULL) is dummy only\r
+               Os_TaskSwapContextTo(NULL,tmpPcbPtr);\r
+               // We should not return here\r
+               assert(0);\r
+       }\r
+}\r
+#if 0\r
+static void os_start( void ) {\r
+\r
+}\r
+#endif\r
+\r
+#define TEST_DATA  0x12345\r
+#define TEST_SDATA2    0x3344\r
+volatile uint32_t test_data = TEST_DATA;\r
+volatile uint32_t test_bss = 0;\r
+/* Define if compiler is set to use small data section */\r
+/* #define CC_USE_SMALL_DATA */\r
+\r
+#if defined(CFG_PPC) && defined(__CWCC__)\r
+/* Note! It does not matter if the data is initialized to 0,\r
+ * it still sbss2.
+ */\r
+#if defined(CC_USE_SMALL_DATA)\r
+volatile const int test_sbss2;\r
+#endif\r
+/* Initialized small data */\r
+volatile const int test_sdata2 = TEST_SDATA2;\r
+\r
+#endif\r
+\r
+\r
+#define BAD_LINK_FILE()        while(1) {}\r
+\r
+extern void EcuM_Init();\r
+int main( void )\r
+{\r
+       /* Check link file */\r
+       if (TEST_DATA != test_data) {\r
+               BAD_LINK_FILE();\r
+       }\r
+\r
+       if (test_bss != 0) {\r
+               BAD_LINK_FILE();\r
+       }\r
+\r
+#if defined(CFG_PPC) && defined(__CWCC__)\r
+       /* check sdata2 */\r
+       if (test_sdata2 != TEST_SDATA2) {\r
+               BAD_LINK_FILE();\r
+       }\r
+#endif\r
+\r
+#if defined(CC_USE_SMALL_DATA) && defined(CFG_PPC) && defined(__CWCC__)\r
+       /* check sdata2 */\r
+       if (test_sbss2 != 0) {\r
+               BAD_LINK_FILE();\r
+       }\r
+#endif\r
+\r
+       EcuM_Init();\r
+\r
+}\r
+\r
+/**\r
+ * Starts the OS\r
+ *\r
+ * @param Mode - Application mode to start in\r
+ *\r
+ */\r
+void StartOS(AppModeType Mode) {\r
+\r
+       Os_Sys.appMode = Mode;\r
+\r
+       Os_CfgValidate();\r
+\r
+       os_start();\r
+\r
+       /** @req OS424 */\r
+       assert(0);\r
+}\r
+\r
+/**\r
+ * OS shutdown\r
+ *\r
+ * @param Error - Reason for shutdown\r
+ */\r
+\r
+/** @req OS071 */\r
+void ShutdownOS( StatusType Error ) {\r
+\r
+       if( Os_Sys.hooks->ShutdownHook != NULL ) {\r
+               Os_Sys.hooks->ShutdownHook(Error);\r
+       }\r
+\r
+       Irq_Disable();\r
+       /** @req OS425 */\r
+       while(1) {      }\r
+\r
+}\r
+\r
+\r
+\r