📄 os_viewc.c
字号:
/*
*********************************************************************************************************
* uC/OS-View
*
* (c) Copyright 2002, Micrium, Inc., WESTON, FL
* All Rights Reserved
*
* Intel 80x86 (Large Model)
*
* Filename : OS_VIEWc.C
* Programmer : Jean J. Labrosse
*********************************************************************************************************
*/
#include "includes.h"
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
#define BIT0 0x01 /* Bit masks */
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define OS_VIEW_8250_RBR 0 /* UART register definitions */
#define OS_VIEW_8250_THR 0
#define OS_VIEW_8250_DIV_LO 0
#define OS_VIEW_8250_DIV_HI 1
#define OS_VIEW_8250_IER 1
#define OS_VIEW_8250_IIR 2
#define OS_VIEW_8250_LCR 3
#define OS_VIEW_8250_MCR 4
#define OS_VIEW_8250_LSR 5
#define OS_VIEW_8250_MSR 6
#define OS_VIEW_8250_PARITY_NONE 0 /* Defines for setting parity */
#define OS_VIEW_8250_PARITY_ODD 1
#define OS_VIEW_8250_PARITY_EVEN 2
#define OS_VIEW_8259_INT_REG 0x0020 /* 8259 Priority Interrupt Controller (PIC) */
#define OS_VIEW_8259_MASK_REG 0x0021
#define OS_VIEW_8259_OCW3_REG 0x0020
#define OS_VIEW_8259_SEL_IRR 0x0A
#define OS_VIEW_8259_IRR_REG 0x0020
#define OS_VIEW_8254_CTR0 0x40 /* 8254 PIT Timer 0 Register address. */
#define OS_VIEW_8254_CTR1 0x41 /* 8254 PIT Timer 1 Register address. */
#define OS_VIEW_8254_CTR2 0x42 /* 8254 PIT Timer 2 Register address. */
#define OS_VIEW_8254_CWR 0x43 /* 8254 PIT Control Word Register address. */
#define OS_VIEW_8254_CTR0_MODE3 0x36 /* 8254 PIT Binary Mode 3 for Counter 0 control word. */
#define OS_VIEW_8254_CTR2_MODE0 0xB0 /* 8254 PIT Binary Mode 0 for Counter 2 control word. */
#define OS_VIEW_8254_CTR0_LATCH 0x00 /* 8254 PIT Latch command control word */
#define OS_VIEW_8254_CTR2_LATCH 0x80
#define OS_VIEW_8255_TMR_EN_REG 0x61 /* 8255 used to enable Timer #2 */
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
static INT32U OSView_TmrOvfCtr;
static INT16U OSView_TmrCntsPrev;
static void (*OSView_CommISROld)(void);
/*
*********************************************************************************************************
* LOCAL PROTOTYPES
*********************************************************************************************************
*/
static void OSView_CfgPort(INT16U baud, INT8U bits, INT8U parity, INT8U stops);
static void OSView_IntVectSet(void);
static void OSView_IntVectRcl(void);
static INT8U OSView_PortIn8(INT16U port);
static void OSView_PortOut8(INT16U port, INT8U data);
/*$PAGE*/
/*
*********************************************************************************************************
* EXIT uC/OS-View
*
* Description:
*
* Note(s) :
*********************************************************************************************************
*/
void OSView_Exit (void)
{
OSView_RxIntDis();
OSView_TxIntDis();
OSView_IntVectRcl(); /* Un-install the COM Interrupt vector */
}
/*
*********************************************************************************************************
* Obtain CPU name
*********************************************************************************************************
*/
void OSView_GetCPUName (char *s)
{
strcpy(s, "80x86 (Large)");
}
/*
*********************************************************************************************************
* Obtain Interrupt Stack information
*********************************************************************************************************
*/
INT32U OSView_GetIntStkBase (void)
{
return (0); /* We are not using an ISR stack */
}
INT32U OSView_GetIntStkSize (void)
{
return (0); /* We are not using an ISR stack */
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE uC/OS-View COM PORT
*
* Description: Initialize the hardware required for the OS to run. This will work on any target hardware,
* but may have to be tailored a little for:
* Interrupt vectors
* Time measurement timer
* Communications port
* etc.
*
* Note(s) : 1) Timer #2 is used to measure task execution time.
*********************************************************************************************************
*/
void OSView_InitTarget (void)
{
INT8U data;
OSView_CfgPort(OS_VIEW_BAUDRATE, 8, OS_VIEW_8250_PARITY_NONE, 1);
OSView_IntVectSet();
OSView_PortOut8(OS_VIEW_8254_CWR, OS_VIEW_8254_CTR2_MODE0); /* Initialize Timer #2 on the PC */
OSView_PortOut8(OS_VIEW_8254_CTR2, 0xFF);
OSView_PortOut8(OS_VIEW_8254_CTR2, 0xFF);
data = (INT8U)OSView_PortIn8(OS_VIEW_8255_TMR_EN_REG); /* Enable timer #2 */
data |= BIT0;
OSView_PortOut8(OS_VIEW_8255_TMR_EN_REG, data);
OSView_TmrOvfCtr = 0L; /* Clear variables used to keep track of Tmr#2 overflows */
OSView_TmrCntsPrev = 0L;
OSView_RxIntEn(); /* Enable Rx interrupts */
}
/*$PAGE*/
/*
*********************************************************************************************************
* DISABLE RX INTERRUPTS
*
* Description : This function disables Rx interrupts.
*********************************************************************************************************
*/
void OSView_RxIntDis (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U stat;
INT8U mask;
OS_ENTER_CRITICAL();
stat = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_IER) & ~BIT0; /* Disable Rx interrupts */
OSView_PortOut8(OS_VIEW_8250_BASE + OS_VIEW_8250_IER, stat);
if (stat == 0x00) { /* Both Tx & Rx interrupts are disabled ? */
mask = OSView_PortIn8(OS_VIEW_8259_MASK_REG); /* Yes, disable IRQ on the PC */
mask |= OS_VIEW_8259_COMM_INT_EN;
OSView_PortOut8(OS_VIEW_8259_MASK_REG, mask);
}
OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
* ENABLE RX INTERRUPTS
*
* Description : This function enables the Rx interrupt.
*********************************************************************************************************
*/
void OSView_RxIntEn (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U stat;
INT8U cmd;
OS_ENTER_CRITICAL();
stat = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_IER) | BIT0; /* Enable Rx interrupts */
OSView_PortOut8(OS_VIEW_8250_BASE + OS_VIEW_8250_IER, stat);
cmd = OSView_PortIn8(OS_VIEW_8259_MASK_REG) & ~OS_VIEW_8259_COMM_INT_EN;
OSView_PortOut8(OS_VIEW_8259_MASK_REG, cmd); /* Enable IRQ on the PC */
OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
* Rx Communication handler for uC/OS-View
* (NOT USED for PC since OSView_RxTxHandler() handles this)
*********************************************************************************************************
*/
void OSView_RxISRHandler (void)
{
}
/*$PAGE*/
/*
*********************************************************************************************************
* Rx/Tx Communication handler for uC/OS-View
*
* Description: This function is called by OSView_RxTxISR (see OS_VIEWa.ASM) to process a received
* or transmitted character interrupt.
*
* On the PC, we get a single interrupt whether it's because we received a character or
* because a character has been transmitted.
*********************************************************************************************************
*/
void OSView_RxTxISRHandler (void)
{
INT8U c;
INT8U iir; /* Interrupt Identification Register (IIR) */
iir = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_IIR) & 0x07; /* Get contents of IIR */
while ((iir & 0x01) == 0) { /* Loop until we have no more events */
switch (iir) {
case 0: /* See if we have a Modem Status interrupt */
c = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_MSR); /* Clear interrupt (do nothing about it!) */
break;
case 2: /* See if we have a Tx interrupt */
OSView_TxCtr++;
OSView_TxHandler();
break;
case 4: /* See if we have an Rx interrupt */
OSView_RxCtr++;
c = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_RBR); /* Process received character */
OSView_RxHandler(c);
break;
case 6: /* See if we have a Line Status interrupt */
c = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_LSR); /* Clear interrupt (do nothing about it!) */
break;
}
iir = OSView_PortIn8(OS_VIEW_8250_BASE + OS_VIEW_8250_IIR) & 0x07; /* Get contents of IIR */
}
OSView_PortOut8(OS_VIEW_8259_INT_REG, 0x20); /* Reset interrupt controller */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -