/******************************************************************************
* *
* 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. This file and program are licensed *
* under the GNU Lesser General Public License Version 3, 29 June 2007. *
* The complete license can be accessed from the following location: *
* http://opensource.org/licenses/lgpl-3.0.html *
* *
* Author: Yun Li (yunli.open@gmail.com) *
* Date: 05/22/2010 *
* *
******************************************************************************/
/******************************************************************************
REVISION HISTORY
================
Date Version Name Description
---------- ------- ------------ -------------------------------------------
---------- ------- ------------ -------------------------------------------
******************************************************************************/
//lint -esym(728, g_scheduler_locked_count, g_statistics)
#include "console.h"
#include "clib.h"
#include "task.h"
#include "idle.h"
#include "errtask.h"
#include "clock.h"
#include "hook.h"
#define TASK_PRIORITY_LEVELS BITS_SUPPORTED
#define TASK_LAST_INDEX (TASK_PRIORITY_LEVELS - 1)
#define TASK_PRIORITY_LOWEST TASK_LAST_INDEX
#define IDLE_TASK_PRIORITY TASK_PRIORITY_LOWEST
#define MAGIC_NUMBER_TASK 0x5441534BL
// keep this in line with stack_unit_t
#define STACK_WIDTH_IN_BYTES 4
#define STACK_WIDTH_SHIFT4BYTE 2
#define MAGIC_NUMBER_STACK 0xDEAD5AA5L
#define is_invalid_handle(_handle) (((_handle) == null) || \
((_handle)->magic_number_ != MAGIC_NUMBER_TASK))
typedef struct {
statistic_t scheduled_;
statistic_t overflowed_;
statistic_t invalid_handle_;
} task_statistic_t;
static task_t g_task_pool [TASK_PRIORITY_LEVELS];
task_bitmap_t g_ready_bitmap;
static task_handle_t g_priority_map [TASK_PRIORITY_LEVELS];
static device_handle_t g_tick_handle;
static int g_scheduler_locked_count;
static dll_t g_allocated_task;
static task_statistic_t g_statistics;
static task_handle_t g_task_running;
static task_handle_t g_task_idle;
static task_context_t g_start_context;
static bool g_multitasking_started;
// this is the entry function for all tasks, it calls the entry function setting
// by the user via task_start ()
static void task_main ()
{
task_handle_t handle = g_task_running;
global_interrupt_enable (INTERRUPT_ENABLED);
// the entry function should not return, otherwise, it means the task is
// going to be exited
handle->entry_ (handle->name_, handle->argument_);
// delete the task if the entry function returns, task_delete () could
// return an error code if this is the second time to delete it, so, always
// ignore return value
(void) task_delete (handle);
}
static void task_timer_callback (timer_handle_t _handle, void *_arg)
{
task_handle_t p_task = (task_handle_t)_arg;
interrupt_level_t level;
UNUSED (_handle);
level = global_interrupt_disable ();
if (TASK_STATE_WAITING == p_task->state_) {
(void) task_state_change (p_task, TASK_STATE_READY);
p_task->ecode_ = ERROR_T (ERROR_TASK_WAIT_TIMEOUT);
}
global_interrupt_enable (level);
}
error_t task_state_change (task_handle_t _handle, task_state_t _new_state)
{
error_t ecode = 0;
if (_handle->state_ == _new_state) {
return 0;
}
switch (_new_state)
{
case TASK_STATE_CREATED:
{
#define TIMER_PREFIX "Task:"
char timer_name [NAME_MAX_LENGTH + 1] = TIMER_PREFIX;
// initialize the stack with value of MAGIC_NUMBER_STACK
stack_unit_t *p_unit = (stack_unit_t *)_handle->stack_base_;
int count = _handle->stack_size_ >> STACK_WIDTH_SHIFT4BYTE;
while (count > 0) {
*p_unit ++ = MAGIC_NUMBER_STACK;
count --;
}
context_init (&_handle->context_, _handle->stack_base_,
_handle->stack_size_, (address_t) task_main);
strncpy (&timer_name [sizeof (TIMER_PREFIX)], _handle->name_,
sizeof (timer_name) - (sizeof (TIMER_PREFIX) + 1));
timer_name [sizeof (timer_name) - 1] = 0;
ecode = timer_alloc (&_handle->timer_, timer_name, TIMER_TYPE_INTERRUPT);
if (0 != ecode) {
return ecode;
}
}
break;
case TASK_STATE_READY:
{
if (TASK_STATE_RUNNING == _handle->state_) {
break;
}
if (timer_is_started (_handle->timer_)) {
(void) timer_stop (_handle->timer_, null);
}
task_bitmap_bit_set (&g_ready_bitmap, _handle->priority_);
g_priority_map [_handle->priority_] = _handle;
}
break;
case TASK_STATE_RUNNING:
{
}
break;
case TASK_STATE_SUSPENDING:
{
if (timer_is_started (_handle->timer_)) {
(void) timer_stop (_handle->timer_, &_handle->timeout_);
}
task_bitmap_bit_clear (&g_ready_bitmap, _handle->priority_);
}
break;
case TASK_STATE_WAITING:
{
if (_handle->timeout_ != 0) {
(void) timer_start (_handle->timer_, _handle->timeout_,
task_timer_callback, _handle);
_handle->timeout_ = 0;
}
task_bitmap_bit_clear (&g_ready_bitmap, _handle->priority_);
}
break;
case TASK_STATE_DELETED:
{
task_bitmap_bit_clear (&g_ready_bitmap, _handle->priority_);
(void) timer_free (_handle->timer_);
}
break;
}
_handle->state_ = _new_state;
return 0;
}
void task_schedule (preschedule_callback_t _callback)
{
interrupt_level_t level;
task_handle_t running, successor;
bool overflowed = false;
level = global_interrupt_disable ();
if (!g_multitasking_started) {
global_interrupt_enable (level);
return;
}
if (is_in_interrupt () || g_scheduler_locked_count != 0) {
global_interrupt_enable (level);
return;
}
successor = g_priority_map [task_bitmap_lowest_bit_get (&g_ready_bitmap)];
if (successor == g_task_running) {
global_interrupt_enable (level);
return;
}
running = g_task_running;
g_task_running = successor;
if (0 == is_stack_overflowed (running, &overflowed)) {
if (overflowed) {
console_print ("\n\nError: stack overflow for task \"%s\"\n\n",
running->name_);
(void) task_suspend (running);
g_statistics.overflowed_ ++;
}
}
if (TASK_STATE_RUNNING == running->state_) {
(void) task_state_change (running, TASK_STATE_READY);
}
(void) task_state_change (successor, TASK_STATE_RUNNING);
g_statistics.scheduled_ ++;
successor->stats_scheduled_ ++;
if (null != _callback) {
_callback (running, successor);
}
task_switch_hook_traverse (running, successor);
context_switch (&running->context_, &successor->context_);
global_interrup
没有合适的资源?快使用搜索试试~ 我知道了~
ClearRTOS示例代码
5星 · 超过95%的资源 需积分: 10 30 下载量 177 浏览量
2013-06-10
15:33:02
上传
评论
收藏 64KB GZ 举报
温馨提示
共110个文件
h:44个
c:40个
makefile:15个
ClearRTOS 示例代码。李云书籍示例代码。“实时”操作系统示例代码。
资源推荐
资源详情
资源评论
收起资源包目录
ClearRTOS示例代码 (110个子文件)
task.c 24KB
timer.c 17KB
clib.c 16KB
heap.c 14KB
device.c 11KB
mpool.c 9KB
queue.c 8KB
syncobj.c 8KB
unitest_dll.c 7KB
mutex.c 7KB
dll.c 7KB
semaphore.c 6KB
hook.c 6KB
event.c 6KB
module.c 6KB
unitest_task.c 5KB
taskvar.c 5KB
interrupt.c 5KB
main.c 5KB
unitest_clib.c 5KB
main.c 4KB
bitmap.c 4KB
main.c 4KB
main.c 4KB
context.c 4KB
clock.c 4KB
main.c 4KB
console.c 4KB
fifo.c 4KB
inventory.c 3KB
ctrlc.c 3KB
idle.c 3KB
unitest_bitmap.c 3KB
dllht.c 3KB
error.c 3KB
alignment.c 2KB
injector.c 2KB
unitest_dllht.c 2KB
ioport.c 2KB
mlocation.c 2KB
COPYING3 7KB
err2str.cpp 6KB
unitest.h 6KB
task.h 5KB
interrupt.h 4KB
module.h 4KB
dll.h 3KB
device.h 3KB
config.h 3KB
syncobj.h 3KB
fifo.h 3KB
timer.h 3KB
heap.h 3KB
mpool.h 3KB
errsync.h 3KB
errtask.h 3KB
dllht.h 3KB
queue.h 2KB
error.h 2KB
mutex.h 2KB
hook.h 2KB
context.h 2KB
event.h 2KB
bitmap.h 2KB
alignment.h 2KB
primitive.h 2KB
semaphore.h 2KB
errdev.h 2KB
main.h 2KB
injector.h 2KB
errheap.h 2KB
clock.h 2KB
ioport.h 2KB
clib.h 2KB
console.h 2KB
errtmr.h 2KB
errmpool.h 2KB
mlocation.h 2KB
offset.h 2KB
ctrlc.h 2KB
taskvar.h 2KB
errmod.h 2KB
idle.h 2KB
errclock.h 2KB
errcon.h 2KB
errctrlc.h 2KB
au-sm123.lnt 12KB
co-gnu3.lnt 11KB
options.lnt 950B
std.lnt 147B
Makefile 6KB
Makefile 1KB
Makefile 341B
Makefile 334B
Makefile 269B
Makefile 265B
Makefile 265B
Makefile 265B
Makefile 264B
Makefile 256B
共 110 条
- 1
- 2
资源评论
- yunsiwocao2014-08-29光盘读不了才来下的,东西不错,学习下
金风
- 粉丝: 13
- 资源: 42
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功