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

📄 example.c

📁 此代码为NUCLEUS操作系统的原码
💻 C
字号:
/*包含必要的Nucleus PLUS 文件*/
 #include <nucleus.h>

 /*定义应用程序数据结构*/

 NU_TASK 	Task_0;
 NU_TASK 	Task_1;
 NU_TASK 	Task_2;

 NU_TASK 	Task_4;
 NU_TASK 	Task_5;
 NU_QUEUE 	Queue_0;
 NU_SEMAPHORE 	Semaphore_0;
 NU_EVENT_GROUP Event_Group_0;
 NU_MEMORY_POOL System_Memory;

 /*分配全局计数器*/
 unsigned 	Task_Time;
 UNSIGNED 	Task_2_message_received;
 UNSIGNED 	Task_2_ invalid_messages;
 UNSIGNED 	Task_1_messages_sent;
 NU_TASK 	*Who_has_the_resource;
 UNSIGNED 	Event_Detections;

 /*定义引用函数的原型*/
 void task_0(UNSIGNED argc,VOID *argv);
 void task_1(UNSIGNED argc,VOID *argv);
 void task_2(UNSIGNED argc,VOID *argv);
 void task3_and_4(UNSIGNED argc,VOID *argv);
 void task_5(UNSIGNED argc,VOID *argv);
 
void main(void)
{
	/*这是一个汇编函数,处理底层的和目标板相关的初始化。当这个函数完成后,就调用Inc_Initialize		*/
	/*Inc_Initialize是系统初始化函数,所有的组件都被该函数初始化,之后再调用Application_Initialize	*/
	Int_Initialize();/*-->Inc_Initialize(VOID *first_available_memory)-->Application_Initialize()	*/
	
	/*任务调度函数:该函数等待一个变成就绪的线程,当一个线程就绪时,该函数就开始将控制权转移给该线程*/
	TCT_Schedule();
}

/*************************************************************************
*定义应用程序初始化子程序,初始化子程序决定初始化Nucleus PLUS 应用程序环境
*************************************************************************/
 void Application_Initialize(void *first_available_memeory)
 {
	 VOID *pointer;
	
	 /*创建一个系统内存池将用于分配任务堆栈,队列区域等*/
	
	 NU_Create_Memory_Pool(&System_Memory,”SYSTEM”,	first_available_memory,20000,50,NU_FIFO);
	
	 /*创建系统中的每个任务*/
	
	 /*创建任务0*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1333, NU_NO_SUSPEND);
	 NU_Create_Task(&Task_0,TASK_0,task_0,0,NU_NULL,pointer,1000,1,20,NU_PREEMPT,NU_START);
	
	 /*创建任务1*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
	 NU_create_Task(&Task_1,TASK_1,task_1,3,NU_NULL,pointer,1000,10,5,NU_PREEMPT,NU_START);
	
	 /*创建任务2*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1333, NU_NO_SUSPEND);
	 NU_Create_Task(&Task_2,TASK_2,task_2,0,NU_NULL,pointer,1000,13,5,NU_PREEMPT,NU_START);
	
	 /*创建任务3。注意任务4 用的同一个指令区*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
	 NU_Create_Task(&Task_3,TASK_3,task3_and_4,0,NU_NULL,	pointer,1000,5,0,NU_PREEMPT,NU_START);
	
	 /*创建任务4。注意任务3 使用同样的指令区*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
	 NU_Create_Task(&Task_4,TASK_4,task_4,3,NU_NULL,pointer,1000,5,0,NU_PREEMPT,NU_START);
	
	 /*创建任务5*/
	 NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
	 NU_Create_Task(&Task_5,TASK_5,task_5,0,NU_NULL,pointer,1000,7,0,NU_PREEMPT,NU_START);
	
	 /*创建通信队列*/
	 NU_Allocate_Memory(&System_Memory,&pointer,100*sizeof(UNSIGNED),NU_NO_SUSPEND);
	 NU_Create_Queue(&Queue_0,QUEUE_0,pointer,100,NU_FIXED_SIZE,1,NU_FIFO);
	
	 /*创建同步信号量*/
	 NU_Create_Semaphore(&Semaphore_0,SEM_0,1,NU_FIFO);
	
	 /*创建事件标志集*/
	 NU_Create_Event_Group(&Event_Group_0,EVGROUP0);
}

/*****************************************************************
*定义任务0。任务0 每18 个时钟节拍递增一次Task_Time 变量。另外,
*任务0置位任务5 正在等待的事件标志集,每个循环一次反复			
*任务0 无限循环的处理包括连续调用NU_Sleep 和NU_Set_Events。	
*因为NU_Sleep 的调用,任务0 循环每18 个定时器节拍运行一次。	
*****************************************************************/
 void task_0(UNSIGNED argc,VOID *argv)
 {
	
	 STATUS status;
		
	 /*访问argc 和argv 只是为了避免编辑警告*/
	 status = (STATUS) argc + (STATUS)argv;
	
	 /*设置时钟为0。这个时钟每18 个系统定时器节拍为一拍。*/
	 Task_Time = 0;
	
	 while(1)
	 {
		
		 /*休眠18 个定时器节拍。在IND.ASM 中时钟节拍值可编程,且与目标系统的速度有关*/
		 NU_Sleep(18);
		
		 /*递增次数*/
		 Task_Time++;
		
		 /*设置事件标志来消除任务5 的挂起*/   
		 /*任务5优先级低于任务0,在任务0再次运行NU_Sleep调用之前,任务5不会运行*/
		 NU_Set_Events(&Event_Group_0,1,NU_OR);
	 }
 }

/*****************************************************************
*定义队列发送任务。对列满条件和配置文件指定的时间片导致任务挂起。
*任务1 连续发送单个32 位消息到队列0。当管道充满时,任务1挂起,	
*直到队列0空间有效(有可用空间)。任务1的挂起允许任务2 恢复运行。
*****************************************************************/
 void task_1(UNSIGNED argc,void *argv)
 {

	 STATUS status;
	 UNSIGNED Send_Message;
	
	 /*访问argc 和argv 只是为了避免编辑警告*/
	 status = (STATUS)argc + (STATUS)argv;
	
	 /*初始化消息计数器*/
	 Task_1_messages_send = 0;
	
	 /*初始化消息内容。接收器将检查消息内容是否错误。*/
	
	 Send_Message = 0;
	
	 while(1)
	 {
		
		 /*发送消息到Queue_0,任务2 从里面读。注意如果目标队列充满,这个任务挂
		 起直到空间有效*/
		
		 status = NU_Send_To_Queue(&Queue_0,&Send_Message,1,
		 NU_SUSPEND);
		
		 /*确定消息是否发送成功*/
		 if (status == NU_SUCCESS){
		 	Task_1_message_sent++;
		 }
		
		 /*修改下一个发送消息的内容*/
		 Send_Message++;
	}
}

/*****************************************************************
*定义队列接收任务。注意队列空条件和配置文件指定的时间片导致任务挂起 
*任务2 连续从队列0接收单个32 位消息。当队列为空时,任务挂起,直到队
*列0空间有效(有可用消息)。任务1 的挂起允许任务2 恢复运行。				
*****************************************************************/
 void task_2(UNSIGNED argc,VOID *argv)
{

	 STATUS status;
	 UNSIGNED Receive_Message;
	 UNSIGNED received_size;
	 UNSIGNED message_expected;
	
	 /*访问argc 和argv 只是为了避免编辑警告*/
	 status = (STATUS)argc + (STATUS)argv;
	
	 /*初始化消息计数器*/
	 Task_2_message_received = 0;
	
	 /*初始化消息错误计数器*/
	 Task_2_invalid_messages = 0;
	
	 /*初始化消息内容为期望值*/
	 message_expected = 0;
	
	 while(1)
	{
		
		 /*从Queue_0 重新获得任务1 写入的消息,注意如果源队列为空,这个任务挂
		 起知道有东西可用*/
		
		 status = NU_Receive_From_Queue(&Queue_0,&Receive_Message,1,&received_size,NU_SUSPEND);
		
		 /*确定消息是否接收正确*/
		 if (status == NU_SUCCESS){
			Task_2_message_received++;
		 }
		 /*检测消息内容是否与任务期望一致*/
		
		 if ((received_size !=) || (Receive_Message != message_expected)){
		 	Task_2_invalid_messages++;
		 }
		 message_expected++;
	}
}
/*****************************************************************
*Task_3_and_4 只想要单个资源。一旦其中一个任务获得资源,它将在释放
*它之前保持33 个时钟节拍。在这期间,其他任务挂起等待这个资源。注意
*任务3和4都使用同样的代码区但是堆栈不一样。
*****************************************************************/
 void task_3_and_4(UNSIGNED argc,VOID *argv)
 {

	STATUS status;
	
	/*访问argc 和argv 只是为了避免编辑警告*/
	status = (STATUS)argc + (STATUS)argv;
	
	/*循环分配和收回资源*/
	while(1)
	{
		
		/*分配资源。挂起知道它变得有效*/
		status = NU_Obtain_Semaphore(&Semaphore_0,NU_NU_SUSPEND);
		
		/*如果status 为成功,显示这个任务拥有资源*/
		if (status == NU_SUCCESS)
		{
			
			Who_has_the_resource = NU_Create_Task_Pointer();
			
			/*休眠100 个时钟节拍导致其他任务挂起等待资源*/
			
			NU_Sleep(100);
			
			/*释放信号量*/
			NU_Release_Semaphore(&Semaphore_0);
		}
	}
 }

/*****************************************************************
*定义等待任务0 设置事件的任务							
*此任务在一个死循环中等待事件标志被置位。被等待的事件标
*志被任务0 置位。因此,任务5 和任务0 以同样的频率运行	
*****************************************************************/
 void task_5(UNSIGNED argc,VOID *argv)
 {

	 STATUS status;
	 UNSIGNED event_group;
	
	
	 /*访问argc 和argv 只是为了避免编辑警告*/
	 status = (STATUS)argc + (STATUS)argv;
	
	 /*初始化事件跟踪计数器*/
	 Event_Detections = 0;
	
	 /*永远继续这个处理*/
	 while(1)
	 {
		
		/*等待一个事件且消耗它*/
		status = NU_Retrieve_Events(&Event_Group_0,1,NU_OR_CONSUME,&event_group,NU_SUSPEND);
		
		/*如果status 成功,递增计数器*/
		if (status == NU_SUCCESS){
			Event_Detections++;
	 	}
	 }
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -