📄 os_viewc.c
字号:
}
/*$PAGE*/
/*
*********************************************************************************************************
* Update 32-bits cycles counter
*
* Description: This function must be called by OSTimeTickHook() and is used to maintain a 32 bit counter
* of clock cycles.
*
* On the PC, Timer #2 is used but, Timer #2 is only a 16-bit counter. In order to get a
* 32-bit value, this function must be called at every tick which is assumed to be every
* 5 mS (200 Hz) on the PC. This function basically samples the current value of timer #2
* in order to avoid having to keep track of overflows.
* Timer #2 is feed by a 1,193,180 Hz clock source and thus, Timer #2 rolls over every
* 54.925 milliseconds.
*
* Returns : None
*
* Note(s) : Changes the global variable OSViewCyclesCtr
*********************************************************************************************************
*/
void OSView_TickHook (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U low;
INT8U high;
INT16U cnts;
INT16U cnts8254;
OS_ENTER_CRITICAL();
OSView_PortOut8(OS_VIEW_8254_CWR, OS_VIEW_8254_CTR2_LATCH); /* Read current Timer #2 counts */
low = OSView_PortIn8(OS_VIEW_8254_CTR2); /* ... First LOW byte */
high = OSView_PortIn8(OS_VIEW_8254_CTR2); /* ... Now HIGH byte */
cnts8254 = ((INT16U)high << 8) + (INT16U)low;
cnts = (INT16U)0xFFFF - cnts8254; /* Down counter, convert to absolute */
OSView_CyclesCtr += cnts - OSView_TmrCntsPrev;
OSView_TmrCntsPrev = cnts; /* Save current counts for next time */
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/*
*********************************************************************************************************
* Get time [cycles]
*
* Description: This routine is required for task execution time measurement. This function needs to
* return time as accurately as possible and in a 32-bit variable.
*
* On the PC, the cycles counter is actually updated by the tick ISR (see OSView_TickHook()).
* Because of this, this function only needs to return the value of the global counter
* OSView_CyclesCtr.
*
* Returns : A 32-bit representation of time.
*********************************************************************************************************
*/
INT32U OSView_TimeGetCycles (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT32U cycles;
OS_ENTER_CRITICAL();
cycles = OSView_CyclesCtr;
OS_EXIT_CRITICAL();
return (cycles);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Communication for uC/OS-View
*
* Description: Send 1 character to COM Port
*
* Note(s) : 1) Assumes UART #0
*********************************************************************************************************
*/
void OSView_Tx1 (INT8U c)
{
OSView_PortOut8(OS_VIEW_8250_BASE + OS_VIEW_8250_THR, c);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Disable Tx Interrupts
*********************************************************************************************************
*/
void OSView_TxIntDis (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) & ~BIT1; /* Disable Tx 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);
mask |= OS_VIEW_8259_COMM_INT_EN;
OSView_PortOut8(OS_VIEW_8259_MASK_REG, mask); /* Yes, disable IRQ on the PC */
}
OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
* Enable Tx Interrupts
*********************************************************************************************************
*/
void OSView_TxIntEn (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) | BIT1; /* Enable Tx 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();
}
/*$PAGE*/
/*
*********************************************************************************************************
* Tx Communication handler for uC/OS-View
* (NOT USED for PC since OSView_RxTxHandler() handles this)
*********************************************************************************************************
*/
void OSView_TxISRHandler (void)
{
}
/*
*********************************************************************************************************
* CONFIGURE PORT
*
* Description : This function is used to configure a serial I/O port. This code is for IBM-PCs and
* compatibles and assumes a National Semiconductor NS16450.
*
* Arguments : 'baud' is the desired baud rate (anything, standard rates or not)
* 'bits' defines the number of bits used and can be either 5, 6, 7 or 8.
* 'parity' specifies the 'parity' to use:
* OS_VIEW_8250_PARITY_NONE
* OS_VIEW_8250_PARITY_ODD
* OS_VIEW_8250_PARITY_EVEN
* 'stops' defines the number of stop bits used and can be either 1 or 2.
*
* Returns : NOTHING
*
* Notes : 1) Refer to the NS16450 Data sheet
* 2) The constant 115200 is based on a 1.8432 MHz crystal oscillator and a 16 x Clock.
* 3) 'lcr' is the Line Control Register and is define as:
*
* B7 B6 B5 B4 B3 B2 B1 B0
* ------ #Bits (00 = 5, 01 = 6, 10 = 7 and 11 = 8)
* -- #Stops (0 = 1 stop, 1 = 2 stops)
* -- Parity enable (1 = parity is enabled)
* -- Even parity when set to 1.
* -- Stick parity (see 16450 data sheet)
* -- Break control (force break when 1)
* -- Divisor access bit (set to 1 to access divisor)
* 4) This function enables Rx interrupts but not Tx interrupts.
*********************************************************************************************************
*/
static void OSView_CfgPort (INT16U baud, INT8U bits, INT8U parity, INT8U stops)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16U div; /* Baud rate divisor */
INT8U divlo;
INT8U divhi;
INT8U lcr; /* Line Control Register */
INT16U base; /* COMM port base address */
base = OS_VIEW_8250_BASE;
div = (INT16U)(115200L / (INT32U)baud); /* Compute divisor for desired baud rate */
divlo = div & 0x00FF; /* Split divisor into LOW and HIGH bytes */
divhi = (div >> 8) & 0x00FF;
lcr = ((stops - 1) << 2) + (bits - 5);
switch (parity) {
case OS_VIEW_8250_PARITY_ODD:
lcr |= 0x08; /* Odd parity */
break;
case OS_VIEW_8250_PARITY_EVEN:
lcr |= 0x18; /* Even parity */
break;
}
OS_ENTER_CRITICAL();
OSView_PortOut8(base + OS_VIEW_8250_LCR, BIT7); /* Set divisor access bit */
OSView_PortOut8(base + OS_VIEW_8250_DIV_LO, divlo); /* Load divisor */
OSView_PortOut8(base + OS_VIEW_8250_DIV_HI, divhi);
OSView_PortOut8(base + OS_VIEW_8250_LCR, lcr); /* Set line control register (Bit 8 is 0) */
OSView_PortOut8(base + OS_VIEW_8250_MCR, BIT3 | BIT1 | BIT0); /* Assert DTR and RTS and, allow interrupts */
OSView_PortOut8(base + OS_VIEW_8250_IER, 0x00); /* Disable both Rx and Tx interrupts */
OSView_PortOut8(base + OS_VIEW_8250_IIR, 0x00); /* Disable FIFO mode of 16550 UART */
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/*
*********************************************************************************************************
* SET INTERRUPT VECTOR
*
* Description : This function installs the interrupt vector for the desired communications channel.
* Arguments : none
* Note(s) : This function assumes that the 80x86 is running in REAL mode.
*********************************************************************************************************
*/
static void OSView_IntVectSet (void)
{
OSView_CommISROld = PC_VectGet(OS_VIEW_8250_VECT);
PC_VectSet(OS_VIEW_8250_VECT, OSView_RxTxISR);
}
/*
*********************************************************************************************************
* RESTORE OLD INTERRUPT VECTOR
*
* Description : This function restores the old interrupt vector for the desired communications channel.
* Arguments : none
* Note(s) : This function assumes that the 80x86 is running in REAL mode.
*********************************************************************************************************
*/
static void OSView_IntVectRcl (void)
{
OSView_RxIntDis();
OSView_TxIntDis();
PC_VectSet(OS_VIEW_8250_VECT, OSView_CommISROld);
}
/*$PAGE*/
/*
*********************************************************************************************************
* PORT I/Os
*
* Description: These functions encapsulate accessing I/O ports (both reads and writes).
*********************************************************************************************************
*/
static INT8U OSView_PortIn8 (INT16U port)
{
INT8U data;
data = (INT8U)inp(port);
return (data);
}
static void OSView_PortOut8 (INT16U port, INT8U data)
{
outp(port, data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -