this is for holding javascript data
Fernando Freitas Alves added file codes/LAB2C.simple.C
about 8 years ago
Commit id: 56117dd1ebdb86edd84526d20e7d3d1bdcc6d4b7
deletions | additions
diff --git a/codes/LAB2B.C b/codes/LAB2B.C
new file mode 100644
index 0000000..247e5c1
--- /dev/null
+++ b/codes/LAB2B.C
...
// Definitions
#define TASK_STK_SIZE 512 // Size of each task's stacks (# of bytes)
#define N_TASKS 3 // Number of identical tasks
#define MAX_COUNT 100 // Maximum count value
#define TMA5_MASK 0x20 // Mask for Timer A5 in TACSR
#define TMA6_MASK 0x40 // Mask for Timer A6 in TACSR
#define TMA7_MASK 0x80 // Mask for Timer A7 in TACSR
// Redefine uC/OS-II configuration constants as necessary
#define OS_MAX_EVENTS N_TASKS // Maximum number of events (semaphores, queues, mailboxes)
#define OS_MAX_TASKS 3+N_TASKS // Maximum number of tasks system can create (less stat and idle tasks)
#define OS_TASK_STAT_EN 1 // Enable statistics task creation
#define OS_TICKS_PER_SEC 128 // Number of ticks per second
#use "ucos2.lib"
// Task and function prototypes
void InitTimerInt(); // Setup Timer A interrupts
void Tmr_A_isr(); // Timer A interrupt service routine
void UpdateStat(); // Display RTOS statistics
void Task(void *data); // Function prototype of tasks
void TaskStart(void *data); // Function prototype of startup task
void DispStr(int x, int y, char *s);
char count_TMRA5;
char count_TMRA6;
char count_TMRA7;
int display_count[N_TASKS];
UBYTE TaskData[N_TASKS]; // Parameters to pass to each task
OS_EVENT *TimerSem[N_TASKS];
void main (void)
{
auto UBYTE i;
brdInit(); // Initialize MCU baord
OSInit(); // Initialize uC/OS-II
OSTaskCreate(TaskStart, (void *)0, TASK_STK_SIZE, 10);
for (i = 0 ; i < N_TASKS ; i++)
TimerSem[i] = OSSemCreate(0); // Semaphores for timer 5,6,7
OSStart(); // Start multitasking
}
void TaskStart (void *data)
{
auto UBYTE i;
// Create N_TASKS identical tasks
for (i = 0; i < N_TASKS; i++) {
TaskData[i] = i; // Each task has its own number
OSTaskCreate(Task, (void *)&TaskData[i], TASK_STK_SIZE, 11+i);
}
InitTimerInt(); // Setup Timer A internal interrupts
OSStatInit(); // Initialize statistics task
DispStr(0, 12, "#Tasks : xxxxx CPU Usage: xxxxx %");
DispStr(0, 13, "#Task switch/sec: xxxxx");
DispStr(0, 14, "<-PRESS 'Q' TO QUIT->");
for (;;) {
UpdateStat();
OSTimeDly(OS_TICKS_PER_SEC); // Wait one second
}
}
// Tasks
nodebug void Task (void *data)
{
auto UBYTE err;
auto UBYTE num;
auto char display[128];
// Prepare the STDIO screen
num = *((int *)data) + 5;
sprintf(display, "Number of TMRA%d interrupts: xxxxx (x100)", num);
DispStr(20, num, display);
for (;;) {
num = *((int *)data);
display[0] = '\0';
OSSemPend(TimerSem[num], 0, &err); // Wait for Semaphore to be posted
sprintf(display, "%5d", display_count[num]);
DispStr(48, num+5, display);
}
}
// Interrupt routine
nodebug root interrupt void Tmr_A_isr()
{
char TMRA_status; // This will hold the interrupt flags
TMRA_status = RdPortI(TACSR); // Read interrupt flags and store to TMRA_status
// Timer A demultiplexing
if (TMRA_status & TMA7_MASK) { // if Timer A7 has trigered
count_TMRA7++;
if (count_TMRA7 == MAX_COUNT) { // if Timer A7 has interrupted the CPU 100 times
display_count[2]++; // increment corresponding display counter
count_TMRA7 = 0; // clear Timer A7 counter
OSSemPost(TimerSem[2]); // Post a semaphore for Timer A7 counter
}
}
if (TMRA_status & TMA6_MASK) { // if Timer A6 has trigered
count_TMRA6++; // increment Timer A6 counter
if (count_TMRA6 == MAX_COUNT) { // if Timer A6 has interrupted the CPU 100 times
display_count[1]++; // increment coressponding display counter
count_TMRA6 = 0; // clear Timer A6 counter
OSSemPost(TimerSem[1]); // Post a semaphore for Timer A6 Counter
}
}
if (TMRA_status & TMA5_MASK) { // if Timer A5 has trigered
count_TMRA5++; // increment Timer A5 counter
if (count_TMRA5 == MAX_COUNT) { // if Timer A5 has interrupted the CPU 100 times
display_count[0]++; // increment corresponding display counter
count_TMRA5 = 0; // clear the Timer A5 counter
OSSemPost(TimerSem[0]); // Post a semaphore for Timer A5 Counter
}
}
OSIntExit();
}
// Helper functions
void InitTimerInt()
{
auto UBYTE i;
count_TMRA5 = 0;
count_TMRA6 = 0;
count_TMRA7 = 0;
for (i = 0; i < N_TASKS; i++)
display_count[i] = 0;
// Setup internal interrupt and set up timer A
SetVectIntern(0x0A, Tmr_A_isr); // Set up timer A interrupt vector
WrPortI(TAT7R, &TAT7RShadow, 0x3F); // Set TMRA7 to count down from 63
WrPortI(TAT6R, &TAT6RShadow, 0x7F); // Set TMRA6 to count down from 127
WrPortI(TAT5R, &TAT5RShadow, 0xFF); // Set TMRA5 to count down from 255
WrPortI(TAT1R, &TAT1RShadow, 0xFF); // Set TMRA1 to count down from 255
WrPortI(TACR, &TACRShadow, 0xE1); // Clock TMRA5-7 by TMRA1 and set interrupt priority to 1
WrPortI(TACSR, &TACSRShadow, 0xE1); // Enable TMRA5-7 and main clock for Timer A
}
void UpdateStat()
{
char key, s[50];
sprintf(s, "%5d", OSTaskCtr); // Display #tasks running
DispStr(18, 12, s);
#if OS_TASK_STAT_EN
sprintf(s, "%5d", OSCPUUsage); // Display CPU usage in %
DispStr(36, 12, s);
#endif
sprintf(s, "%5d", OSCtxSwCtr); // Display avg #context switches per 5 seconds
DispStr(18, 13, s);
OSCtxSwCtr = 0;
if (kbhit()) { // See if key has been pressed
key = getchar();
if (key == 0x71 || key == 0x51) // Yes, see if it's the q or Q key
exit(0);
}
}
void DispStr (int x, int y, char *s)
{
x += 0x20;
y += 0x20;
printf ("\x1B=%c%c%s", x, y, s);
}
diff --git a/codes/LAB2C.C b/codes/LAB2C.C
deleted file mode 100644
index 2756f1c..0000000
--- a/codes/LAB2C.C
+++ /dev/null
...
// LAB 2 part C. This program counts Timer B interrupts and during the lab session will be modified to display the interrupt overhead
// uC/OS-II configuration constants
#define TASK_STK_SIZE 512 // Size of each task's stacks (# of bytes)
#define OS_MAX_EVENTS 1 // Maximum number of events (semaphores, queues, mailboxes)
#define OS_MAX_TASKS 4 // Maximum number of tasks system can create (less stat and idle tasks)
#define OS_TASK_STAT_EN 1 // Enable statistics task creation
#define OS_TICKS_PER_SEC 128 // Number of ticks per second
#use "ucos2.lib"
// Task and function prototypes
void TaskStart(void *data); // Function prototype of startup task
void Task(void *data); // Function prototype of tasks
void InitTimerInt(); // Setup Timer B interrupts
void Tmr_B_isr(); // Timer B interrupt service routine
void UpdateStat(); // Display RTOS statistics
void DispStr(int x, int y, char *s);
// Variable declarations
OS_EVENT *TimerSem; // Timer semaphore
int int_count; // This variable will count Timer B interrupts
int display_int_count; // This variable will increment for every 1000 Timer B interrupts
int Timer_B_value; // This variable will hold the current contents of the Timer B count registers
void main (void)
{
brdInit(); // Initialize MCU baord
OSInit(); // Initialize uC/OS-II
OSTaskCreate(TaskStart, (void *)0, TASK_STK_SIZE, 10);
TimerSem = OSSemCreate(0); // Semaphore for the timer
OSStart(); // Start multitasking
}
void TaskStart (void *data)
{
OSTaskCreate(Task, (void *)0, TASK_STK_SIZE, 11);
InitTimerInt(); // Setup Timer B internal interrupts
OSStatInit(); // Initialize statistics task
DispStr(0, 12, "#Tasks : xxxxx CPU Usage: xxxxx %");
DispStr(0, 13, "#Task switch/sec: xxxxx");
DispStr(0, 14, "<-PRESS 'Q' TO QUIT->");
for (;;) {
UpdateStat();
OSTimeDly(OS_TICKS_PER_SEC); // Wait one second
}
}
// Tasks
nodebug void Task (void *data)
{
auto UBYTE err;
auto char display[128];
auto char key;
// Prepare the STDIO screen
display[0] = '\0';
sprintf(display, "Number of Timer B interrupts: xxxxx (x1000)");
DispStr(5, 2, display);
display[0] = '\0';
sprintf(display, "Timer B overhead: xxxxx x(PCLK/16 cycles)"); //Time at start of ISR minus time of ISR call (0x15E)
DispStr(5, 4, display);
for (;;) {
OSSemPend(TimerSem, 0, &err); // Wait for Semaphore to be posted
display[0] = '\0';
sprintf(display, "%5d", display_int_count);
DispStr(35, 2, display);
display[0] = '\0';
sprintf(display, "%5d", Timer_B_value-350);
DispStr(23, 4, display);
}
}
// Setup Timer B interrupts
void InitTimerInt()
{
int_count = 0;
display_int_count = 0;
Timer_B_value = 0;
// Set up Timer B B1 interrupt
SetVectIntern(0x0B, Tmr_B_isr); // Set up Timer B interrupt vector
WrPortI(TBCR, &TBCRShadow, 0x09); // Clock Timer B with (perclk/16), priority 1
WrPortI(TBM1R, NULL, 0x40); // Set up match register(s) to 10-bit value 0x15E
WrPortI(TBL1R, NULL, 0x5E); // Set up match register(s) to 10-bit value 0x15E
WrPortI(TBCSR, &TBCSRShadow, 0x03); // Enable Timer B and B1 match interrupt
}
// Timer B interrupt service routine
nodebug root interrupt void Tmr_B_isr()
{
int TBCMR_status, TBCLR_status;
char TMRB_status;
TMRB_status = RdPortI(TBCSR); // This clears the interrupt flag.
WrPortI(TBM1R, NULL, 0x40); // Set up match register(s) to 10-bit value 0x15E (350)
WrPortI(TBL1R, NULL, 0x5E); // Set up match register(s) to 10-bit value 0x15E (350)
int_count++; // Increment interrupt counter
if (int_count == 1000) { // Divide increment counter by 1000
display_int_count++;
int_count = 0;
}
/* During your lab session, you will modify the ISR to calculate the interrupt overhead. To do this you must
1. Read the current time value in the TBCMR-TBCLR register pair. Scale and add properly to give an accurate value.
2. Subtract the time at which the interrupt was generated: 0x15E = 350 (or TBM1R=0x40, TBL1R=0x5E)
3. Interrupt overhead will be displayed by the background process
*/
TBCLR_status = RdPortI(TBCLR);
TBCMR_status = RdPortI(TBCMR);
if (!(TBCLR_status & 0x80) && ((TBCLR_status ^ RdPortI(TBCLR)) & 0x80))
TBCMR_status--;
OSIntExit();
}
// Helper functions
void UpdateStat()
{
char key, s[50];
sprintf(s, "%5d", OSTaskCtr); // Display #tasks running
DispStr(18, 12, s);
#if OS_TASK_STAT_EN
sprintf(s, "%5d", OSCPUUsage); // Display CPU usage in %
DispStr(36, 12, s);
#endif
sprintf(s, "%5d", OSCtxSwCtr); // Display avg #context switches per 5 seconds
DispStr(18, 13, s);
OSCtxSwCtr = 0;
if (kbhit()) { // See if key has been pressed
key = getchar();
if (key == 0x71 || key == 0x51) // Yes, see if it's the q or Q key
exit(0);
}
}
// Set the STDIO cursor location and display a string
void DispStr(int x, int y, char *s)
{
x += 0x20;
y += 0x20;
printf ("\x1B=%c%c%s", x, y, s);
}
diff --git a/codes/LAB2C.simple.C b/codes/LAB2C.simple.C
new file mode 100644
index 0000000..d8dc294
--- /dev/null
+++ b/codes/LAB2C.simple.C
...
// LAB 2 part C. This program counts Timer B interrupts and during the lab session will be modified to display the interrupt overhead
// Variable declarations
int int_count; // This variable will count Timer B interrupts
int display_int_count; // This variable will increment for every 1000 Timer B interrupts
int Timer_B_value; // This variable will hold the current contents of the Timer B count registers
// Function prototype
void Tmr_B_isr(); // Timer B interrupt service routine
void DispStr(int x, int y, char *s); // Display strings on computer monitor
main()
{
// Initializations
auto char display[128];
auto char key;
brdInit();
int_count = 0;
display_int_count = 0;
Timer_B_value = 0;
// Set up Timer B B1 interrupt
SetVectIntern(0x0B, Tmr_B_isr); // Set up Timer B interrupt vector
WrPortI(TBCR, &TBCRShadow, 0x0A); // Clock Timer B with (perclk/16), priority 2
WrPortI(TBM1R, NULL, 0x40); // Set up match register(s) to 10-bit value 0x15E
WrPortI(TBL1R, NULL, 0x5E); // Set up match register(s) to 10-bit value 0x15E
WrPortI(TBCSR, &TBCSRShadow, 0x03); // Enable Timer B and B1 match interrupt
// This is the background process. It repeatedly updates the computer monitor with the values of the interrupt count, and the overhead
while (1) {
// Update computer monitor
display[0] = '\0';
sprintf(display, "Number of Timer B interrupts = %d (x1000)", display_int_count);
DispStr(5, 2, display);
display[0] = '\0';
sprintf(display, "Timer B overhead = %d x(PCLK/16 cycles)", Timer_B_value-350); //Time at start of ISR minus time of ISR call (0x15E)
DispStr(5, 4, display);
if (kbhit()) { // See if key has been pressed
key = getchar();
if (key == 0x71 || key == 0x51) // Yes, see if it's the q or Q key
exit(0);
}
}
}
// Timer B interrupt service routine
nodebug root interrupt void Tmr_B_isr()
{
int TBCMR_status, TBCLR_status;
char TMRB_status;
TMRB_status = RdPortI(TBCSR); // This clears the interrupt flag.
WrPortI(TBM1R, NULL, 0x40); // Set up match register(s) to 10-bit value 0x15E (350)
WrPortI(TBL1R, NULL, 0x5E); // Set up match register(s) to 10-bit value 0x15E (350)
int_count++; // Increment interrupt counter
if (int_count == 1000) { // Divide increment counter by 1000
display_int_count++;
int_count = 0;
}
/* During your lab session, you will modify the ISR to calculate the interrupt overhead. To do this you must
1. Read the current time value in the TBCMR-TBCLR register pair. Scale and add properly to give an accurate value.
2. Subtract the time at which the interrupt was generated: 0x15E = 350 (or TBM1R=0x40, TBL1R=0x5E)
3. Interrupt overhead will be displayed by the background process
*/
TBCLR_status = RdPortI(TBCLR);
TBCMR_status = RdPortI(TBCMR);
if (!(TBCLR_status & 0x80) && ((TBCLR_status ^ RdPortI(TBCLR)) & 0x80))
TBCMR_status--;
}
// Set the STDIO cursor location and display a string
void DispStr(int x, int y, char *s)
{
x += 0x20;
y += 0x20;
printf ("\x1B=%c%c%s", x, y, s);
}