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

📄 main.c

📁 Real Time Operating System for Hi-Tech C compiler.
💻 C
字号:
/************************************************************ 
Copyright (C) 1995-2002 Pumpkin, Inc. and its
Licensor(s). Freely distributable.

$Source: C:\\RCS\\d\\salvo\\demo\\d4\\main.c,v $
$Author: aek $
$Revision: 3.4 $
$Date: 2002-08-04 22:44:20-07 $

Demo program. Runs on Microchip PICDEM-2 (PIC16C77, 
PIC18C452, etc.) and MPLAB-ICD (PIC16F877).

Illustrates several multitasking concepts with Salvo:

	1) Variable task delays.
	2) Effect of task priorities.
	3) Idling hook.
	4) Interrupt-driven system timer.
	
Observe the following:
	
	1) LED shift rate is controlled via potentiometer.
	2) Idle task hook runs often enough to sample
        potentiometer properly.
    3) When TaskMedium() runs (via keypress), it runs
        "flat out". By having TaskMedium() yield while
        it's running, TaskHigh() can run when it needs
        to. Neither TaskLow() nor the idle task can
        run when TaskMedium() is running.
    4) TaskMedium() always runs to completion. The time 
        represents minimum time to do NUM_CTXSWS context 
        switches, with some context switches thrown in when
        high-priority task runs.
    5) Context switches can be placed anywhere in a task.
    6) Delay parameter for OS_Delay() can be variables,
        expressions, etc.

************************************************************/

#include "main.h"
#include <salvo.h>


/************************************************************
****                                                     ****
**                                                         **
Local #defines and function prototypes.

**                                                         **
****                                                     ****
************************************************************/
#define	KEY_DELAY		5		/* number of system		*/
								/*  ticks between key	*/
								/*  reads.				*/
								
#define	TASK_HIGH_DELAY	250		/* for 1Hz @ 4MHz		*/

#define NUM_CTXSWS		20000	/* number of ctxsws for	*/
								/*  TaskOverride().		*/
								
#define LED_PORT_MASK	0x7F	/* bits that medium- 	*/
								/*  and low-priority	*/
								/*  tasks can change.	*/								

/* global variable */			
char delay;

/* function prototypes */
void TaskHigh(void);
void TaskMedium(void);
void TaskLow(void);

/* context-switching labels */
_OSLabel(TaskHigh1)
_OSLabel(TaskMedium1)
_OSLabel(TaskMedium2)
_OSLabel(TaskLow1)


/************************************************************
****                                                     ****
**                                                         **
main()

Initialize relevant hardware registers, initialize Salvo and
create tasks, enable interrupts and start multitasking.

**                                                         **
****                                                     ****
************************************************************/
int main( void )
{
	/* init h/w, etc.							*/
	Init();
	
	/* initialize Salvo.						*/
	OSInit();
	
	/* create tasks.							*/
	OSCreateTask(TaskLow,     OSTCBP(1), 7);
	OSCreateTask(TaskHigh,    OSTCBP(2), 1);
	OSCreateTask(TaskMedium,  OSTCBP(3), 5);
		
	/* enable interrupts.						*/
	OSEi();
	
	/* go!										*/
	for (;;) 
		OSSched();

}


/************************************************************
****                                                     ****
**                                                         **
TaskHigh()

Blinks a single LED continuously -- blink rate does not 
change.

Runs whenever it's not delayed.

Also samples the pot.

**                                                         **
****                                                     ****
************************************************************/
void TaskHigh( void )
{
	static OStypeDelay tmr = TASK_HIGH_DELAY;
	
	
	/* enable A/D converter, inputs only on		*/
	/*  RA0. Start first conversion.			*/
	ADCON1 = ADCON1_INIT;
	ADCON0 = ADCON0_INIT;
	
	for (;;) {
		/* if conversion is complete, update 	*/
		/*  delay and start new conversion.		*/
		if ( !ADGO_BIT ) {
			delay = ADREG;
						
			ADGO_BIT = 1;
		}
		
		/* every TASK_HIGH_DELAY ticks, toggle	*/
		/*  the LED.							*/
		if ( --tmr == 0 ) {
			LED_PORT ^= ~LED_PORT_MASK;
			tmr = TASK_HIGH_DELAY;
		}

		/* delay 1 tick to allow other tasks	*/
		/*  to run, etc.						*/
		OS_Delay(1, TaskHigh1);
	}
}


/************************************************************
****                                                     ****
**                                                         **
TaskMedium()

This task writes directly to the LEDs.

Runs whenever it's not delayed, and when TaskHigh isn't
running.

Once it detects a keypress, it context-switches NUM_CTXSWS
times, and displays the upper 7 bits of the countdown timer.
While context-switching / counting down, only high-priority
task can run.

**                                                         **
****                                                     ****
************************************************************/
void TaskMedium( void )
{
	static int i;
	
	
	for (;;) {
		/* sample key every 5 system ticks.				*/
		OS_Delay(KEY_DELAY, TaskMedium1);	
		
		/* if key is pressed, do NUM_CTXSWS context		*/
		/*  switches, while displaying countdown timer.	*/
		if (!keySW) {
			i = NUM_CTXSWS;
			do {
				LED_PORT &= ~LED_PORT_MASK;
				LED_PORT |= ((i >> 8) & LED_PORT_MASK);
				OS_Yield(TaskMedium2);
			} while (--i);
		}
	}
}


/************************************************************
****                                                     ****
**                                                         **
TaskLow()

This task shifts a single LED through the LEDs at a rate
set by the variable delay, which is controlled by the
potentiometer. 

Runs when it's the highest-priority eligible task, i.e when 
neither TaskMedium() nor TaskHigh() is running.

delay is not allowed to be 0, because OS_Delay(0)
is equivalent to OS_Stop(), and we don't want TaskShiftLED()
to stop running.

**                                                         **
****                                                     ****
************************************************************/
void TaskLow( void )
{
	/* set initial value. Since no other part of this	*/
	/*  program uses imageLED_PORT, we'll keep its 		*/
	/*  scope local to here.							*/
	static char imageLED_PORT = 0x01;
	
	
	/* set LED_PORT for all outputs and turn off all	*/
	/*  its LEDs.										*/
	LED_TRIS = 0x00;	
	LED_PORT = 0x00;	
	
	/* shift the single LED by one digit, with delay	*/
	/*  between shifts specified by delay. Reset bit	*/
	/*  pattern when bit "falls off bit 6." Continue	*/
	/*  forever.										*/
	for (;;) {
		LED_PORT &= ~LED_PORT_MASK;
		LED_PORT |= imageLED_PORT;
		imageLED_PORT = (imageLED_PORT << 1);
		
		if ( imageLED_PORT == (char) ~LED_PORT_MASK )
			imageLED_PORT = 0x01;

		#if OSCOMPILER == OSMPLAB_C18
		if ( delay == 0 ) 
			delay++;
		OS_Delay(delay, TaskLow1);
		#else	
		OS_Delay((delay > 0) ? delay : ++delay, TaskLow1);
		#endif
	}
}


/************************************************************
****                                                     ****
**                                                         **
OSIdlingHook()

Not used.

**                                                         **
****                                                     ****
************************************************************/
void OSIdlingHook( void )
{
	;
}

⌨️ 快捷键说明

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