Home | | Embedded Systems Design | Program listing- Real-time without a RTOS

Chapter: Embedded Systems Design : Real-time without a RTOS

Program listing- Real-time without a RTOS

This contains the logging program, complete with comments that describe its operation. These com-ments are easy to spot as they are in bold text.

Program listing

 

This contains the logging program, complete with comments that describe its operation. These comments are easy to spot as they are in bold text.

 

#include      <stdio.h>

 

#include      <stdlib.h>

 

#include      <string.h>

 

#include      <dos.h>

 

#include      <dir.h>

 

#include      <alloc.h>

 

#include      <conio.h>

 

#include      <time.h>

 

#define TRUE       0x01

 

#define FALSE     0x00

 

#define DISPLAY  0x00

 

#define DATALOG  0x01

 

#define FILECOPY 0x02

 

/*

 

*   VERSION numbers....

 

*/

 

#define MAJOR 6 #define MINOR 1

 

/*

 

*   I/O addresses

 

*/

 

#define PORT1   0x3F8   /* COM1 port address */

#define PORT2   0x2F8   /* COM2 port address */

#define PORT3   0x3E8   /* COM3 port address */

#define PORT4   0x2E8   /* COM4 port address */

#define LPT1    0x378 /* LPT1 port address */

#define LPT2    0x268 /* LPT2 port address */

 

/*

 

*    Now define the required BAUD rate

 

*    38400=0x03 115200=0x01     57600=0x02   19200=0x06

*    9600=0x0C  4800=0x18  2400=0x30

*/                  

#define BAUD    0x06 /* 19200 baud rate */

/*

 

*    Data logging utility

 

*    Usage: TCLOG

 

*   

 

*    Compile with PACC -R or “_getargs() wildcard expansion”

 

*    if you want it to handle wildcards, e.g. CHK *.EXE

 

*/

 

/*

 

*    This version reprograms the system TICK (18th sec) and daisy chains

 

*    onto the 0x1c interrupt where it changes the status of the variable

 

*    Waitflag instead of using the int 21 routine which seems to be a little

 

*    BIOS unfriendly!

 

*    When Waitflag changes, the sampling routine resets and runs again.

 

*    In this way the sampling is synchronised to the interrupt rate e.g. 33 Hz

 

*/

 

void set_rate(int Hz); /* Programs the tick timer to support Hz sample rate */

 

void setup_int();    /* Sets up out vector 1C interrupt   routine */

void restore(); /* Restores the orig vector 1C  routine */

void create_header();     

 

void interrupt timer_tick(); /* Changes the value of waitflag from 0 to 128     */

void interrupt (far *old_1C_vect)(); /* Stores the old vector handler */

void tc_display(int tc);   /* Displays the TC level */

 

/*

 

*    Let’s declare the global data...

 

*/

 

unsigned int    h,i,j,k;   /* loop counters */

unsigned int    byte_count;     /* Counts six bytes - goes 0 to 6 */

unsigned int    time_out;  /* flag to indicate time out problem */

unsigned int    get_com;   /* bioscom status */

unsigned char   byte; /* bioscom parameter */

unsigned char   lpt; /* LPT data */

unsigned char   c[512];    /* character read from file */

unsigned char   fn[20];    /* string for target filename */

unsigned int    buf[7];    /* buffer for incoming data */

FILE *     infile;    /* input file handle */

FILE *     outfile;   /* output file handle */

unsigned char log[256];    /* Buffer for incoming serial data */

 

unsigned int waitflag;     /* stores the flag for timer tick status */

 

main()

 

{

 

/*

 

*    The main loop may look a little cumbersome in that apart from setup and

 

*    restore and the interrupt routine, it does not use any subroutines.

 

*    The reason is that timing is quite tight on a slow machine and the

 

*    potential overhead of passing large amounts of data can make a difference

 

*    at high data rates.

 

*/

 

/*

 

*    Let’s initialise the data

 

*/

 

time_out = 0;

 

 

waitflag = 0; j =0; k =0;

 

/*

 

*    Clear the two spare data channels. These are stored but not used

 

*    currently. They can be filled in by reading external data such as

 

*    throttle and brake position.

 

*/

 

log[6] = 0; log[7] =0;

 

/*

 

*    Set up the COM port for 19.200 kbaud, 8B, No P, 1 STOP, FIFO on

 

*/

 

outportb(PORT1 + 1, 0x00); /* Turn off COM port interrupts */

 

outportb(PORT1 + 3, 0x80); outportb(PORT1 + 0, BAUD); outportb(PORT1 + 1, 0x00); outportb(PORT1 + 3, 0x03); outportb(PORT1 + 2, 0xC7); outportb(PORT1 + 4, 0x0B);

 

 

/*

 

*    Set up the LPT control port to enable the switches...

 

bits 3,1 and 0 are used to generate active high signals for the status port inputs.

 

Bit  7 6 5 4 3 2 1 0

Data 1 1 0 0 1 0 1 1 0xCB

*/        

outportb(LPT1 + 2, 0xCB);  /* Set up the control port */

 

/*

 

*    Set up the interval timer params.......

 

*    This is setup to generate a .033 second timing rate.

 

*    This is compatible with the data log software.

 

*    ( c[07] = 0x3D; Set up internal timing for 30 Hz)

 

*/

 

set_rate(30); /* 30 Hz for data logging */ setup_int();

 

printf(“Setup complete.    ch = %x\n”,check_port());

 

/*

 

*    Print the intro so we know the version and what it does...

 

*/

 

printf(“TCLOG version %d.%d FIFOs enabled 19.2 kbps\n”,MAJOR,MINOR); printf(“This collates data from the traction control.\n”);

 

do   /* Start of main control loop */

 

{

 

/* Look at external controls */

 

/* If logging set then go into log loop */ /* If not go into display loop */

/* Currently we go into log loop */

 

if (inportb(LPT1+1) < 0x80)

{ /* we are not data logging just displaying the tc values */ printf(“Going into display mode...\n”);

 

 

FIFO Clear\n”);

 

FIFO Clear\n”);

 

/* Clear the serial port FIFO */ printf(“Clearing serial port FIFO: “); while (inportb(PORT1 + 5) & 1)

 

{

 

log[10] = inportb(PORT1); printf(“=X”);

 

}

 

printf(“

 

printf(“ A MODE FL FR RL RR RPM TC  Samples\n”);

j = 0;          /* Check the

while (inportb(LPT1+1) < 0x80 & bioskey(1) == 0)    

switch value and the keyboard */          

{         

/* First send out the M to the data logger to get it */

/* to send the next 6 bytes of data  */

outportb(PORT1,0x4D);     

/* Now lets get the data in  */

byte_count = 0; /* clear the byte counter */   

do        

 

{get_com = inportb(PORT1 + 5); get_com = inportb(PORT1 + 5);

 

if (get_com & 1)

 

{

 

log[byte_count++] = inportb(PORT1);

 

}

 

} while (waitflag != 128 & byte_count != 6);

 

/* Now we have six data samples, check if we timed out... */ j++;

if (byte_count == 6)

 

{ /* Display the traction control status */ tc_display(log[5]);

/* All done */

 

}

 

else tc_display(0); /* RESET the TC status */

 

/* all done so wait for timer to expire... */ printf(“Display mode: %x %x %x %x %x %x %d\r”, log[0],log[1],log[2],log[3],log[4],log[5],j); for(;waitflag != 128;);

 

waitflag = 0; /* Now clear the wait flag to repeat */ } /* end of data display WHILE loop */

fcloseall();

 

/* restore(); */ /* now performed on program exit */ printf(“\nEnd of data display routine\n”);

} /* end of IF data display = TRUE loop */ else

{/*

 

*    WE ARE DATA LOGGING!

 

*/

 

/* Set up the data log file */ create_header();

j =0; time_out = 0;

 

/* Clear the serial port FIFO */ printf(“Clearing serial port FIFO: “); while (inportb(PORT1 + 5) & 1)

 

{

 

log[10] = inportb(PORT1); printf(“=X”);

}

 

printf(“F")

 

 /* Now synchronise with the clock */ printf(“Synchronising\n”);

printf(“A MODE Data logging starting \a\a\a\n”); printf(“FL FR RL RR RPM TC OK FAIL\n”); for(;waitflag != 128;);

 

waitflag = 0;

 

while(inportb(LPT1+1) > 0x80 & bioskey(1) == 0)

/* this would test the switch */

 

{

/* First send out the M to the data logger to get it */

 

/* to send the next 6 bytes of data  */

 

outportb(PORT1,0x4D);

/* Now lets get the data in     */

 

byte_count = 0; /* clear the byte counter */

 

do

 

{ get_com = inportb(PORT1 + 5);

 

if (get_com & 1)

 

{ log[byte_count++] = inportb(PORT1);

 

}

 

} while (waitflag != 128 & byte_count != 6);

 

/* Now we have six data samples, check if we timed out... */ if (byte_count == 6)

{ /* Success! */ j++;

 

/* Reorg the data correctly

 

This has been commented out as it was not needed when the real problem was found out. */

/* Input order: 0 = FL, 1 = FR, 2=RPM,3=TC,4=RL, 5=RR */

 

/* Output order: FL, FR, RL, RR, RPM, TC */

 

/* log[9] = log[2];*/ /* Copy RMP to [9] */ /* log[8] = log[3];*/ /* Copy TC to [8] */ /* log[2] = log[4];*/ /* Copy RL to [2] */ /* log[3] = log[5];*/ /* Copy RR to [3] */

 

/* log[4] = log[9];*/ /* Copy RPM to [4] */

 

/* log[5] = log[8];*/ /* Copy TC to [5] */

 

/* Store the data in the file */ fwrite(log,1,8,outfile);

/* Display the traction control status */ tc_display(log[5]);

 

/* Display the LPT port status */

 

/* printf(“LPT=%x\n”,inportb(LPT1+1)); */

 

}

 

else /* we timed out.. */

 

{

 

/* Mark the file so we know we timed out */ strcpy(log,”********”); fwrite(log,1,8,outfile);

 

time_out++; tc_display(0);

}

 

printf(“%x %x %x %x %x %x %d %d\r”, log[0], log[1], log[2], log[3], log[4],log[5],j,time_out);

/* all done so wait for timer to expire... */ for(;waitflag != 128;);

 

waitflag = 0; /* Now clear the wait flag to repeat */

 

} /* end of data logging WHILE loop */ fcloseall();

printf(“\nTime out = %d”,time_out); printf(“ Transfers attempted: %d\n”,j);

 

} /* end of data log ELSE */

 

} while ( (inportb(LPT1+1) & 0x20) == 0x00);

/*

 

*    We are quitting the program so restore and close...

 

*/

 

restore();

 

printf(“ Quitting TCLOG now...\n”); } /* end of MAIN() */

 

/*

 

*    This is where the sub-routines live that control the tick ...

 

*/

 

void set_rate(int Hz /* This is the sample rate we need */)

 

{

 

int  rate_hi, rate_lo;   /* low and high bytes to program the timer */

int  num; /* temp value  */

 

printf(“Changing the BIOS 1/18th tick rate to 1/%d\n”,Hz);

 

/*

 

*    First calculate the values we need to program...

 

*    If the rate is 18... re program to normal BIOS value to restore normality

 

*/

 

/*

 

*    The main clock is 14.31818 MHz divided by 12 to give 1.1931816 MHz

 

*    Divide by 65536 to give the 18.2 Hz tick.

 

*    To reprogram it, divide 1,193,181.6 by the Hz value.

 

*    For 30 Hz this is 39773 or 0x965C

 

*

 

*/

 

if (Hz == 18) { rate_hi = 0xFF; rate_lo = 0xFF; } else if (Hz == 30) {rate_hi = 0x96; rate_lo = 0x5C;}

else {

 

num=65536/(Hz/18.2); rate_hi = num&0xFF00; rate_hi = rate_hi/256;

rate_lo = num&0x00FF;

 

}

 

outportb(0x43,0x36); /* Set up 8253 timer for Sq Wave */ outportb(0x40,rate_lo); /* program divisor low byte */ outportb(0x40,rate_hi); /* program divisor high byte */

 

/*

 

*    The tick has now been set up for the required sampling frequency.

 

*/

 

} /* End of set_rate()     */

 

void interrupt timer_tick()

 

{

/*

 

* The timer has expired so change the value of waitflag and return.. */

waitflag = 128;

 

} /* end of timer tick interrupt routine */

 

 

void setup_int()

 

{

 

disable(); old_1C_vect=getvect(0x1C); setvect(0x1c,timer_tick); enable();

 

} /* end of setup_int() */ void restore()

{

 

disable(); set_rate(18);

setvect(0x1C,old_1C_vect); enable();

}/* end of restore()  */

 

 

void create_header()

 

{

char file_name[28];  /* Stores the file name */

 

char temp_str[28];   /* Holds the file name */

 

struct ffblk f; /* File block structure */

 

int done;  /* Stores the result of the file find */

 

int count; /* Stores the number of files to work out the

 

next file name for storage */

 

/*

 

*    This creates the enhanced Racelogic format file header from a

 

*    header file called BLANKHDR.BIN

 

*/

 

/*

 

*    First work out the next file name in the sequence

 

*/

 

count = 0;

 

done = findfirst(“data_*.dat”,&f,0); while(!done) {

count++;

 

printf(“Count: %d %s\n”,count,f.ff_name); done = findnext(&f);

}

 

strcpy(file_name,”data_”); itoa(count,temp_str,10); strcat(file_name,temp_str); strcat(file_name,”.dat”);

 

strcpy(fn,file_name);

 

printf(“file name is %s\n”,fn); if (!(outfile = fopen(fn,”wb”)))

{

 

printf(“Can’t open file %s.     Exitting.\n”,fn);

 

exit(1);

 

exit(1);

 

}

 

/*

 

*    Let’s do the file copying now that we know that the

 

*    input and output files are open...

 

*/

 

if (!(infile = fopen(“BLANKHDR.BIN”, “r”)))

 

{

 

printf(“Can’t open BLANKHDR.BIN file for logging\n”); exit(1);

 

}

 

/*   fread(c, 260, 1, infile); /* Read the header */

               

*  Now update the information  

*/             

           c[00]=8;   /* Set up the extra channel 06 to 07 */

     /*   3C = 125Hz, 3E = 7.5Hz, 3f = 202.89/256, 3D = 33Hz  */

     /*   NOTE: <3a,3B,2D, and >3F DON’T WORK! */

           c[07] = 0x3D;   /* Set up internal timing for 33 Hz */

/* Name the 1 s time stamp channel */

 

c[156]=’T’; c[157]=’C’; c[158]=’6'; c[159]=’1'; c[160]=’H’; c[161]=’z’; c[162]=’3'; c[163]=’0';

 

/* Store the display factor for the channel */

 

c[164]= 0x00; c[165]= 0x00; c[166]= 0x4C; c[167]= 0x3E;

 

/* Name the 20 second time stamp channel */ c[180]=’T’; c[181]=’i’; c[182]=’m’; c[183]=’e’; c[184]=’ ‘; c[185]=’s’; c[186]=’e’; c[187]=’c’;

/* Store the display factor for the channel */

 

c[188]= 0x00; c[189]= 0x00; c[190]= 0xA0; c[191]= 0x41;

 

/*

 

*    Now let’s write the channel names.....

 

*/

 

/* Name the first channel */

 

c[12]=’L’; c[13]=’e’; c[14]=’f’; c[15]=’t’; c[16]=’ ‘; c[17]=’F’; c[18]=’r’; c[19]=’ ‘;

 

/* Store the display factor */

 

c[20]= 0x00; c[21]= 0x00; c[22]= 0x26; c[23]= 0x3F;

 

/* Name the second channel */ c[36]=’R’;c[37]=’i’;c[38]=’g’;c[39]=’h’; c[40]=’t’;c[41]=’ ‘;c[42]=’F’;c[43]=’r’;

/* Store the display factor */

 

c[44]= 0x00;c[45]= 0x00;c[46]= 0x26;c[47]= 0x3F;

 

/* Name the third channel */ c[60]=’L’;c[61]=’e’;c[62]=’f’;c[63]=’t’; c[64]=’ ‘;c[65]=’B’;c[66]=’a’;c[67]=’k’;

/* Store the display factor */

 

c[68]= 0x00;c[69]= 0x00;c[70]= 0x26;c[71]= 0x3F;

 

/* Name the fouth channel */ c[84]=’R’;c[85]=’i’;c[86]=’g’;c[87]=’h’; c[88]=’t’;c[89]=’ ‘;c[90]=’B’;c[91]=’k’;

 

/* Store the display factor */

 

c[92]= 0x00;c[93]= 0x00;c[94]= 0x26;c[95]= 0x3F;

 

/* Was 259, now 260 for 8th channel */

 

fwrite(c, 260, 1, outfile);     /* write the header */

 

/* HEADER completed! */

 

}/* end of create_header */

 

void tc_display(int tc)

 

{

/*

 

*    This displays the TC level either on the screen or

 

*    on an external LED array using the parallel port.

 

*    Replace with printf to write to the screen

 

*/

if (tc == 0) {outportb(LPT1,0x00);} else if (tc == 1) {outportb(LPT1,0x01);} else if (tc == 2) {outportb(LPT1,0x03);} else if (tc == 3) {outportb(LPT1,0x07);} else if (tc == 4) {outportb(LPT1,0x0f);}

 

}  /* end of tc_display() */

 

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
Embedded Systems Design : Real-time without a RTOS : Program listing- Real-time without a RTOS |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.