Professional Documents
Culture Documents
David Fischer
February 7, 2007
Project Report David Fischer
Contents
1. Project Idea................................................................................................3
1.1 Approaches ...............................................................................................................3
1.2 Hardware Requirements...........................................................................................3
1.3 Software Requirements ............................................................................................3
2. Approach 1: Running µC/OS-II in Virtual Breadboard ............................4
2.1 Choosing the Target System ...................................................................................4
2.2 Getting the µC/OS-II Code ........................................................................................4
2.3 Compiling µC/OS-II with MPLAB for the PIC18F452 ..............................................4
2.3.1 Compiling Problems .............................................................................................5
2.4 Virtual Breadboard Simulator ..................................................................................7
2.4.1 Virtual Breadboard Problems ...............................................................................7
3. Approach 2: Running µC/OS-II Using Real Hardware.............................8
3.1 Hardware Design.......................................................................................................8
3.2 Running the Basic µC/OS-II Port .............................................................................8
4. Using µC/OS-II for Multitasking..............................................................10
4.1 Digital Input Switches.............................................................................................10
4.2 Source Code............................................................................................................11
4.2.1 Tasks..................................................................................................................11
4.2.2 Final Code Size ..................................................................................................11
5. Conclusion and Outlook.........................................................................12
References...................................................................................................13
Appendix: Source Code of test.c ...............................................................14
1. Project Idea
Microchip’s 8-bit low-cost PIC microcontrollers feature a powerful architecture, flexible
memory technologies, and comprehensive easy-to-use development tools [1]. The author
has used PIC microcontrollers many times and is still fascinated by the simplicity of their
architecture and instruction set.
Porting µC/OS-II to a PIC microcontroller is the first goal of this project. The µC/OS-II
website [2] indicates that there is a possibility to port µC/OS-II to the PIC18F
microcontroller family.
For convenience reasons, a software simulator (Virtual Breadboard) for emulating some
popular PIC microcontrollers without using any hardware will be used. Also, there is a free
student version of the C-compiler that is tailored for the PIC18F family.
After porting µC/OS-II, the ultimate goal of this project is to create, run, and manage
several independent tasks with different priorities in µC/OS-II on a PIC. The tasks will be
simple counters and their progress will be observed on a display.
1.1 Approaches
There are two possible approaches for completing this project:
• Set up the hardware exclusively with virtual components in Virtual Breadboard.
• Set up the hardware on a real breadboard with real components.
If possible the first approach will be used. If there are any problems with the first approach,
the second approach is an equally good but more time-consuming backup solution.
Define one large RAM grp instead of six smaller grps, change stack
uc-18f452.lkr Linker Script
size to 0x30
Table 2-1: µC/OS-II File Structure
After resolving the problems, the project has successfully been compiled.
The first problem has been resolved by the Virtual Breadboard developer, the second and
the third could not be resolved so far. Another more serious problem is that the µC/OS-II
function OSStart(), which starts the counting task in the multitask environment, is not
working. This might have something to do with the other Virtual Breadboard bugs, but it
may also be another problem. If the counting task is called in a foreground/background
environment, it works fine.
At this point, the author decided to use a real breadboard to set up the hardware instead of
Virtual Breadboard.
VCC
U1
2 11
3 RA0/AN0 VDD 32
4 RA1/AN1 VDD
5 RA2/AN2/VREF- 15
6 RA3/AN3/VREF+ RC0/T1OSO/T1CKI 16
7 RA4/T0CKI RC1/T1OSI/CCP2 17
14 RA5/AN4/SS/LVDIN RC2/CCP1 18
RA6/OSC2/CLKO RC3/SCK/SCL 23
33 RC4/SDI/SDA 24
34 RB0/INT0 RC5/SDO 25
35 RB1/INT1 RC6/TX/CK 26
36 RB2/INT2 RC7/RX/DT U2 R 150 V1
37 RB3/CCP2 19 7 13 7 3
38 RB4 RD0/PSP0 20 1 A a 12 6 a C 8
VCC 39 RB5/PGM RD1/PSP1 21 2 B b 11 4 b C
40 RB6/PGC RD2/PSP2 22 6 C c 10 2 c
Q1 12M RB7/PGD RD3/PSP3 27 D d 9 1 d
13 RD4/PSP4 28 VCC 4 e 15 9 e
OSC1/CLKI RD5/PSP5 29 5 BI f 14 10 f
1 RD6/PSP6 30 3 LE g 5 g
C1 C2 MCLR/VPP RD7/PSP7 LT dp
22p 22p 12 8 16 8 LSHD-5503
31 VSS RE0/RD/AN5 9 VDD GND
VSS RE1/WR/AN6 10 CD4511B
RE2/CS/AN7
PIC18F452
U1 R1 150 V1
7 13 7 3
1 RD6/PSP6 30 D d 9 1 d
C1 C2 MCLR/VPP RD7/PSP7 VCC 4 e 15 9 e
22p 22p 12 8 5 BI f 14 10 f
31 VSS RE0/RD/AN5 9 3 LE g 5 g
VSS RE1/WR/AN6 10 LT dp
RE2/CS/AN7 16 8 LSHD-5503
PIC18F452 VDD GND
2/7/07
CD4511B
Project Report David Fischer
Assigned priorities should be either 1, 2, or 3. Priority 0 is reserved for the task manager.
Also, the priority assigned to each task has to be unique at all times. This is a requirement
of µC/OS-II. Therefore, if priorities can’t be changed at the exact same time (which is
hardly possible with this design), all tasks should be turned off when priorities are changed.
However, there is no need to stop µC/OS-II for this matter.
1
The two digital input switches for each task’s priority make up the two bits of a binary number. Bit 0
0 1
represents the LSB (2 = 1), whereas bit 1 represents the MSB (2 = 2) of the binary number. Setting these
two bits to a combination of either logic 0 or logic 1 assigns the priorities 0, 1, 2, or 3.
4.2.1 Tasks
Four tasks are created. The first task with the highest priority is the task manager. It
assigns the priorities for the other three tasks on-the-fly by reading from the digital input
switches. This process works as follows:
• Determine the task’s priorities by reading from the digital input switches
• If priorities have changed assign dummy priorities to all three tasks (this is to ensure
that no tasks have the same priority at any given time)
• Assign the new priorities to the three tasks
• Delay for some time to yield the CPU to the other tasks
• Start over
The other three tasks are all the same. They count from 0 to 9 in an endless loop if they
are switched on. If they are switched off they delay until they are switched on again. This is
to yield the CPU to the other tasks. Tasks with higher priorities always preempt tasks with
lower priorities. As long as higher priority tasks are running, lower priority tasks cannot run.
Therefore, a higher priority task has to be turned off if a lower priority task wants to run.
References
[1] Microchip Technology, Inc., Website.
http://www.microchip.com
[5] Labrosse, Jean J., MicroC OS II: The Real Time Kernel, Newnes, June 2002.
http://www.amazon.com/exec/obidos/tg/detail/-/1578201039
/*****************************************************************************
* Filename : test.c *
* Purpose : Implement 3 test tasks and a task manager for uC/OS-II *
* Project : NPU / CE589B *
* MCU : PIC18F452 *
* Language : C *
* Compiler : MPLAB IDE v7.40 / MPLAB C18 v3.02 *
* *
* Programmed by : David Fischer *
* *
* Version/Date : 1.0 / 07-1-16 *
* Changes : *
*****************************************************************************/
//----------------------------------------------------------------------------
// Config
//----------------------------------------------------------------------------
#include "includes.h"
#include "timers.h"
#include "delays.h"
// PIC configuration
#pragma config OSC = HS
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF
// Number of tasks
#define TASK_NUMBER 3
//----------------------------------------------------------------------------
// Global variables
//----------------------------------------------------------------------------
INT8U prio_old[TASK_NUMBER+1];
INT8U prio_new[TASK_NUMBER+1];
//----------------------------------------------------------------------------
// Initialize I/O ports
//----------------------------------------------------------------------------
void port_init(void)
{
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
ADCON1 = 0x07; // disable analog inputs
INTCONbits.RBIE = 0; // disable RB interrupt
TRISB = 0x00; // outputs
TRISC = 0x00; // outputs
TRISD = 0x00; // outputs
}
//----------------------------------------------------------------------------
// Initialize timer
//----------------------------------------------------------------------------
void timer_init(void)
{
OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_4);
WriteTimer0(-10000);
}
//----------------------------------------------------------------------------
// Determine task priorities from PORTA
//----------------------------------------------------------------------------
void get_prio(void)
{
prio_old[1] = prio_new[1];
prio_new[1] = PORTA & 0x03;
prio_old[2] = prio_new[2];
prio_new[2] = PORTA >> 2 & 0x03;
prio_old[3] = prio_new[3];
prio_new[3] = PORTA >> 4 & 0x03;
}
//----------------------------------------------------------------------------
// 1. Task: Task manager
//----------------------------------------------------------------------------
while (1)
{
get_prio();
OSTimeDly(100);
//----------------------------------------------------------------------------
// 2. Task: Counter 1
//----------------------------------------------------------------------------
while (1)
{
while (PORTEbits.RE0 == 0) // Task on/off switch
{
OSTimeDly(100);
}
Delay10KTCYx(100);
PORTB = 0x00;
}
}
//----------------------------------------------------------------------------
// 3. Task: Counter 2
//----------------------------------------------------------------------------
while (1)
{
while (PORTEbits.RE1 == 0) // Task on/off switch
{
OSTimeDly(100);
}
Delay10KTCYx(100);
PORTC = 0x00;
}
}
//----------------------------------------------------------------------------
// 4. Task: Counter 3
//----------------------------------------------------------------------------
while (1)
{
while (PORTEbits.RE2 == 0) // Task on/off switch
{
OSTimeDly(100);
}
Delay10KTCYx(100);
PORTD = 0x00;
}
}
//----------------------------------------------------------------------------
// Main function
//----------------------------------------------------------------------------
void main(void)
{
port_init();
timer_init();
get_prio();
OSInit();
OSStart();
}