Duplicate Comtest On PIC24 DEMO

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();
    }
}