Thread: Unkown Hang

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    278
    OK, Here goes...

    Code:
    // HASP_COM.H
    
    // Serial Port Setup Addresses for COM2
    #define COM2_BASE            0x3F8          // Base address for COM2 Port
    #define COM2_BUFFERS         COM2_BASE + 0  // Transmitter Holding Buffer (W) and Receiver Buffer (R) when DLAB=0 or Divisor Latch Low Byte (R/W) when DLAB=1
    #define COM2_INTERRUPT       COM2_BASE + 1  // Interrupt Enable (R/W) when DLAB=0 or Divisor Latch High Byte (R/W) when DLAB=1
    #define COM2_FIFO_INT_ID     COM2_BASE + 2  // Interrupt Identification (R) and FIFO Control (W)
    #define COM2_LINE_CONTROL    COM2_BASE + 3  // Line Control Register (R/W)
    #define COM2_MODEM_CONTROL   COM2_BASE + 4  // Modem Control Register (R/W)
    #define COM2_LINE_STATUS     COM2_BASE + 5  // Line Status Register (R)
    #define COM2_MODEM_STATUS    COM2_BASE + 6  // Modem Status Register (R)
    
    #define COM2_INTVECT         0x0C  // COM2's IRQ Base Address
    #define COM2_BUFFER_SIZE     1025  // COM2's Buffer Size in Bytes 
    
    
    // HASP_Comm_Setup Return Values
    #define HASP_COMM_PASS       0     // HASP/GPS Communication Setup Successful
    #define HASP_COMM_FAIL       1     // HASP/GPS Communication Setup Failure

    Code:
    // hasp_com.c
    
    #include <stdlib.h>
    #include <time.h>                      // time() function used to get timestamps
    #include <dos.h>                       // delay() function
    #include "help_fun.h"                  // Helper Functions
    #include "hasp_com.h"
    
    int  COM2_Buffer_Read_Position = 0;    // Position Marker for Input Buffer's Read Position
    int  COM2_Buffer_Write_Position = 0;   // Position Marker for Input Buffer's Write Position
    char COM2_Buffer[COM2_BUFFER_SIZE];    // Buffer to hold all COM2 data
    int  COM2_Is_Accepting_Commands = FALSE; // Flag Indicating whether COM2 (HASP) is accepting manual commands
    
    // Begin COM2 Interrupt Setup Functions
    void interrupt (*old_COM2_Interrupt)();
    
    void interrupt COM2_Interrupt() {
      COM2_Buffer[COM2_Buffer_Write_Position] = inportb(COM2_BUFFERS);
      if (COM2_Is_Accepting_Commands) {
        Transmit_To_HASP(&(COM2_Buffer[COM2_Buffer_Write_Position]));
        COM2_Buffer_Write_Position++;
        if (COM2_Buffer_Write_Position == COM2_BUFFER_SIZE - 1) COM2_Buffer_Write_Position = 0;
      }
      outportb(0x20, 0x20);
    }
    // End COM2 Interrupt Setup Functions
    
    
    /* HASP Communication Setup Function
       Version 0.1
       April 15, 2009
    
       Return Values : HASP_COMM_PASS         (0) - HASP Communication Setup Successful
                       HASP_COMM_FAIL         (1) - HASP Communication Setup Successful
       Parameters    : None
       Description   : Sets up the communication with the HASP/GPS
    */
    int HASP_Comm_Setup () {
      int HASP_Comm_Setup_Result  = HASP_COMM_PASS; // Holds the value returned by HASP_Comm_Setup
      //***** NOTE : INITIAL VALUES FOR RESULTS ARE SET TO FAIL - OTHER FUNCTIONS USUALLY INITIALLY SUCCESS*****//
    
    
      // Setup Communication Protocol
      outportb(COM2_LINE_CONTROL,  0x00);  // Set DLAB = 0
      outportb(COM2_INTERRUPT,     0x00);  // Turn off interrupts
    
      old_COM2_Interrupt = getvect(COM2_INTVECT); // Save Old Interrupt
      setvect(COM2_INTVECT, COM2_Interrupt);      // Set New Interrupt
    
      outportb(COM2_LINE_CONTROL,  0x80);  // Set DLAB = 1
      outportb(COM2_BUFFERS,       0x60);  // Set Baud rate to 1200 - Divisor Latch Low Byte
      outportb(COM2_INTERRUPT,     0x00);  // Set Baud rate to 1200 - Divisor Latch High Byte
      outportb(COM2_LINE_CONTROL,  0x03);  // 8 Bits, No Parity, 1 Stop Bit
      outportb(COM2_FIFO_INT_ID,   0xC7);  // Enable FIFO and Clear FIFO Buffers
      outportb(COM2_MODEM_CONTROL, 0x0B);  // Turn on DTR, RTS, and OUT2
      disable();
      outportb(0x21, (inportb(0x21) & 0xF7)); // Set Programmable Interrupt Controller
      enable();
      outportb(COM2_INTERRUPT,     0x01);  // Interrupt When data recieved
    
      return HASP_Comm_Setup_Result;
    }
    
    
    /* HASP Communication Shutdown Function
       Version 0.1
       April 15, 2009
    
       Return Values : None
       Parameters    : None
       Description   : Shuts down the communication with the HASP
    */
    void HASP_Comm_Shutdown () {
      // Reset Communication Protocol to original settings
      outportb(COM2_LINE_CONTROL, 0x00);         // Set DLAB = 0
      outportb(COM2_INTERRUPT, 0x00);            // Turn off interrupts
      disable();
      outportb(0x21, (inportb(0x21) | 0x08));    // Set Programmable Interrupt Controller
      enable();
      setvect(COM2_INTVECT, old_COM2_Interrupt); // Restore Old Interrupt Vector
    }
    
    
    /* Reset HASP Communication Buffer Function
       Version 0.1
       April 15, 2009
    
       Return Values : None
       Parameters    : None
       Description   : Resets the HASP Communication Buffer (COM2) (sets all bytes to 0 and resets the read and write positions to 0)
    */
    void Reset_HASP_Comm_Buffer () {
      int x;
    
      for (x = 0; x < COM2_BUFFER_SIZE; x++) {
        COM2_Buffer[x] = 0x00;
      }
    
      COM2_Buffer_Read_Position = 0;
      COM2_Buffer_Write_Position = 0;
    }
    
    
    /* Transmit to HASP Function
       Version 0.1
       April 17, 2009
    
       Return Values : None
       Parameters    : Log_String                 - String to be transmitted
       Description   : Transmits the given number of characters from Log_String
    */
    void Transmit_To_HASP(char *Log_String) {
      int Line_Ready = 0;
      int Length = strlen(Log_String);
      int x;
    
      for (x = 0; x < Length; x++) {
        // Check to make sure port is ready to send
        while (Line_Ready == 0) {
          Line_Ready = inportb(COM2_LINE_STATUS) & 0x20;
        }
        Line_Ready = 0;
        // Send next byte
        outportb(COM2_BUFFERS, Log_String[x]);
      }
    }
    
    
    // Sets COM2_Is_Accepting_Commands Flag to given value
    void Set_COM2_Is_Accepting_Commands (int Value) {
      COM2_Is_Accepting_Commands = Value;
    }
    
    // Gets a manual command via COM2
    char Get_Manual_Command() {
      char Manual_Command = '~';
      char *Temp = (char*) malloc(sizeof(char) * 5);
    
      COM2_Is_Accepting_Commands = FALSE;
    
      if (COM2_Buffer_Read_Position != COM2_Buffer_Write_Position) {
        Manual_Command = COM2_Buffer[COM2_Buffer_Read_Position];
        Transmit_To_HASP(" - Command Accepted (");
        sprintf(Temp, "%c", Manual_Command);
        Transmit_To_HASP(Temp);
        Transmit_To_HASP(").\n\r");
        Reset_HASP_Comm_Buffer();
      }
    
      COM2_Is_Accepting_Commands = TRUE;
    
      free(Temp);
    
      return Manual_Command;
    }
    Code:
    // main.c
    
    #define MAX_FAILURES 5                 // Maximum number of failures allowed before action is taken
    #define COLLECTION_PERIOD 20          // The number of seconds between each data dump from the DP4/DP4
    
    // INCLUDE Files
    #include <time.h>                      // time() function used to get timestamps
    #include <stdio.h>                     // Standard I/O functions (File I/O)
    #include "help_fun.h"                  // Helper Functions
    #include "hasp_com.h"                  // HASP/GPS Communicatioln Functions (COM2)
    
    // Function Prototypes
    void Initialize (ts *Time_Stamp); // Initializes certain values and allocates memory for global variables as needed
    
    // Global Constants
    const char * const Flash_Card_Base_Path = "C:\\Data\\";          // Needs changed to actual path of Flash Card drive on SBC
    const char * const Diagnostic_Log_Path  = "diag_log.txt";  // Saves in program directory
    const char * const Data_Log_Path        = "Data\\data_log.txt";  // Saves in program directory
    
    
    /* Main Function
       Version 0.7
       April 14, 2009
       
       Return Values : None
       Parameters    : None
       Description   : Main Control Function
    */
    int main() {
      int  HASP_Comm_Setup_Result = 0;    // Holds the value returned by HASP_Comm_Setup
      ts   Time_Stamp;                    // Holds the old timestamp (Unix Epoch Seconds)
      int  Terminate_Data_Acquisition = 0;// Flag that Terminates Data Acquisition Cycle on any value other than 0
      char Manual_Command = '~';          // Holds the Manual Commands sent via HASP/COM2
      int  x = 0;
      int  y = 0;
    
    
      // Set all initial values
      Initialize(&Time_Stamp);
    
      // HASP/GPS Communication Setup
      HASP_Comm_Setup_Result = HASP_Comm_Setup();
    
    
      // Write SBC Boot Info to Log File/Screen
      Write_to_Diagnostic_Log("*******************************************************************\n", -1, Diagnostic_Log_Path, &Time_Stamp);
      Write_to_Diagnostic_Log("SBC booted successfully. Control software initiated.\n", -1, Diagnostic_Log_Path, &Time_Stamp);
    
      
      // Write HASP Communication Setup Info to Log File/Screen
      if (HASP_Comm_Setup_Result == HASP_COMM_PASS) {
        Write_to_Diagnostic_Log("HASP/GPS Comm Setup..... PASSED!", -1, Diagnostic_Log_Path, &Time_Stamp);
      } else { 
        Write_to_Diagnostic_Log("HASP/GPS Comm Setup..... FAILED! (Error Code : 0x%03X)", HASP_Comm_Setup_Result, Diagnostic_Log_Path, &Time_Stamp);
        //*************************************************************************************************************************NEED CODE FOR FAILED COMMUNICATION WITH HASP/GPS
      }
    
      // Main Control Loop
    
      Write_to_Diagnostic_Log("\n", -1, Diagnostic_Log_Path, &Time_Stamp);
      Write_to_Diagnostic_Log("Begin Data Collection Phase...\n", -1, Diagnostic_Log_Path, &Time_Stamp);
    
      while (Terminate_Data_Acquisition == 0) {
    
        Update_Time_Stamp(&Time_Stamp, TRUE);
    
        Write_to_Diagnostic_Log("  Collection Cycle (%d seconds) Started.", COLLECTION_PERIOD, Diagnostic_Log_Path, &Time_Stamp);
    
        // Allow Manual Commands
        Reset_HASP_Comm_Buffer();
        Transmit_To_HASP("\n\r    Accepting Manual Commands > ");
        Manual_Command = '~';
        Set_COM2_Is_Accepting_Commands(TRUE);
        printf("\nAccepting Commands Delay :    ");
        
        // Wait for next time period (Flash LED While waiting)
        for (x = 0; x < COLLECTION_PERIOD * 2; x++) {      
          delay(500);
          printf("\b\b\b%03d", x);
    
          Manual_Command = Get_Manual_Command();
    
          switch (Manual_Command) {
            case 'e': // End Collection Cycle
              Write_to_Diagnostic_Log("    MANUAL COMMAND : End Collection Cycle.", -1, Diagnostic_Log_Path, &Time_Stamp);
              Transmit_To_HASP("\n\r");
              x = COLLECTION_PERIOD * 2;
              break;
            case 't': // Temporary test command
              Write_to_Diagnostic_Log("    MANUAL COMMAND : Temporary Test Command.", -1, Diagnostic_Log_Path, &Time_Stamp);
              Transmit_To_HASP("\n\r    Accepting Manual Commands > ");
              break;
            case '~':  // No Command Received
              break;
            default:  // Command Received but Not recognized
              Write_to_Diagnostic_Log("    MANUAL COMMAND : Command Unkown.", -1, Diagnostic_Log_Path, &Time_Stamp);
              Transmit_To_HASP("\n\r    Accepting Manual Commands > ");
          }
    
          // Flash LED while debugging so we know the thing is working
          outportb(SBC_LED, inportb(SBC_LED) ^ 0x01);
        }
    
        Set_COM2_Is_Accepting_Commands(FALSE);
        if (Manual_Command == '~') Transmit_To_HASP(" No Manual Commands Received.\n\n\r");
        Write_to_Diagnostic_Log("  Collection Cycle Complete.", -1, Diagnostic_Log_Path, &Time_Stamp);
        
        // Turn off LED
        outportb(SBC_LED, inportb(SBC_LED) & 0x00);
    
        // Pull Location Data from GPS
        Transmit_To_HASP("  Switching Communication to GPS.\n\r");
        Reset_HASP_Comm_Buffer();
        //Get_GPS_Data_Result = Get_GPS_Data(MAX_FAILURES);
        Reset_HASP_Comm_Buffer();
        Transmit_To_HASP("  Returning Communication to HASP.\n\r");
    
        // Transmit/Log GPS Results
    
    
        y++;                                       // REMOVE AFTER TESTING
        if (y == 5) Terminate_Data_Acquisition = 1;// REMOVE AFTER TESTING
      }
      Write_to_Diagnostic_Log("End Data Collection...\n\n", -1, Diagnostic_Log_Path, &Time_Stamp);
    
    
      // Write SBC Shutdown Info to Log file/Screen
      Write_to_Diagnostic_Log("Control software shutting down.\n", -1, Diagnostic_Log_Path, &Time_Stamp);
      Write_to_Diagnostic_Log("*******************************************************************\n", -1, Diagnostic_Log_Path, &Time_Stamp);
    
    
      // Turn On LED To Signal Run Complete
      outportb(SBC_LED, inportb(SBC_LED) | 0x01);
      
      return 0;
    }
    
    
    /* Initialization Function
       Version 0.8
       April 17, 2009
       
       Return Values : None
       Parameters    : Time_Stamp
       Description   : Initializes certain initial values
    */
    void Initialize (ts *Time_Stamp) {
      int x;
    
      // Two calls are required to flush the initial values for the timestamps
      Update_Time_Stamp(Time_Stamp, FALSE);
      Update_Time_Stamp(Time_Stamp, FALSE);
    }
    Code:
    // help_fun.h
    
    #ifndef HELP_FUN_H
    #define HELP_FUN_H
    
    #include <string.h>                    // String Functions
    #include <stdio.h>                     // Standard I/O functions (File I/O)
    #include <stdlib.h>
    #include <time.h>                      // time_t typedef
    
    #define FALSE 0
    #define TRUE 1
    
    typedef struct ts{
      time_t Old;
      time_t New;
      time_t Start;  // Only updated at beginning of collection cycle
    } ts;
    
    
    char * String_Concat (const char *s1, const char *s2); // Concatenates two strings and returns the result.  Both s1 and s2 are unchanged.
    void Update_Time_Stamp (ts *Time_Stamp, int Do_Start); // Updates the the timestamp
    void Write_to_Diagnostic_Log (const char * const In_String,            int   Error_Code,
                                  const char * const Diagnostic_Log_Path, ts    *Time_Stamp);
    #endif
    Code:
    // help_fun.c
    
    #include <string.h>                    // String Functions
    #include <stdio.h>                     // Standard I/O functions (File I/O)
    #include <stdlib.h>
    #include <time.h>                      // time_t typedef
    #include "hasp_com.h"                  // for sending debug info to HASP
    #include "help_fun.h"
    
    /* String Concatenation Function
       Version 1.0
       February 10, 2009
    
       Return Values : A pointer to a C-Style String
       Parameters    : Two pointers to C-Style Strings
       Description   : Concatenates two C-Style strings and returns the result.  Both original strings are unchanged.
    */
    char * String_Concat (const char *s1, const char *s2) {
      char *sTemp = (char*) malloc((sizeof(char) * strlen(s1)) + (sizeof(char) * strlen(s2)));
    
      strcpy(sTemp, s1);
      strcat(sTemp, s2);
    
      return sTemp;
    }
    
    
    /* Update Time Stamp Function
       Version 1.1
       February 11, 2009
    
       Return Values : None
       Parameters    : Time_Stamp
                       Do_Start                   - Flag indicating whether or not to update Start
       Description   : Copies Time_Stamp.New into Time_Stamp.Old and sets Time_Stamp.New to the current timestamp and updates Start time
     */
    void Update_Time_Stamp(ts *Time_Stamp, int Do_Start) {
      Time_Stamp->Old = Time_Stamp->New;
      Time_Stamp->New = time(NULL);
      if (Do_Start) Time_Stamp->Start = Time_Stamp->New;
    }
    
    
    /* Diagnostic Log Writing Function
       Version 0.5
       February 23, 2009
    
       Return Values : None
       Parameters    : In_String                  - The string to write to the log/screen
                       Error_Code                 - The error code, if any, to be included in the output (any negative number and no error code is printed)
                       Diagnostic_Log_Path
                       Time_Stamp
       Description   : Appends the given "string" to the END of the file at the given path.
                       In_String is less than 5 characters then a timestamp is included, otherwise only the "string" is written. (Mainly used for printing blank lines)
                       NOTE : Currently does NOT generate an error if a write failure of some kind occurs
                       NOTE : Time_Stamp is always updated
     */
    void Write_to_Diagnostic_Log(const char * const In_String, int Error_Code, const char * const Diagnostic_Log_Path, ts *Time_Stamp) {
      FILE *Diagnostic_Log;                // Pointer to the Diagnostic Log File
      char *Temp = (char*) malloc(sizeof(char)*23); // Holds string version of Time_Stamp(New) 
      char *Log_String;                    // String to be written to log file
      int  Error_Code_Length = 0;          // Length of the Error Code, if any
    
      if (Error_Code > 0) Error_Code_Length = 5;
      printf("\n1");
      Log_String = (char*) malloc(sizeof(char) * (strlen(In_String) + 1 + Error_Code_Length));
      printf("2");
    
      if (Error_Code >= 0) sprintf(Log_String, In_String, Error_Code);
      else                 strcpy (Log_String, In_String);
    
      printf("3");
      Diagnostic_Log = fopen(Diagnostic_Log_Path, "a");
      if (Diagnostic_Log == 0) printf("FILE ERROR!");
    
      printf("4");
      Update_Time_Stamp(Time_Stamp, FALSE);
    
      printf("5");
      if (strlen(Log_String) > 5 && Log_String[0] != '*') {
        strftime(Temp, 23, "(%H:%M:%S %m-%d-%Y) ", gmtime(&(Time_Stamp->New)));
        fprintf(Diagnostic_Log, "%s", Temp);
      }
    
      printf("6");
      fprintf(Diagnostic_Log, "%s\n", Log_String);
      
      printf("7");
      Transmit_To_HASP(String_Concat(Log_String, "\n\r"));
    
      printf("8");
      fclose(Diagnostic_Log);
      free(Temp);
      free(Log_String);
    }
    There may be references to things that I have removed from this post here for convenience. Right now they are commented out so are not part of the executing code. Hopefully this makes sense.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Can you pinpoint the section of code where the hang is most likely happening.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Hang man program hanging
    By pieisgood in forum C++ Programming
    Replies: 14
    Last Post: 02-21-2009, 06:08 PM
  2. C# and the WebClient class - application hang?
    By Devils Child in forum Networking/Device Communication
    Replies: 1
    Last Post: 01-09-2009, 11:24 AM
  3. How to get an unkown hWnd
    By Xzyx987X in forum Windows Programming
    Replies: 1
    Last Post: 11-26-2003, 03:29 PM
  4. storage size of regs is unkown
    By Vertex34 in forum C Programming
    Replies: 5
    Last Post: 11-04-2003, 10:17 AM
  5. Reading files with an unkown amount of characters
    By Zahl in forum C++ Programming
    Replies: 13
    Last Post: 10-10-2002, 02:04 PM