简易内核调度设计 --基于TQ2440(ARM9)的实现(1)
来源:互联网 发布:关于网络诈骗的作文800 编辑:程序博客网 时间:2024/04/24 07:16
作者:姜广伟
日期:2010-12-9
邮箱:Guangwei.jiang@gmail.com/jgw2008@126.com
**
1. 概述
**
多任务是现代操作系统的核心功能,深入理解多任务并非易事,但学习者如果能尝试去实现一个简易的多任务程序,对理解操作系统的“多任务”概念会有很大的帮助。若能进一步拓展这个多任务的程序,则可设计一个简易的内核(Kernel)。
本文就是介绍一个十分简易的多任务程序。
实验程序中共有2个任务,Task1和Task2:
Task1中,闪烁LED1灯3次后,主动将CPU使用权切换给Task2;
Task2中,闪烁LED2灯3次后,主动将CPU使用权切换给Task1。
从而,实现2个任务的交替执行。
实验环境说明:
本实验的操作平台为TQ2440(ARM9)开发板,程序代码在S3C2440“SteppingStone”的4KB内部RAM中运行。程序就是利用这4KB的空间来实现多任务的切换。
请选择从NAND Flash启动,并将生成的二进制文件烧到NAND Flash中。
当选择从NAND Flash启动CPU时,CPU会通过内部硬件将NAND Flash开始的4KB字节数据复制到“SteppingStone” 的4KB内部RAM中(此时内部RAM的起始地址是0),然后跳到地址0开始执行。
Task1和Task2的代码如下,
2. 详解设计/实现部分
程序分为3大部分,
**–初始化
–存储模型
–任务切换**
2.1 初始化
程序的初始化很简单,_start是CPU reset后运行的第一段代码。
a. 因为要调用C函数,必须要先设置了SVC模式下的堆栈(CPU reset后,默认进入SVC模式);
b. 为了防止CPU不断自动重启,需要关闭WatchDog;
c. 接下来初始化4个LED灯(关闭4个LED灯);
d. 最后,启动第一个任务Task1。
注意:Task1堆栈的初始化指针指向#4000,它工作在SVC模式中。
初始化代码(_start)如下,
2.2存储模型
Code存放区域: 0x00000000~0x000007FF (2KB);
Task2的堆栈区域: 0x00000C00~0x00000E03(516B);
Task1的堆栈区域: 0x00000E04~0x00000FA3(416B);
TCB指针存放区域: 0x00000FA4~0x00000FFF(92B)。
注意:
a. 栈的增长方向由高地址到低地址;
b. TCB指针存放区域,存放的是Task栈顶指针,如0x0000FFC保存Task1的栈顶指针;0x00000FF8保存Task2的栈顶指针。
存储划分图表如下,
2.3任务切换
运行新任务之前,必须要为每个新任务初始化PCB(Process Control Block)。PCB是一个保留在RAM的数据结构,用于保存所有ARM寄存器的一个副本(见下表)。
任务控制块(PCB, Process Control Block)
测试代码中,任务1是主程序并首先运行,不需要初始化PCB。
任务2运行之前,需要先初始化PCB,初始化代码如下,
其中,函数“TaskCreate”的3个参数含义如下:
void(*Task)(void): Task地址
unsigned long *p_Stack: Task堆栈指针
unsigned long *Task_STK_PTR: 保存Task栈顶指针的地址
下面以Task1切换到Task2为例,来说明任务切换的过程。
第一阶段,保存Task1运行的上下文(Context)。
将PC/LR/R0-R12/CPSR压入堆栈中,然后将栈顶指针保存起来。代码如下,
第二阶段,恢复Task2的运行上下文(Context)。
首先取出Task2的栈顶指针;然后,PSR先出栈并恢复CPSR;接着R0-R12/LR/PC依次出栈。
至此,Task2恢复了之前的运行上下文并接管CPU的控制权。
本文源代码可以从作者的github下载,链接如下
https://github.com/GuangweiJiang/diy_kernel/tree/master/01_TaskSwitch
- 简易内核调度设计 --基于TQ2440(ARM9)的实现(1)
- 简易内核调度设计--基于TQ2440(ARM9)的实现(2)
- 简易内核调度设计 --基于TQ2440(ARM9)的实现(3)
- 简易内核调度设计 --基于TQ2440(ARM9)的实现(4)
- 基于ARM9内核Processor外部NAND FLASH的控制实现
- 基于ARM9内核Processor外部NAND FLASH的控制实现
- 【1】基于TQ2440的MP3设计——【5、裁剪和移植Linux 2.6 内核】
- 基于ARM9的嵌入式Zigbee网关设计与实现
- 基于ARM9嵌入式网管系统的设计与实现
- 关于arm内核编译(基于tq2440)的一些问题
- 基于arm9的linux3.0内核移植
- 基于ARM9的智能车载系统设计
- PXA270-基于ARM9内核Processor外部NAND FLASH的控制实现
- 自用的ARM9(tq2440)的启动代码
- 基于TQ2440的电子相册项目实现
- 《Linux内核设计与实现》- 进程的调度
- Linux内核设计与实现 读书笔记(4)进程的调度
- 基于ARM9+linux2.6内核的键盘驱动初探
- Java中23种设计模式简介
- Qt在pro中添加依赖库的简单方法
- swift----设置图片圆角
- KVC/KVO原理详解及编程指南(转载)
- windows批处理字符串提取
- 简易内核调度设计 --基于TQ2440(ARM9)的实现(1)
- 3D图片轮播
- 关于MCNS/DOCSIS兼容RF接口的RF接口MIB
- Java 8 中新的 Date 和 Time 类入门详解, DateUtil ,以后可以少写几个了,关键是线程安全了
- 第一次使用Android Studio时你应该知道的一切配置
- 191. Number of 1 Bits [easy] (Python)
- unsolved 2 db2 issues
- 如何手动安装VMware Tools? VMvare三种网络模式?
- Spring 3.1中对JSR-330的支持