echortos wrote on Thursday, September 10, 2009:
I try to duplicate comtest ( vAltStartComTestTasks,vAltStartComTestTasks2 ).
it can run only one task. when all it run my board is not work. How to slove it.
echortos wrote on Thursday, September 10, 2009:
I try to duplicate comtest ( vAltStartComTestTasks,vAltStartComTestTasks2 ).
it can run only one task. when all it run my board is not work. How to slove it.
rtel wrote on Thursday, September 10, 2009:
You need to:
1) Provide more information about what you have done.
2) Provide more information about what is not working.
This is such a vague question that nobody could possibly give you a useful answer.
Regards.
echortos wrote on Thursday, September 10, 2009:
I duplicate serial.c to serial_uart1.c . I duplicate it by change funcion name and parameter exp.
static xQueueHandle xRxedCharsUart1;
static xQueueHandle xCharsForTxUart1;
static portBASE_TYPE xTxHasEndedUart1;
/*-----------------------------------------------------------*/
xComPortHandle2 xSerialPortInitMinimalUart1( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
next. I duplicate comtest.c to comtestuart1.c by same method.
next. I run a duplicate task vAltStartComTestTasks2 on main program. it work.
But when i run original vAltStartComTestTasks and vAltStartComTestTasks2 on main progarm. it not work. anything is not run. On serial comport is not any signal.
I a beginer for RTOS. I want to know . How to solve it? and What is happen?
Thank you.
echortos wrote on Thursday, September 10, 2009:
/* Demo app include files. */
#include "serial_uart1.h"
/* Hardware setup. */
#define serOUTPUT 0
#define serINPUT 1
#define serLOW_SPEED 0
#define serONE_STOP_BIT 0
#define serEIGHT_DATA_BITS_NO_PARITY 0
#define serNORMAL_IDLE_STATE 0
#define serAUTO_BAUD_OFF 0
#define serLOOPBACK_OFF 0
#define serWAKE_UP_DISABLE 0
#define serNO_HARDWARE_FLOW_CONTROL 0
#define serSTANDARD_IO 0
#define serNO_IRDA 0
#define serCONTINUE_IN_IDLE_MODE 0
#define serUART_ENABLED 1
#define serINTERRUPT_ON_SINGLE_CHAR 0
#define serTX_ENABLE 1
#define serINTERRUPT_ENABLE 1
#define serINTERRUPT_DISABLE 0
#define serCLEAR_FLAG 0
#define serSET_FLAG 1
/* The queues used to communicate between tasks and ISR’s. */
static xQueueHandle xRxedCharsUart1;
static xQueueHandle xCharsForTxUart1;
static portBASE_TYPE xTxHasEndedUart1;
/*-----------------------------------------------------------*/
xComPortHandle2 xSerialPortInitMinimalUart1( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
portCHAR cChar;
/* Create the queues used by the com test task. */
xRxedCharsUart1= xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
xCharsForTxUart1 = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
/* Setup the UART. */
U1MODEbits.BRGH = serLOW_SPEED;
U1MODEbits.STSEL = serONE_STOP_BIT;
U1MODEbits.PDSEL = serEIGHT_DATA_BITS_NO_PARITY;
U1MODEbits.RXINV = serNORMAL_IDLE_STATE;
U1MODEbits.ABAUD = serAUTO_BAUD_OFF;
U1MODEbits.LPBACK = serLOOPBACK_OFF;
U1MODEbits.WAKE = serWAKE_UP_DISABLE;
U1MODEbits.UEN = serNO_HARDWARE_FLOW_CONTROL;
U1MODEbits.IREN = serNO_IRDA;
U1MODEbits.USIDL = serCONTINUE_IN_IDLE_MODE;
U1MODEbits.UARTEN = serUART_ENABLED;
U1BRG = (unsigned portSHORT)(( (float)configCPU_CLOCK_HZ / ( (float)16 * (float)ulWantedBaud ) ) - (float)0.5);
U1STAbits.URXISEL = serINTERRUPT_ON_SINGLE_CHAR;
U1STAbits.UTXEN = serTX_ENABLE;
U1STAbits.UTXINV = serNORMAL_IDLE_STATE;
U1STAbits.UTXISEL0 = serINTERRUPT_ON_SINGLE_CHAR;
U1STAbits.UTXISEL1 = serINTERRUPT_ON_SINGLE_CHAR;
/* It is assumed that this function is called prior to the scheduler being
started. Therefore interrupts must not be allowed to occur yet as they
may attempt to perform a context switch. */
portDISABLE_INTERRUPTS();
IFS0bits.U1RXIF = serCLEAR_FLAG;
IFS0bits.U1TXIF = serCLEAR_FLAG;
IPC2bits.U1RXIP = configKERNEL_INTERRUPT_PRIORITY;
IPC3bits.U1TXIP = configKERNEL_INTERRUPT_PRIORITY;
IEC0bits.U1TXIE = serINTERRUPT_ENABLE;
IEC0bits.U1RXIE = serINTERRUPT_ENABLE;
/* Clear the Rx buffer. */
while( U1STAbits.URXDA == serSET_FLAG )
{
cChar = U1RXREG;
}
xTxHasEndedUart1 = pdTRUE;
return NULL;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialGetCharUart1( xComPortHandle2 pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
{
/* Only one port is supported. */
( void ) pxPort;
/* Get the next character from the buffer. Return false if no characters
are available or arrive before xBlockTime expires. */
if( xQueueReceive( xRxedCharsUart1, pcRxedChar, xBlockTime ) )
{
return pdTRUE;
}
else
{
return pdFALSE;
}
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialPutCharUart1( xComPortHandle2 pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
{
/* Only one port is supported. */
( void ) pxPort;
/* Return false if after the block time there is no room on the Tx queue. */
if( xQueueSend( xCharsForTxUart1, &cOutChar, xBlockTime ) != pdPASS )
{
return pdFAIL;
}
/* A critical section should not be required as xTxHasEnded will not be
written to by the ISR if it is already 0 (is this correct?). */
if( xTxHasEndedUart1 )
{
xTxHasEndedUart1 = pdFALSE;
IFS0bits.U1TXIF = serSET_FLAG;
}
return pdPASS;
}
/*-----------------------------------------------------------*/
void vSerialCloseUart1( xComPortHandle2 xPort )
{
}
/*-----------------------------------------------------------*/
void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt( void )
{
portCHAR cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Get the character and post it on the queue of Rxed characters.
If the post causes a task to wake force a context switch as the woken task
may have a higher priority than the task we have interrupted. */
IFS0bits.U1RXIF = serCLEAR_FLAG;
while( U1STAbits.URXDA )
{
cChar = U1RXREG;
xQueueSendFromISR( xRxedCharsUart1, &cChar, &xHigherPriorityTaskWoken );
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
taskYIELD();
}
}
/*-----------------------------------------------------------*/
void __attribute__((__interrupt__, auto_psv)) _U1TXInterrupt( void )
{
signed portCHAR cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* If the transmit buffer is full we cannot get the next character.
Another interrupt will occur the next time there is space so this does
not matter. */
IFS0bits.U1TXIF = serCLEAR_FLAG;
while( !( U1STAbits.UTXBF ) )
{
if( xQueueReceiveFromISR( xCharsForTxUart1, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Send the next character queued for Tx. */
U1TXREG = cChar;
}
else
{
/* Queue empty, nothing to send. */
xTxHasEndedUart1 = pdTRUE;
break;
}
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
taskYIELD();
}
}
echortos wrote on Thursday, September 10, 2009:
Code for ComtestUart1.c
/* Demo app include files. */
#include "serial_uart1.h"
/* Hardware setup. */
#define serOUTPUT 0
#define serINPUT 1
#define serLOW_SPEED 0
#define serONE_STOP_BIT 0
#define serEIGHT_DATA_BITS_NO_PARITY 0
#define serNORMAL_IDLE_STATE 0
#define serAUTO_BAUD_OFF 0
#define serLOOPBACK_OFF 0
#define serWAKE_UP_DISABLE 0
#define serNO_HARDWARE_FLOW_CONTROL 0
#define serSTANDARD_IO 0
#define serNO_IRDA 0
#define serCONTINUE_IN_IDLE_MODE 0
#define serUART_ENABLED 1
#define serINTERRUPT_ON_SINGLE_CHAR 0
#define serTX_ENABLE 1
#define serINTERRUPT_ENABLE 1
#define serINTERRUPT_DISABLE 0
#define serCLEAR_FLAG 0
#define serSET_FLAG 1
/* The queues used to communicate between tasks and ISR’s. */
static xQueueHandle xRxedCharsUart1;
static xQueueHandle xCharsForTxUart1;
static portBASE_TYPE xTxHasEndedUart1;
/*-----------------------------------------------------------*/
xComPortHandle2 xSerialPortInitMinimalUart1( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
portCHAR cChar;
/* Create the queues used by the com test task. */
xRxedCharsUart1= xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
xCharsForTxUart1 = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
/* Setup the UART. */
U1MODEbits.BRGH = serLOW_SPEED;
U1MODEbits.STSEL = serONE_STOP_BIT;
U1MODEbits.PDSEL = serEIGHT_DATA_BITS_NO_PARITY;
U1MODEbits.RXINV = serNORMAL_IDLE_STATE;
U1MODEbits.ABAUD = serAUTO_BAUD_OFF;
U1MODEbits.LPBACK = serLOOPBACK_OFF;
U1MODEbits.WAKE = serWAKE_UP_DISABLE;
U1MODEbits.UEN = serNO_HARDWARE_FLOW_CONTROL;
U1MODEbits.IREN = serNO_IRDA;
U1MODEbits.USIDL = serCONTINUE_IN_IDLE_MODE;
U1MODEbits.UARTEN = serUART_ENABLED;
U1BRG = (unsigned portSHORT)(( (float)configCPU_CLOCK_HZ / ( (float)16 * (float)ulWantedBaud ) ) - (float)0.5);
U1STAbits.URXISEL = serINTERRUPT_ON_SINGLE_CHAR;
U1STAbits.UTXEN = serTX_ENABLE;
U1STAbits.UTXINV = serNORMAL_IDLE_STATE;
U1STAbits.UTXISEL0 = serINTERRUPT_ON_SINGLE_CHAR;
U1STAbits.UTXISEL1 = serINTERRUPT_ON_SINGLE_CHAR;
/* It is assumed that this function is called prior to the scheduler being
started. Therefore interrupts must not be allowed to occur yet as they
may attempt to perform a context switch. */
portDISABLE_INTERRUPTS();
IFS0bits.U1RXIF = serCLEAR_FLAG;
IFS0bits.U1TXIF = serCLEAR_FLAG;
IPC2bits.U1RXIP = configKERNEL_INTERRUPT_PRIORITY;
IPC3bits.U1TXIP = configKERNEL_INTERRUPT_PRIORITY;
IEC0bits.U1TXIE = serINTERRUPT_ENABLE;
IEC0bits.U1RXIE = serINTERRUPT_ENABLE;
/* Clear the Rx buffer. */
while( U1STAbits.URXDA == serSET_FLAG )
{
cChar = U1RXREG;
}
xTxHasEndedUart1 = pdTRUE;
return NULL;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialGetCharUart1( xComPortHandle2 pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
{
/* Only one port is supported. */
( void ) pxPort;
/* Get the next character from the buffer. Return false if no characters
are available or arrive before xBlockTime expires. */
if( xQueueReceive( xRxedCharsUart1, pcRxedChar, xBlockTime ) )
{
return pdTRUE;
}
else
{
return pdFALSE;
}
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialPutCharUart1( xComPortHandle2 pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
{
/* Only one port is supported. */
( void ) pxPort;
/* Return false if after the block time there is no room on the Tx queue. */
if( xQueueSend( xCharsForTxUart1, &cOutChar, xBlockTime ) != pdPASS )
{
return pdFAIL;
}
/* A critical section should not be required as xTxHasEnded will not be
written to by the ISR if it is already 0 (is this correct?). */
if( xTxHasEndedUart1 )
{
xTxHasEndedUart1 = pdFALSE;
IFS0bits.U1TXIF = serSET_FLAG;
}
return pdPASS;
}
/*-----------------------------------------------------------*/
void vSerialCloseUart1( xComPortHandle2 xPort )
{
}
/*-----------------------------------------------------------*/
void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt( void )
{
portCHAR cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Get the character and post it on the queue of Rxed characters.
If the post causes a task to wake force a context switch as the woken task
may have a higher priority than the task we have interrupted. */
IFS0bits.U1RXIF = serCLEAR_FLAG;
while( U1STAbits.URXDA )
{
cChar = U1RXREG;
xQueueSendFromISR( xRxedCharsUart1, &cChar, &xHigherPriorityTaskWoken );
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
taskYIELD();
}
}
/*-----------------------------------------------------------*/
void __attribute__((__interrupt__, auto_psv)) _U1TXInterrupt( void )
{
signed portCHAR cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* If the transmit buffer is full we cannot get the next character.
Another interrupt will occur the next time there is space so this does
not matter. */
IFS0bits.U1TXIF = serCLEAR_FLAG;
while( !( U1STAbits.UTXBF ) )
{
if( xQueueReceiveFromISR( xCharsForTxUart1, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Send the next character queued for Tx. */
U1TXREG = cChar;
}
else
{
/* Queue empty, nothing to send. */
xTxHasEndedUart1 = pdTRUE;
break;
}
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
taskYIELD();
}
}