1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
28 //#include "arch_offset.h"
\r
32 #include "ext_config.h"
\r
34 #include "internal.h"
\r
36 _Bool os_pcb_pid_valid( pcb_t *restrict pcb ) {
\r
37 return ( pcb->pid > Oil_GetTaskCnt() ) ? 0 : 1;
\r
40 * Start an extended task.
\r
42 * - Grab the internal resource for the process
\r
43 * - Set it running state.
\r
44 * - Start to execute the process
\r
47 void os_proc_start_extended( void ) {
\r
50 // TODO: Get internal resource
\r
53 pcb = os_get_curr_pcb();
\r
54 os_resource_get_internal();
\r
55 os_pcb_make_running(pcb);
\r
57 os_arch_first_call();
\r
59 // If we have a extented process that that exits, we end up here
\r
60 // See OS052,OS069, Autosar SWS
\r
61 ERRORHOOK(E_OS_MISSINGEND);
\r
63 /* TODO: Terminate the task */
\r
68 * Start an basic task.
\r
69 * See extended task.
\r
72 void os_proc_start_basic( void ) {
\r
75 // TODO: Get internal resource
\r
78 pcb = os_get_curr_pcb();
\r
79 os_resource_get_internal();
\r
80 os_pcb_make_running(pcb);
\r
81 os_arch_first_call();
\r
84 // ERRORHOOK(E_OS_MISSINGEND);
\r
88 * Setup the context for a pcb. The context differs for different arch's
\r
89 * so we call the arch dependent functions also.
\r
90 * The context at setup is always a small context.
\r
92 * @param pcb Ptr to the pcb to setup context for.
94 void os_setup_context( pcb_t *pcb ) {
\r
97 /* Find bottom of the stack so that we can place the
\r
100 * stack bottom = high address. stack top = low address
\r
102 bottom = (uint8_t *)pcb->stack.top + pcb->stack.size;
\r
103 pcb->stack.curr = bottom;
\r
104 // TODO: aligments here..
\r
105 // TODO :use function os_arch_get_call_size() ??
\r
107 // Make some space for back-chain.
\r
109 // Set the current stack so that it points to the context
\r
110 pcb->stack.curr = bottom - os_arch_get_sc_size();
\r
112 os_arch_setup_context(pcb);
\r
116 * Search for a specific task in the pcb list.
\r
118 * @param tid The task id to search for
119 * @return Ptr to the found pcb or NULL
121 pcb_t *os_find_task( TaskType tid ) {
\r
124 /* TODO: Implement this as an array */
\r
125 TAILQ_FOREACH(i_pcb,& os_sys.pcb_head,pcb_list) {
\r
126 if(i_pcb->pid == tid ) {
\r
135 * Adds a pcb to the list of pcb's
138 TaskType os_add_task( pcb_t *pcb ) {
\r
141 Irq_Save(msr); // Save irq status and disable interrupts
\r
143 pcb->pid = os_sys.task_cnt;
\r
144 // Add to list of PCB's
\r
145 TAILQ_INSERT_TAIL(& os_sys.pcb_head,pcb,pcb_list);
\r
148 Irq_Restore(msr); // Restore interrupts
153 #define PRIO_ILLEGAL -100
\r
154 // TODO: we can't have O(n) search here.. hash on prio instead
\r
157 * Find the top priority task. Even the running task is included.
\r
162 pcb_t *os_find_top_prio_proc( void ){
\r
164 pcb_t *top_prio_pcb = NULL;
\r
165 prio_t top_prio = PRIO_ILLEGAL;
\r
167 os_isr_printf(D_TASK,"os_find_top_prio_proc\n");
\r
169 TAILQ_FOREACH(i_pcb,& os_sys.ready_head,ready_list) {
\r
170 // all ready task are canidates
\r
171 if( i_pcb->state & (ST_READY|ST_RUNNING)) {
\r
172 if( top_prio != PRIO_ILLEGAL ) {
\r
173 if( i_pcb->prio > top_prio ) {
\r
174 top_prio = i_pcb->prio;
\r
175 top_prio_pcb = i_pcb;
\r
178 top_prio = i_pcb->prio;
\r
179 top_prio_pcb = i_pcb;
\r
185 os_isr_printf(D_TASK,"Found %s\n",top_prio_pcb->name);
\r
187 return top_prio_pcb;
\r
191 * Used at startup to initialize a pcb. Is sometimes
\r
192 * used to restore the state of a basic process.
\r
194 * @param pcb The pcb to make virgin
197 void os_pcb_make_virgin( pcb_t *pcb ) {
\r
198 if( pcb->autostart ) {
\r
199 os_pcb_make_ready(pcb);
\r
201 pcb->state = ST_SUSPENDED;
\r
204 /* TODO: cleanup resource here ?? */
\r
208 os_setup_context(pcb);
\r
212 pcb_t *os_find_higher_priority_task( prio_t prio ) {
\r
214 pcb_t *h_prio_pcb = NULL;
\r
215 prio_t t_prio = prio;
\r
217 TAILQ_FOREACH(i_pcb,& os_sys.ready_head,ready_list) {
\r
218 if( i_pcb->prio > t_prio ) {
\r
219 t_prio = i_pcb->prio;
\r
220 h_prio_pcb = i_pcb;
\r