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

📄 bugsamp.c

📁 CMEX source code RTOS for atmel atmega128
💻 C
字号:
/* the following program does really nothing, except to show the
user different function calls and how to set them up. */

#include <cxfuncs.h>
#include <iom103.h> 
#include <string.h>

#define TSK6_EVENT1 0x0001	/* task 6 event bit 0 */
#define TSK6_EVENT2 0x0002	/* task 6 event bit 1 */
#define TSK6_EVENT3 0x0004	/* task 6 event bit 2 */

#define RESOURCE0	0	/* resource 0 number */

#define MBOX0 0		/* mailbox 0 number */
#define MBOX1 1		/* mailbox 1 number */

#define CYCLIC0 0		/* cyclic timer 0 number */
#define CYCLIC1 1		/* cyclic timer 1 number */


byte task1_slot;	/* task 1 global slot number */
byte task2_slot;	/* task 2 global slot number */
byte task3_slot;	/* task 3 global slot number */
byte task4_slot;	/* task 4 global slot number */
byte task5_slot;	/* task 5 global slot number */
byte task6_slot;	/* task 6 global slot number */
byte task7_slot;	/* task 7 global slot number */
byte task8_slot;	/* task 8 global slot number */

byte t0_cnt;		/* used by interrupt, for counter */
byte go_ahead;		/* used by interrupt, to determine when to send messages */

const char int_mesg[] = {"interrupt mesg"};	/* message that interrupt will send */

byte toggle;		/* used by task 7 and 8 */

/* some messages */

char *mesg_out[5] = { "hello world1",
							"hello world2",
							"hello world3",
							"hello world4",
							"hello world5" };
byte *mesg_in1;	/* message in pointers */
byte *mesg_in2;

byte queue1[20 * 1];	/* queue */

struct {		/* not used in demo, but shows user proper struture for
					fixed memory block */
	byte *dmp_ptr;
	byte array1[10*3];
	} mem1_b;

byte *mem1;

void task1();
void task2();
void task3();
void task4();
void task5();
void task6();
void task7();
void task8();
void common_error();


void task1()
{
	byte status;
	word16 cntr;

	mesg_in1 = K_Mesg_Get(MBOX0);	/* go get message, mesg_in should be NULL */
	status = K_Task_Start(task2_slot);	/* trigger task 2 to start */
	mesg_in1 = K_Mesg_Wait(MBOX0,0);		/* now, lets wait for message */
		for (cntr = 0; cntr < 55000; cntr++)
			;		/* just eat up some time, so as to have CMXBug
						TIME ANALYSIS show task doing something. This
						also will simulate task 1 doing some processing */
	K_Mesg_Ack_Sender();							/* ack sender, will be task 2 */
	status = K_Mesg_Send(MBOX1,mesg_out[0]);	/* now send message to mailbox 1 */
	do {
		mesg_in1 = K_Mesg_Get(MBOX0);	/* go retrieve additional messages */
		} while (mesg_in1);			/* if not NULL, then message retrieved */
	if (K_Resource_Get(RESOURCE0) == K_OK)	/* go see if resource 0 available */	
		status = K_Resource_Release(RESOURCE0);		/* now, release it */
	status = K_Resource_Wait(RESOURCE0,0);		/* go get it again, but wait if need be */
	status = K_Task_Start(task5_slot);	/* trigger task 5 */
	K_Task_Wait(3);							/* show that task 5 will wait for resource */
	status = K_Resource_Release(RESOURCE0);			/* now release resource */
	status = K_Task_Start(task3_slot);	/* trigger task 3 */
	K_Task_End();	/* done, go back to IDLE state */
}
void task2()
{
	byte status;
	word16 cntr;

	mesg_in2 = K_Mesg_Wait(MBOX1,2);	/* wait for message, will time out */
	status = K_Mesg_Send_Wait(MBOX0,0,mesg_out[0]);	/* now send message, and wit for reply */
	mesg_in2 = K_Mesg_Wait(MBOX1,0);	/*	now wait for message from mailbox 1 */
	cntr = 0;
	do {
		status = K_Mesg_Send(0,mesg_out[cntr]);	/* send 5 messages */ 
		} while (++cntr != 5);
	for (cntr = 0; cntr < 30000; cntr++)
		;		/* just eat up some time, so as to have CMXBug
					TIME ANALYSIS show task doing something. This
					also will simulate task 2 doing some processing */
	K_Task_End();	/* now end task, put into IDLE state */
}
void task3()
{
	byte status;
	byte queue_byte;

	K_Que_Create(20,1,queue1,0);	/* create 1'st queue */
	queue_byte = 0x31;		/* one way to pass to queue */
	K_Que_Add_Top(0,&queue_byte);	/* add to top of queue */
	K_Que_Add_Bottom(0,"2");	/* add to bottom of queue, another way */
	queue_byte = 0x33;
	K_Que_Add_Top(0,&queue_byte);	/* add to top of queue */
	status = K_Que_Add_Bottom(0,"4"); /* add to bottom of queue, another way */
	K_Task_Wait(4);					/* wait 4 SYSTEM TICKS */
	status = K_Que_Get_Top(0,&queue_byte);	/* go remove from queue top */
	status = K_Que_Get_Bottom(0,&queue_byte);	/* go remove from queue bottom */
	status = K_Que_Get_Top(0,&queue_byte);	/* go remove from queue top */
	status = K_Que_Get_Bottom(0,&queue_byte);	/* go remove from queue bottom */
	status = K_Que_Get_Bottom(0,&queue_byte);	/* go remove from queue top,
													should be "K_QUE_EMPTY */
	K_Task_Start(task4_slot);		/* go fire up task 4 now */
	K_Task_End();		/* let task end, becomes IDLE */
}

void task4()
{
	byte status;

	while(1)
		{
		status = K_Task_Wait(0);	/* wait till task 8 wakes this task */
		/* ... */
		}
	K_Task_End();	/* really NOT needed here, but always good to have
						just incase user removes endless loop */
}

void task5()
{
	byte status;
	byte ctr;

	status = K_Resource_Wait(RESOURCE0,0);	/* wait for resource 0 */
	status = K_Resource_Release(RESOURCE0);		/* now release it */
	K_OS_Slice_On();		/* now turn time slicing on */
	status = K_Task_Start(task7_slot);	/* go fire up task 7 now */
	status = K_Task_Start(task8_slot);	/* go fire up task 8 now */
	go_ahead = 1;			/* let interrupt now pass message to this task */

	for (ctr = 0; ctr < 10; ctr++ )	/* loop 10 times */
		{
		mesg_in1 = K_Mesg_Wait(MBOX0,0);		/* wait for message, from mailbox 0 */
		if (strcmp(mesg_in1,int_mesg))
			{
			while(1)
				{
				;	/* make sure correct address passed. */
				}
			}
		}
	go_ahead = 0;			/* disable interrupts passing more messages */
	do {
	mesg_in1 = K_Mesg_Get(MBOX0);		/* just in case interrupt sent additional
											messages, before task woke up and cleared
											go_ahead variable. FLUSH BUFFER */
	} while(mesg_in1);
	K_Task_End();		/* let task end, becomes IDLE */
}

void task6()
{
	word16 events;

	while(1)
		{
		/*
		Note: the following assumes the user will NOT wake this task
		using the CMXBug functions, while waiting for the event to be
		set by the cyclic timers. If the user DOES wake this task
		using the CMXBug WAKE function, then common_error will be
		branched to.
		*/
		if ((events = K_Event_Wait(TSK6_EVENT1,30,2)) != TSK6_EVENT1)	/* wait for event 1 */
			common_error();											/* should match */
		if ((events = K_Event_Wait(TSK6_EVENT2,30,2)) != TSK6_EVENT2)	/* wait for event 2 */
			common_error();											/* should match */
		if ((events = K_Event_Wait(TSK6_EVENT3,40,2)) != 0)		/* wait for event 3 */
			common_error();											/* should time out */
		}
	K_Task_End();	/* really NOT needed here, but always good to have
						just incase user removes endless loop */
}

void task7()
{
	byte ctr;

	ctr = 0;
	while(1)	/* endless loop */
		{
		if (!toggle)	/* this way task 8 will toggle 'toggle' */
			{
			toggle = 1;
			if (++ctr == 10)	/* do 10 iterations */
				break;			/* break out of loop */
			}
		}
	K_Task_End();		/* let task end, becomes IDLE */
}
void task8()
{
	byte status;
	byte ctr;

	ctr = 0;
	while(1)	/* endless loop */
		{
		if (toggle)		/* this way task 7 will toggle 'toggle' */
			{
			toggle = 0;
			if (++ctr == 10)	/* do 10 iterations */
				break;			/* break out of loop */
			}
		}
	status = K_Task_Wake(task4_slot);	/* now go wake task 4 up, should be sleeping */
	K_Task_End();		/* let task end, becomes IDLE */
}

void common_error()
{
	while(1)
		{
		;
		}
}

main()
{
	byte status;
	K_OS_Init();	 /* initialize ram and things */
	status = K_Task_Create(5,&task1_slot,task1,256,32);	/* create task 1 */
	status = K_Task_Name(task1_slot,"TASK1");		/* Name for task */
	status = K_Task_Create(3,&task2_slot,task2,256,32);	/* create task 2 */
	status = K_Task_Name(task2_slot,"TASK2");		/* Name for task */
	status = K_Task_Create(6,&task3_slot,task3,256,32);	/* create task 3 */
	status = K_Task_Name(task3_slot,"TASK3");		/* Name for task */
	status = K_Task_Create(2,&task4_slot,task4,256,32);	/* create task 4 */
	status = K_Task_Name(task4_slot,"TASK4");		/* Name for task */
	status = K_Task_Create(4,&task5_slot,task5,256,32);	/* create task 5 */
	status = K_Task_Name(task5_slot,"TASK5");		/* Name for task */
	status = K_Task_Create(4,&task6_slot,task6,256,32);	/* create task 6 */
	status = K_Task_Name(task6_slot,"TASK6");		/* Name for task */
	status = K_Task_Create(0xfe,&task7_slot,task7,256,32);	/* create task 7 */
	status = K_Task_Name(task7_slot,"TASK7");		/* Name for task */
	status = K_Task_Create(0xfe,&task8_slot,task8,256,32); /* create task 8 */
	status = K_Task_Name(task8_slot,"TASK8");		/* Name for task */
	status = K_Task_Start(task1_slot);	/* trigger task 1 */
	status = K_Task_Start(task6_slot);	/* trigger task 2 */
	status = K_Timer_Create(CYCLIC0,0,task6_slot,TSK6_EVENT1);	/* set up cyclic timer 0 */
	status = K_Timer_Start(CYCLIC0,10,10);	/* now start cyclic timer 0 */
	status = K_Timer_Create(CYCLIC1,0,task6_slot,TSK6_EVENT2);	/* set up cyclic timer 1 */
	status = K_Timer_Start(CYCLIC1,15,15);	/* now start cyclic timer 1 */

	/*
	the following will set up the CMX timer tick. When the interrupt
	happens, the interrupt code will properly call the K_OS_Intrp_Entry
	assembly lanquage routine, call the K_OS_Tick_Update function, then call
	the K_OS_Intrp_Exit assembly routine. Set for 20MHZ crystal
	*/

	TIMSK = 0x02;	/* enable timer 0 compare interrupt */
	TCCR0 = 0x0C;	/* select TCK0 / 64 and auto clear when compare occurs */
	OCR0 = 0xa0;	/* select compare value */

	K_OS_Start();			/* enter CMX RTOS */
}


⌨️ 快捷键说明

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