forked from jorya/raw-os
-
Notifications
You must be signed in to change notification settings - Fork 0
/
raw_sched.c
225 lines (161 loc) · 5.26 KB
/
raw_sched.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
raw os - Copyright (C) Lingjun Chen(jorya_txj).
This file is part of raw os.
raw os is free software; you can redistribute it it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.
raw os 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 Lesser General Public License
along with this program. if not, write email to jorya.txj@gmail.com
---
A special exception to the LGPL can be applied should you wish to distribute
a combined work that includes raw os, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/* 2012-4 Created by jorya_txj
* xxxxxx please added here
*/
#include <raw_api.h>
void raw_sched(void)
{
RAW_SR_ALLOC();
/*if it is in interrupt or system is locked, just return*/
if (raw_int_nesting || raw_sched_lock) {
return;
}
USER_CPU_INT_DISABLE();
get_ready_task(&raw_ready_queue);
/*if highest task is currently task, then no need to do switch and just return*/
if (high_ready_obj == raw_task_active) {
USER_CPU_INT_ENABLE();
return;
}
TRACE_TASK_SWITCH(raw_task_active, high_ready_obj);
CONTEXT_SWITCH();
USER_CPU_INT_ENABLE();
}
/*
************************************************************************************************************************
* Init raw os
*
* Description: This function is called to init raw os.
*
* Arguments :None
* -----
*
*
*
* Returns RAW_U16: RAW_SUCCESS.
*
* Note(s)
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_os_init(void)
{
TRACE_INIT();
raw_os_active = RAW_OS_STOPPED;
run_queue_init(&raw_ready_queue);
/*Init the tick heart system*/
tick_list_init();
/*Init the task debug head list*/
list_init(&(raw_task_debug.task_head));
#if (CONFIG_RAW_USER_HOOK > 0)
raw_os_init_hook();
#endif
/*Start the first idle task*/
raw_task_create(&raw_idle_obj, (RAW_U8 *)"idle_task", 0,
IDLE_PRIORITY, 0, idle_stack,
IDLE_STACK_SIZE, raw_idle_task, 1);
/*The timer module need mutex*/
#if (CONFIG_RAW_TIMER > 0)
raw_timer_init();
raw_mutex_create(&timer_mutex, (RAW_U8 *)"timer_mutex", RAW_MUTEX_INHERIT_POLICY, 0);
#endif
/*tick task to reduce interrupt time*/
#if (CONFIG_RAW_TICK_TASK > 0)
tick_task_start();
#endif
/*For statistic*/
#if (RAW_CONFIG_CPU_TASK > 0)
cpu_task_start();
#endif
return RAW_SUCCESS;
}
/*
************************************************************************************************************************
* Start raw os first task
*
* Description: This function is called to start raw os first task.
*
* Arguments :None
* -----
*
*
*
* Returns RAW_U16: RAW_SYSTEM_ERROR.
*
* Note(s) This function shoud not returned!
*
*
************************************************************************************************************************
*/
RAW_OS_ERROR raw_os_start(void)
{
if (raw_os_active == RAW_OS_STOPPED) {
get_ready_task(&raw_ready_queue);
/*done it here, so doesn't need do it in raw_start_first_task*/
raw_task_active = high_ready_obj;
raw_os_active = RAW_OS_RUNNING;
raw_start_first_task();
}
else {
return RAW_OS_RUNNING;
}
return RAW_SYSTEM_ERROR;
}
#if (CONFIG_SCHED_FIFO_RR > 0)
void calculate_time_slice(RAW_U8 task_prio)
{
RAW_TASK_OBJ *task_ptr;
LIST *head;
RAW_SR_ALLOC();
head = &raw_ready_queue.task_ready_list[task_prio];
RAW_CRITICAL_ENTER();
/*if ready list is empty then just return because nothing is to be caculated*/
if (is_list_empty(head)) {
RAW_CRITICAL_EXIT();
return;
}
/*Always look at the first task on the ready list*/
task_ptr = raw_list_entry(head->next, RAW_TASK_OBJ, task_list);
/*SCHED_FIFO does not has timeslice, just return*/
if (task_ptr->sched_way == SCHED_FIFO) {
RAW_CRITICAL_EXIT();
return;
}
/*there is only one task on this ready list, so do not need to caculate time slice*/
/*idle task must satisfy this condition*/
if (head->next->next == head) {
RAW_CRITICAL_EXIT();
return;
}
if (task_ptr->time_slice) {
task_ptr->time_slice--;
}
/*if current active task has time_slice, just return*/
if (task_ptr->time_slice) {
RAW_CRITICAL_EXIT();
return;
}
/*Move current active task to the end of ready list for the same priority*/
move_to_ready_list_end(&raw_ready_queue, task_ptr);
/*restore the task time slice*/
task_ptr->time_slice = task_ptr->time_total;
RAW_CRITICAL_EXIT();
}
#endif