⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxavr.c

📁 一个小的操作系统包括应用程序很有参考价值
💻 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 + -