Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * File: main.c
- * Author: abdullah
- *
- * Created on 10 Haziran 2012 Pazar, 14:43
- */
- #include <xc.h> // Include the header file needed by the compiler
- __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & IOSCFS_4MHZ & BOREN_ON);
- /*
- * INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
- * WDT disabled and can be enabled by SWDTEN bit of the WDTCON register
- * PWRT enabled
- * MCLR pin function is digital input, MCLR internally tied to VDD
- * Program memory code protection is disabled
- * Internal Oscillator Frequency Select bit : 4MHz
- * Brown-out Reset Selection bits : BOR enabled
- */
- /*
- * OS_initializeTask(); definition will copy the PCLATH register to the task's PCLATH , which is held in taskx.pch
- * This will help us hold the PCLATH at the point we yield.
- * After that, it will copy the (PCL register + 8) to current task's PCL which is held in taskx.pcl.
- * 8 is added to PCL because this line plus the "return" takes 8 instructions.
- * We will set the PCL after these instructions, because
- * we want to be in the point after OS_initializeTask when we come back to this task.
- * After all, the function returns without doing anything more. This will initialize the task's PCLATH and PCL.
- */
- #define numberOfTasks 2
- #define OS_initializeTask(x); tasks[x].pch = PCLATH;\
- tasks[x].pcl = PCL + 6;\
- asm("return");
- /*
- * OS_yield(); definition will do the same stuff that OS_initializeTask(); definition do, however
- * it will return to "taskswitcher" label, which is the start of OS_runTasks(); definition.
- */
- #define OS_yield(x); tasks[x].pch = PCLATH;\
- tasks[x].pcl = PCL + 6;\
- asm("goto _taskswitcher");
- /*
- * OS_runTasks(); definition will set the "taskswitcher" label. After that it will change the
- * current task to the next task, by pointing the next item in the linked list of "TCB"s.
- * After that, it will change the PCLATH and PCL registers with the current task's. That will
- * make the program continue the next task from the place it left last time.
- */
- #define OS_runTasks(); asm("_taskswitcher");\
- ++currentTask;\
- if (currentTask > (numberOfTasks - 1))currentTask = 0; \
- PCLATH = tasks[currentTask].pch; \
- PCL = tasks[currentTask].pcl;
- typedef struct _TCB // Create task control block and type define it as "TCB"
- {
- unsigned char pch; // pch register will hold the PCLATH value of the task after the last yield.
- unsigned char pcl; // pcl register will hold the PCL value of the task after the last yield.
- } TCB;
- unsigned char currentTask = 0; // This TCB pointer will point to the current task's TCB.
- TCB tasks[2]; // Define the TCB for task1 and task2.
- void fTask1(void); // Prototype the function for task1.
- void fTask2(void); // Prototype the function for task2.
- void main(void) @ 0x0099
- {
- TRISA = 0; // Set all of the PORTA pins as outputs.
- TRISC = 0; // Set all of the PORTC pins as outputs.
- ANSEL = 0; // Set all of the analog input pins as digital i/o.
- PORTA = 0; // Clear PORTA bits.
- PORTC = 0; // Clear PORTC bits.
- /*
- * Before running the tasks, we should initialize the PCL and PCLATH registers for the tasks.
- * In order to do this, we could have looked up the absolute address with a function pointer.
- * However, it seems like this is not possible with this compiler (or all the x16 PICs?)
- * What this compiler creates is a table of the addresses of the functions and a bunch of GOTOs.
- * This will not let us get the absolute address of the function by doing something like:
- * "currentTask->pcl=low(functionpointer);"
- */
- fTask1(); // Run task1 so that we get the address of it and initialize pch and pcl registers.
- currentTask = currentTask++; // Point the currentTask pointer to the next pointer which
- fTask2(); // is task2. And run task2 so that we get the correct pch and pcl.
- //OS_runTasks(); // Task switcher. See the comments in the definitions above.
- asm("_taskswitcher");
- ++currentTask;
- if (currentTask == 2)currentTask = 0;
- PCLATH = tasks[currentTask].pch;
- PCL = tasks[currentTask].pcl;
- }
- void fTask1(void)
- {
- //OS_initializeTask(0); // Initialize the task
- tasks[0].pch = PCLATH;
- tasks[0].pcl = PCL + 6;
- asm("return");
- while (1)
- {
- PORTA = 0xAA; // Toggle PORTA.0
- //OS_yield(0); // Yield
- tasks[0].pch = PCLATH;
- tasks[0].pcl = PCL + 6;
- asm("goto _taskswitcher");
- PORTA = 0x55; // Toggle PORTA.0
- }
- }
- void fTask2(void)
- {
- //OS_initializeTask(1); // Initialize the task
- tasks[1].pch = PCLATH;
- tasks[1].pcl = PCL + 6;
- asm("return");
- while (1)
- {
- PORTC = 0xAA; // Toggle PORTA.1
- OS_yield(1); // Yield
- PORTC = 0x55; // Toggle PORTA.1
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement