⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basetask.cpp

📁 a program that generates a pulse-width modulated (PWM)signal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void CriticalSectionEnd (void)
         {
         DisableInterrupt();
         CriticalCounter--;  // decrement for each exit
         if(CriticalCounter <= 0)
            {
            // Only remove critical status when leaving the last nesting
            CriticalSection = 0;
            CriticalCounter = 0;  // Make sure counter is at 0 (ignore
                // extra ENDs)
            }
         EnableInterrupt();
         }

#ifdef ISR_SCHEDULING
// File scope global variables for interrupt service routine
// Keep track of preemption (reentry) with this flag
static int ReentryInterrupt = 0;
static int ReentryPreemptable = 0;
int ReentryLevel = 0;
// Allocate static memory to save the floating point processor
//  state apon reentry.  The compiler (Borland C++ 4.5) does not
//  take care of this even for a void interrupt type function.
static far char FPU_Buffer[94 * 2];

// Function to be installed as interrupt service routine
void interrupt TimerISR(...)
        {
        //  Save the state of the floating point unit to the FPU.
        //  Calling fsave [DI] causes all the FPU's internal
        //  registers to be saved to a memory location pointed to
        //  by DI and referenced by the segment register DS.
        //  Therefore, before calling fsave we must set DS to the
        //  data segment of the FPU "stack" space, since defining
        //  FPU_Buffer as a file-scope global has put it in a data
        //  segment which may be different from the one we're in
        //  when this ISR runs.  DI gets the offset into that data
        //  segment at which the FPU state will go.
        // --------------------------------------------------------

        //      Assembly code to save the state of the floating
        //      point processor.
        DisableInterrupt ();
        unsigned Save_DI = FP_OFF (FPU_Buffer) + (94*ReentryLevel);
        unsigned Save_DS = FP_SEG (FPU_Buffer);
        asm     push    DS    //  Push the data segment in which the ISR is
        _DI = Save_DI;        //  intended by the compiler to run; then get
        _DS = Save_DS;        //  DI and DS from the local, automatic vars.
        asm     fsave   [DI]  //  in which they were saved and use them to
        asm     fwait         //  save the FPU state.  Then pop DS because
        asm     pop     DS    //  it's needed for dealing with other data
        EnableInterrupt ();

        // Read the real time clock so that we avoid an overflow and
        //  don't lose track of time.
        GetTimeNow();
        // IF the program is in a critical section - signified by a
        //  a call to CriticalSectionBegin() - don't allow any scheduling.
        if (CriticalSection||ReentryInterrupt)
                {
                // Clean up and return from interrupt
                DisableInterrupt ();
                asm     push    DS
                _DI = Save_DI;      //  Get the data segment and offset at which
                _DS = Save_DS;      //  we saved the FPU state; use to restore
                asm     frstor  [DI]//  the FPU state.  Wait until FPU is fully
                asm     fwait       //  restored before going back to background
                asm     pop     DS
                EnableInterrupt ();
                TimerEOI ();         //  Re-enable hardware timer interrupt
                return;
                }
        ReentryLevel ++;
        ReentryInterrupt = 1;
        //  Re-enable hardware timer interrupt.  From this point on,
        //   this function may reenter, possibly allowing a third thread.
        TimerEOI ();

        // Run Interrupt list
        // Sequentially run all of the Interrupt tasks once.  If
        //  there is some sort of problem, call StopControl and let
        //  the scheduling loop in the main() function (the parent thread)
        //  handle exiting the program cleanly.
        if (TaskDispatcher(NULL, Interrupt))
                StopControl("\n***Problem with Interrupt list***\n");

        DisableInterrupt ();
        ReentryInterrupt = 0;
        EnableInterrupt ();
        // If this call to the ISR was reentrant, don't allow
        // preemptable list to be processed.
        if(ReentryPreemptable)
                {
                // Clean up and return from interrupt
                DisableInterrupt ();
                ReentryLevel --;
                asm     push    DS
                _DI = Save_DI;      //  Get the data segment and offset at which
                _DS = Save_DS;      //  we saved the FPU state; use to restore
                asm     frstor  [DI]//  the FPU state.  Wait until FPU is fully
                asm     fwait       //  restored before going back to background
                asm     pop     DS
                EnableInterrupt ();
                return;
                }
        DisableInterrupt ();
        ReentryPreemptable = 1;
        EnableInterrupt ();

        // Run Preemptable list
        // Sequentially run all of the Preemptable tasks once.  If
        //  there is some sort of problem, call StopControl and let
        //  the scheduling loop in the main() function (the parent thread)
        //  handle exiting the program cleanly.
        if (TaskDispatcher(NULL, Preemptable))
                StopControl("\n***Problem with Preemptable list***\n");

        // Clean up and return from interrupt
        DisableInterrupt ();
        ReentryPreemptable = 0;
        ReentryLevel --;
        asm     push    DS
        _DI = Save_DI;      //  Get the data segment and offset at which
        _DS = Save_DS;      //  we saved the FPU state; use 'em to restore
        asm     frstor  [DI]//  the FPU state.  Wait until FPU is fully
        asm     fwait       //  restored before going back to background
        asm     pop     DS
        EnableInterrupt ();
        return;
        }

static void  interrupt (*oldvec)(...);

// Set up the timer interrupt
void SetupTimerInterrupt(void)
    {
    // Declaration for a pointer to an interrupt service function
    // in which the previous interrupt vector (probably DOS clock)
    // will be stored and later reinstalled from.
    // Set the desired period for the timer ISR (in sec)
    SetupClock(GetTickRate());
    cout << "setting interrupt tickrate to :" << GetTickRate() << " sec\n";
    // Disable interrupts while setting up a new ISR
    DisableInterrupt ();
    // Get existing vector
    oldvec = _dos_getvect(8);
    // Replace it with the new timer interrupt function
    _dos_setvect(8,TimerISR);
    // Enable interrupts when done
    EnableInterrupt ();
    }

void RestoreTimerInterrupt(void)
    {
    DisableInterrupt ();
    // Restore the timer interrupt to what it was
    _dos_setvect(8,oldvec);
    // Reset the default mode for the timer (DOS)
    SetupClock(-1.0);
    EnableInterrupt ();
    }
#endif // ISR_SCHEDULING

// Functions associated with the class DataOutput

// Constructor for time-based array sizing
DataOutput::DataOutput(int nvars,double STime,double LTime,double DTime)
        {
        MaxOutputs = 0; // Make sure that Init... doesn't try an illegal delete!
        NVars = 0;
        BaseTime = 0.0;  // Default value
        if(InitDataOutput(nvars,STime,LTime,DTime) == -1)
                {
                StopControl("Can't initialize for output data\n");
                }
        }

                // Constructor for direct array sizing
DataOutput::DataOutput(int nvars,long nrows)
        {
        MaxOutputs = 0; // Make sure that Init... doesn't try an illegal delete!
        NVars = 0;
        StartTime = 0.0;        // Not used in this mode - make sure they have
        LastTime = 0.0; // legal values
        DeltaTime = 0.0;
        NextTime = 1.e20;
        BaseTime = 0.0;  // Default value
        if(InitDataOutput(nvars,nrows) == -1)
                {
                StopControl("Can't initialize for output data\n");
                }
        }


DataOutput::~DataOutput()       // Destructor
        {
        // If output arrays exist, delete them
        if(MaxOutputs != 0)delete [] TimeRecord;
        if(NVars != 0)
            {
            for(int i = 0; i < NVars; i++)delete [] OutRecord[i];
            delete [] OutRecord;
            }
        }

int DataOutput::SetUpArrays(int nvars,long nrows)
        {
        if((TimeRecord = new double[nrows]) == NULL)
                {
                return(-1);
                }
        for(int i = 0; i < nvars; i++)
                {
                if((OutRecord[i] = new double[nrows]) == NULL)
                        {
                        return(-1);
                        }
                }
        MaxOutputs = nrows;
        OutCount = 0;
        NVars = nvars;
        return(0);
        }

int DataOutput::InitDataOutput(int nvars,long nrows)
        {
        // Returns -1 for error, 0 for OK
        // If output arrays already exist, delete them
        if(MaxOutputs != 0)
      delete TimeRecord;
   if(NVars != 0)
      {
      delete OutRecord;
      }
   OutRecord = new double *[nvars];
        if(SetUpArrays(nvars,nrows) == -1)return(-1);
        return(0);
        }

int DataOutput::InitDataOutput(int nvars,double STime,double LTime,double DTime)
        {
        StartTime = STime;
        LastTime = LTime;
        DeltaTime = DTime;
        NextTime = StartTime;
        // Compute the number of rows and then call the other InitDataOutput
        long nrows = ceil((LTime - STime) / DTime);
        return(InitDataOutput(nvars,nrows));
        }

int DataOutput::AddData(double val, ...)        // Add a data row
   {
   va_list ArgPtr;
   va_start(ArgPtr, val);

   if(OutCount >= MaxOutputs)return(-1);
   double time = GetTimeNow() - BaseTime;
   TimeRecord[OutCount] = time;
   *(OutRecord[0] + OutCount) = val;
   for(int jj=1; jj < NVars; jj++)
      {
        *(OutRecord[jj] + OutCount) = va_arg(ArgPtr, double);
      }
   if (va_arg(ArgPtr, long int) != END_OF_ARGS)
     StopControl("\n\n***Incorrect Arg List for DataOutput::AddData***\n\n");
   OutCount++;
   NextTime += DeltaTime;
   va_end(ArgPtr);
   return(0);
   }

int DataOutput::IsTimeForOutput(void)   // Query to find out if output
        {
        // Returns 1 for YES, 0 for NO
        double time = GetTimeNow() - BaseTime;
        if(time >= NextTime)return(1);
        return(0);
        }

int DataOutput::WriteOutputFile(char *FileName)
        {
        ofstream OutputFile(FileName);  // Opens for 'write'

        if (!OutputFile)
                {
                cout << "Problem opening file " << FileName << "\n";
                return(-1);
                }
        // Returns -1 for error, 0 for OK

        for (int j=0; j < OutCount; j++)
                  {
                  OutputFile << TimeRecord[j] << " ";
                  for(int kk = 0; kk < NVars; kk++)
                                OutputFile << (*(OutRecord[kk] + j)) << " ";
                  OutputFile << "\n";
                  }

        OutputFile.close(); // close the output file.
        return(0);
        }
// Accumulate Scan Statistics
// not used? static long nscans[NTASKSMAX];  // This must be big enough for all tasks!

void InitScanStat(BaseTask *task)
         {
         ntasks++;
         if(ntasks > NTASKSMAX)
                  {
                  StopControl("Too many tasks (fix NTASKSMAX in basetask.cpp)\n");
                  }
         AllTasks[task->TaskID] = task;
         tskname[task->TaskID] = task->Name;
         // not used? nscans[task->TaskID] = 0;
         }

void WriteScanStat(char *FileName, double FinalTime)
         {
         long nsc,tot = 0;
         ofstream OutputFile(FileName); // Opens for 'write'

         if (!OutputFile)
                {
                cout << "Problem opening file " << FileName << "\n";
                return;
                }

         cout << "Task # \t Task Name \t\t #Scans\n\n";
         OutputFile << "Task # \t Task Name \t\t #Scans\n\n";
         for(int i = 0; i < ntasks; i++)
                  {
                  nsc = (AllTasks[i])->GetNumScan();
                  int IDno = (AllTasks[i])->TaskID;
                  tot += nsc;
                  cout << IDno << "\t" << tskname[i] << "\t\t" <<nsc << "\n";
                  OutputFile << IDno << "\t" << tskname[i] << "\t\t" <<nsc << "\n";
                  }
         cout << "\nTotal scans, all tasks: " << tot << "\n";
         OutputFile << "\nTotal scans, all tasks: " << tot << "\n";
         cout << "\nTotal running time: " << FinalTime << "\n";
         OutputFile << "\nTotal running time: " << FinalTime << "\n";
         OutputFile.close();
         }

void WriteProfileStat(char *FileName)
         {
         ofstream OutputFile(FileName); // Opens for 'write'

         if (!OutputFile)
                {
                cout << "<ProfileStat>Problem opening file " << FileName << "\n";
                return;
                }

         OutputFile << "Task Profile Statistics\n";
         for(int i = 0; i < ntasks; i++)
                  {
                  OutputFile  << "\n"<< tskname[i] << "\n";
                  (AllTasks[i])->WriteProfile(OutputFile);
                  }
         OutputFile.close();
         }


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -