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

📄 timer_interrupts.c

📁 windows系统下实时代码,可以进行底层硬件的实时操作
💻 C
📖 第 1 页 / 共 2 页
字号:
	  *(INTR_CLEAR) = 0x00;
	  stop_counter();
	}
    PciDio96_Cleanup(ihr, Clean);

	print_interrupt_stat();
    RtPrintf("\n Exit test (cardNumber=%d depth=%d)\n\n\n", cardNumber, initialized);
    ExitProcess(0);
}
 
//	
// respond: Respond to an interrupt
//          Takes one interrupt and clears it.
//
BOOLEAN RTAPI respond(PVOID pdt)
{
  int k=0, l, num=0;
  BOOLEAN pass=TRUE;
  ULONG status[10];

  if ((IsrUsage == 0) && (is_my_interrupt() == 0)) // If IST only, then check for true
	return PassToNextDevice;     // board interrupt. If not true - pass to next device

  if (pass_interrupt == 2) // If pass_interrupt_to_next() was not called by ISR yet
    pass_interrupt = pass_interrupt_to_next(); // call it by yourself

  // Introduce delay to let EOI reach IoApic:
  if (pass_interrupt == 0) // Only if this IST is final
  {                                          // introduce delay,
    if (IsrUsage <= 3) // but only if IsrUsage does not instruct otherwise
	{
      for (k=0,l=0; k<10000; k++)
	  { l += k; }
	}
  }
  else // Case when either return irrelevant or no ISR and was set to pass interrupt.
    pass = FALSE; // Will pass interrupt to next IST

  status[0] = cardNumber; num++;
  status[1] = *(PORTC_ADDR); num++;
  status[2] = initialized; num++;
  if ((pass_interrupt == 0) && (IsrUsage != 2)) // If final IST and interrupt was not cleared
	clear_interrupt();                          // clear it
  if (append_interrupt_stat(num, status) == 0) // Accumulate statistic
    IntDone = TRUE; // If buffer is full - set IntDone to print statistic and probably reset
  pass_interrupt = 2;  // Next time call pass_interrupt_to_next() again
  
  return pass;
}

// ISR
RTFCNDCL fast_respond(PVOID arg)
{
  if (is_my_interrupt() == 0) // If this is not my interrupt
	return PassToNextDevice;  // pass to next board
  if ((pass_interrupt = pass_interrupt_to_next()) == 1) // If to pass interrupt
  {                                   // to next application for the same board
    pass_interrupt = 2;  // Next time call pass_interrupt_to_next() again
	return PassToNextDevice; // Pass to next board
  }
  if (IsrUsage == 2)
  {
	clear_interrupt();
    return CallInterruptThread;
  }
  else if  (IsrUsage >= 3)
  {
    respond(NULL);
    return Dismiss;
  }

  return CallInterruptThread;
}


#define CNFG_VAL     0x99   // Port A Input Port B Output Port C Input
void initialize_board()
{
  *(INTR_CTRL1) = 0x00;
  *(INTR_CTRL2) = 0x00;
  *(CNFG_ADDR) = CNFG_VAL; 	// Set PPI A to mode 0	
}


ULONG start_counter(ULONG time)
{
  ULONG time1, time2, k;

  if (time <= 0)
	return 0;

  time *= 2; // Time in counter ticks (2MHz frequency).

  if (time <= 0xFFFF) // If timer interval less then 0xFFFF ticks
  {                   // one counter is enough
    time1=time; // First counter will do all job
	time2 = 0;  // No second counter
  }
  else // If bigger timer interval - we need the second counter
  {    // but we will obtain the best possible resolution
	time2 = time >> 1;
	for (k=1; k<16; k++)
	{
	  if (time2 <= 0xFFFF)
	    break;
	  time2 >>= 1;
	}
    time1 = 1 << k;
  }

  *(INTR_CTRL1) = 0x00;
  *(INTR_CTRL2) = 0x00;
  *(CLOCK_CTRL) = 0x34;
  if (time2 == 0)
  {
    *(INTR_CTRL2) = 0x02;
    *(INTR_CTRL2) = 0x06;
  }
  else
  {
    *(CLOCK_CTRL) = 0x74;
    *(INTR_CTRL2) = 0x02;
    *(INTR_CTRL2) = 0x07;
    *(CLOCKB) = (UCHAR)(time2 & 0xFF);
    *(CLOCKB) = (UCHAR)((time2 >> 8) & 0xFF);
  }
  *(CLOCKA) = (UCHAR)(time1 & 0xFF);
  *(CLOCKA) = (UCHAR)((time1 >> 8) & 0xFF);

  if (time2 == 0)
    time = time1;
  else
    time = time2*time1;

  return time;
}

void stop_counter()
{
  *(CLOCK_CTRL) = 0x30;
  *(INTR_CTRL1) = 0x00;
  *(INTR_CTRL2) = 0x00;
}

#define TIME_DELTA	500 // +/- 500 mks
ULONG is_my_interrupt()
{
  ULONG time;

  RtGetClockTime(CLOCK_FASTEST, &current_time); // Get interrupt time

  // Judje by time whether it is our interrupt:  
  time = (ULONG)((current_time.QuadPart-shared_board_data->previous_time.QuadPart)/5+TIME_DELTA);
  if ((time%(shared_board_data->TimerDelay)) < 2*TIME_DELTA)
  {
    shared_board_data->previous_time = current_time;
    return 1;
  }
  else
    return 0;
}

void clear_interrupt()
{
  *(INTR_CLEAR) = 0x00;
}

int append_interrupt_stat(int num, PULONG status)
{
  int k;
  ULONG *pl, *pl0=status;
  COUNTER_STAT *data;

  if (int_stat_num >= MAX_INT_STAT)
	return -1;

  data = int_stat+int_stat_num;
  data->time = current_time;
  for (k=0,pl=data->status,pl0=status; k<num; k++)
  { *pl++ = *pl0++; }
  data->status_num = num; 
  int_stat_num++;
  if (int_stat_num >= MAX_INT_STAT)
    return 0;

  return int_stat_num;
}

int print_interrupt_stat()
{
  int k, m;
  COUNTER_STAT *data;
  ULONGLONG time0, time;

  data = int_stat;
  time0 = init_time.QuadPart;

  RtPrintf("\n");
  for (k=0; k<int_stat_num; k++, data++)
  {
	time = data->time.QuadPart;
	RtPrintf("%d: time=%6u mks   delta=%5u mks   ", k,
		     (ULONG)(time-init_time.QuadPart)/10, (ULONG)(time-time0)/10);
	for (m=0; m<data->status_num; m++)
	{  RtPrintf(" 0x%X", data->status[m]); }
	RtPrintf("\n");
	time0 = time;
  }

  int_stat_num = 0;

  return k;
}

HANDLE alloc_shared_memory(PVOID *mem)
{
  HANDLE handle;

  RtWaitForSingleObject(ShMemMutex, INFINITE);
  if ((handle = RtCreateSharedMemory(0, 0, 1000, shared_mem_all_name, &pSharedMem)) == NULL)
  {
	RtReleaseMutex(ShMemMutex);
	return NULL;
  }
  if (GetLastError() != ERROR_ALREADY_EXISTS)
	initialize_shared_mem(pSharedMem);
  RtReleaseMutex(ShMemMutex);

  return handle;
}

void initialize_shared_mem(PVOID pmem)
{
  int k;
  SHARED_BOARDS_INFO *info = (SHARED_BOARDS_INFO *)pmem;
  
  info->active_num = 0;
  for (k=0; k<MAX_ACTIVE_BOARDS; k++)
  { info->boards[k].initialized = 0; }
}


int board_is_initialized(int number, BOARD_INIT_STRUCT *board)
{
  ULONG init;
  SHARED_BOARDS_INFO *info;
  BOARD_INIT_STRUCT *boards;

  RtWaitForSingleObject(ShMemMutex, INFINITE);
  info = (SHARED_BOARDS_INFO *)pSharedMem;
  boards = info->boards;
  boards += number;
  shared_board_data = boards;
  boards->busy = 1;
  if ((init = boards->initialized) == 0)
  {
    *boards = *board;
  }
  else
  {
	*board = *boards;
  }  
  boards->initialized = init+1;
  boards->busy = 0;
  info->active_num++;
  RtReleaseMutex(ShMemMutex);

  return init;
}

int board_is_cleared(int number)
{
  ULONG init;
  SHARED_BOARDS_INFO *info;
  BOARD_INIT_STRUCT *boards;

  RtWaitForSingleObject(ShMemMutex, INFINITE);
  info = (SHARED_BOARDS_INFO *)pSharedMem;
  if (info->active_num == 0)
  {
    RtReleaseMutex(ShMemMutex);
    return -1;
  }
  boards = info->boards;
  boards += number;
  boards->busy = 1;
  if ((init = boards->initialized) == 0)  
  {
    RtReleaseMutex(ShMemMutex);
	return -2;
  }
  boards->initialized = init-1;
  boards->busy = 0;
  info->active_num--;
  RtReleaseMutex(ShMemMutex);

  return init-1;
}

ULONG pass_interrupt_to_next()
{
  if ((IntPass == 0) || (shared_board_data->busy != 0) ||
	  (shared_board_data->int_serviced >= shared_board_data->initialized-1))
  {
    shared_board_data->int_serviced = 0;
    return 0;
  }
  shared_board_data->int_serviced++;

  return 1;
}

⌨️ 快捷键说明

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