📄 mxavr.c
字号:
//************************************************
//
// MX RTOS AVR 嵌入式操作系统 V1.10 C 内核文件
// 作者:罗国祥 DEF edisonluo@sina.com
// 本人收回本内核所有权
// 2004年3月1日
//************************************************
//#include <avr/io.h>
//************************************************
//
// 内核设置声明
//
//************************************************
#define SP_POINTER SP //声明堆栈指针寄存器
#define TASK_NUMBER 4 //声明要建立的线程数量 (用户修改部分 用来确定用户所建立的线程数目)
//************************************************
//
// 内核外部接口函数声明
//
//************************************************
extern void OS_GET_TO_TASK_INT(void); //汇编函数跳入下一条线程(中断模式)
extern void OS_GET_TO_TASK_DISP(void); //汇编函数跳入下一条线程(普通模式)
extern void START_TICK_POINT(void); //汇编函数第一次启动时跳入调度入口点
extern void OS_DISP_TIME_P(void); //汇编函数处理线程延时保存切换接口
//************************************************
//
// 内核接口函数声明
//
//************************************************
//建立线程函数
void OS_CREATE_TASK(void *task, //线程入口地址
unsigned char task_ready, //线程状态
unsigned char task_pri, //线程优先级
unsigned int task_sp //线程分配堆栈
);
//建立调度系统环境
void OS_CREATE_ATTEMPER(void *task, //线程入口地址
unsigned int task_sp //线程分配堆栈
);
//下一条线程处理函数(中断模式)
void OS_GETTO_NEXT_TASK_INT(void);
//下一条线程处理函数(普通模式)
void OS_GETTO_NEXT_TASK_DISP(void);
//系统调度器
void OS_ATTEMPER(void);
//启动RTOS
inline void OS_START_TICK(void);
//重新初始化系统时钟
void OS_RELOAD_TICK(void);
//保存当前线程SP指针
void OS_SAVE_TASK_SP(unsigned int task_sp);
//线程延时函数
void OS_TASK_DLY(unsigned char disp_time); //参数disp_time为等待时钟节拍数
//时钟节拍处理过程
void OS_DLY_TIME_DEC(void);//用来处理线程的等待时间
//获取线程ID
unsigned char OS_GET_TASK_ID(void *task);
//************************************************
//
// 内核变量声明
//
//************************************************
//线程TCB //储存每条线程的固有特性
volatile typedef struct OS_TASK_TCB
{
unsigned int task_address; //线程入口地址
unsigned char task_pri; //优先级
unsigned char task_ready; //线程状态
unsigned int task_sp; //线程堆栈指针
unsigned char task_wait_clock; //线程等待时钟
unsigned char task_on_activation; //线程活动状态
};
//建立线程TCB数组
volatile static struct OS_TASK_TCB OS_TASK_ARRY[TASK_NUMBER];//TASK_NUMBER为定义数值,为最大线程数
//记录线程已建立数
volatile static unsigned char OS_TASK_INT_USED=0;
//记录现在线程ID
volatile static unsigned char os_now_task;
//记录下一条线程ID
volatile static unsigned char os_next_task;
//************************************************
//
// 内核函数实现
//
//************************************************
//建立线程函数
void OS_CREATE_TASK(void *task, //线程入口地址
unsigned char task_ready, //线程状态
unsigned char task_pri, //线程优先级
unsigned int task_sp //线程分配堆栈
)
{
unsigned int temp_address;//处理线程入口地址临时变量
unsigned char *sp_temp; //初始化线程堆栈临时指针
OS_TASK_ARRY[OS_TASK_INT_USED].task_address=(unsigned int)task; //赋予线程地址
OS_TASK_ARRY[OS_TASK_INT_USED].task_ready=task_ready; //赋予线程状态
OS_TASK_ARRY[OS_TASK_INT_USED].task_pri=task_pri; //赋予线程优先级
//初始化线程堆栈
temp_address=(unsigned int)task;
sp_temp=(unsigned int*)task_sp; //给指针赋值
*sp_temp=(unsigned char)temp_address; //赋值入口地址低8位
--sp_temp;
*sp_temp=(unsigned char)(temp_address>>8); //赋值入口地址高8位
--sp_temp;
*sp_temp--=0;//R0
*sp_temp--=0;//R1
*sp_temp--=0;//R2
*sp_temp--=0;//R3
*sp_temp--=0;//R4
*sp_temp--=0;//R5
*sp_temp--=0;//R6
*sp_temp--=0;//R7
*sp_temp--=0;//R8
*sp_temp--=0;//R9
*sp_temp--=0;//R10
*sp_temp--=0;//R11
*sp_temp--=0;//R12
*sp_temp--=0;//R13
*sp_temp--=0;//R14
*sp_temp--=0;//R15
*sp_temp--=0;//R16
*sp_temp--=0;//R17
*sp_temp--=0;//R18
*sp_temp--=0;//R19
*sp_temp--=0;//R20
*sp_temp--=0;//R21
*sp_temp--=0;//R22
*sp_temp--=0;//R23
*sp_temp--=0;//R24
*sp_temp--=0;//R25
*sp_temp--=0;//R26
*sp_temp--=0;//R27
*sp_temp--=0;//R28
*sp_temp--=0;//R29
*sp_temp--=0;//R30
*sp_temp--=0;//R31
*sp_temp=0x80;//SREG每条线程的总中断开关都为开
OS_TASK_ARRY[OS_TASK_INT_USED].task_sp=(unsigned int)sp_temp-1; //赋予线程堆栈指针
OS_TASK_INT_USED=OS_TASK_INT_USED+1; //修改已使用的线程数目
}
//下一条线程处理函数(中断模式)
void OS_GETTO_NEXT_TASK_INT(void)
{
void *p; //声明入口指针
SP_POINTER=OS_TASK_ARRY[os_next_task].task_sp; //转移SP指针到下一条线程
os_now_task=os_next_task; //修改当前线程标识
p=&OS_GET_TO_TASK_INT; //获取汇编进入线程入口函数地址
goto *p; //进入汇编进入线程函数
}
//下一条线程处理函数(普通模式)
void OS_GETTO_NEXT_TASK_DISP(void)
{
void *p; //声明入口指针
SP_POINTER=OS_TASK_ARRY[os_next_task].task_sp; //转移SP指针到下一条线程
os_now_task=os_next_task; //修改当前线程标识
p=&OS_GET_TO_TASK_DISP; //获取汇编进入线程入口函数地址
goto *p; //进入汇编进入线程函数
}
//保存线程SP指针
void OS_SAVE_TASK_SP(unsigned int task_sp)
{
OS_TASK_ARRY[os_now_task].task_sp=task_sp; //保存当前线程的SP指针
}
//系统调度器
void OS_ATTEMPER(void)
{
unsigned char loop_task_arry; //求出下一条线程的循环变量
unsigned char task_high_pri=0xff; //求出最高优先权临时变量
//为经检验 原来值为0XFF
os_next_task=TASK_NUMBER-1; //预设下一条线程为最后ID线程
for (loop_task_arry=0;loop_task_arry<TASK_NUMBER;loop_task_arry++)
{
if( (OS_TASK_ARRY[loop_task_arry].task_ready==1)&&
(OS_TASK_ARRY[loop_task_arry].task_wait_clock==0))
{
if (OS_TASK_ARRY[loop_task_arry].task_pri<task_high_pri)
{
task_high_pri=OS_TASK_ARRY[loop_task_arry].task_pri;
os_next_task=loop_task_arry;
}
}
}
}
//线程等待时钟节拍处理过程
void OS_DLY_TIME_DEC(void)
{
unsigned char loop_i;
for (loop_i=0;loop_i<TASK_NUMBER;loop_i++)
{
if (OS_TASK_ARRY[loop_i].task_wait_clock!=0)
{
OS_TASK_ARRY[loop_i].task_wait_clock--;
}
}
}
//线程延时函数
void OS_TASK_DLY(unsigned char disp_time)
{
OS_TASK_ARRY[os_now_task].task_wait_clock=disp_time;//设置当前线程等待时钟节拍数
OS_DISP_TIME_P(); //进入汇编线程等待处理过程
}
//获取线程ID
unsigned char OS_GET_TASK_ID(void *task)
{
unsigned char loop_i;
for (loop_i=0;loop_i<TASK_NUMBER;loop_i++)
{
if (OS_TASK_ARRY[loop_i].task_address==(unsigned int)task)
{
return loop_i;
}
}
}
//************************************************
//
// 以下是用户使用时需要修改的代码部分
// (主要用来确定时钟节拍)
//************************************************
//启动RTOS
inline void OS_START_TICK(void)
{
void *p; //获取汇编函数第一次启动时跳入调度入口点的地址临时指针(用户不必理会)
SREG=SREG|0X80; //开总中断 (用户可能需要修改部分)
TIMSK=TIMSK|0X01; //开时钟0中断 (用户可能需要修改部分)
TCNT0=0X80; //设置时钟初值 (用户可能需要修改部分)
TCCR0=TCCR0|0X03; //启动时钟0 (用户可能需要修改部分)
p=&START_TICK_POINT; //获取汇编函数第一次启动时跳入调度入口点地址 (用户不必理会)
goto *p; //跳入汇编函数第一次启动时跳入调度入口点 (用户不必理会)
}
//重新初始化系统时钟
void OS_RELOAD_TICK(void)
{
TCNT0=0X80; //重新装入定时器 (用户可能需要修改部分)
}
//用户不需要理会一下代码,是作者本人编写时遗留下来的测试代码
/*
//************************************************
//
// 用户程序
//
//************************************************
void task_1(void);
void task_2(void);
void task_3(void);
void task_4(void);
//可重入函数
void dispt(void)
{
unsigned int i;
for (i=0;i<0x01ff;i++);
}
void task_1(void)
{
for (;;)
{
PORTD=PORTD^0X01;
dispt();
OS_TASK_DLY(1);
}
}
void task_2(void)
{
for (;;)
{
PORTD=PORTD^0X02;
dispt();
OS_TASK_DLY(1);
}
}
void task_3(void)
{
for (;;)
{
PORTD=PORTD^0X04;
dispt();
OS_TASK_DLY(1);
}
}
void task_4(void)
{
for (;;)
{
PORTD=PORTD^0X08;
dispt();
//OS_TASK_DLY(1);
}
}
int main (void)
{
void *p;
OS_CREATE_TASK(&task_1,1,0,SP_POINTER-120);
OS_CREATE_TASK(&task_2,1,1,SP_POINTER-320);
OS_CREATE_TASK(&task_3,1,2,SP_POINTER-520);
OS_CREATE_TASK(&task_4,1,255,SP_POINTER-720);
p=&OS_START_TICK;
goto *p;
for (;;);
return 0;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -