Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Homepage FreeRTOS+ Products FreeRTOS Labs Integration Services Contact / Enquiries

Creating FreeRTOS+Nabto Applications
Part 2: Worked Examples


<<< Previous: Creating Applications Part 1 - Nabto Queries and the Event Handling C Function

Event handler function prototype

Part 1 of this integration guide described the interface between the FreeRTOS+Nabto C source files and the user's embedded application as a single event handling C function. The prototype of the C function is shown in Listing 1.

The event handler is called automatically each time a Nabto query is received. One of the handler's parameters is used to pass the query's request parameters into the C function, another parameter is used to pass any response parameters that might be generated out of the C function. The query ID is used to determine both the number of, and the format of, the request and response parameters.

Example implementations that handle the queries used in the live demo are provided on this page.


/*
 * Parameters:
 * pxRequest     A pointer to a structure that contains details of the query, 
 *               including the query's unique ID.
 * pxReadBuffer  A buffer that contains the request parameters. Do not read from 
 *               the buffer directly. Access functions are provided.
 * pxWriteBuffer A buffer into which response parameters are written. Do not 
 *               write to the buffer directly. Access functions are provided.
 */
application_event_result_t application_event( application_request_t* pxRequest,
                                              buffer_read_t* pxReadBuffer,
                                              buffer_write_t* pxWriteBuffer );
						
Listing 1: The prototype of the FreeRTOS+Nabto application event handler



Worked examples from the live demo

This section provides an event handler implementation for each of the queries used in the live demo.


Live demo query #1: Get RTOS tick count

In the live demo query ID #1 is used to obtain the RTOS tick count.

Query ID #1: Get RTOS tick count
Request Parameters:  None 
Response Parameters:  The RTOS tick count value, transmitted as a 32-bit unsigned integer 


The source code that handles query #1 is shown in Listing 2. Notes:

  • Listing 2 shows an event handler that has the standard prototype already introduced in Listing 1.

  • pxRequest->query_id holds the ID of the query the event handler was called to process.

  • Query #1 does not have any request parameters so pxReadBuffer is not accessed.

  • The response parameter (the RTOS tick count) is not written to pxWriteBuffer directly, but indirectly using the Nabto buffer_write_uint32() function. buffer_write_uint32() is used because the RTOS tick count is an unsigned 32-bit integer (uint32).

  • In this case there is only one response parameter, but if there were two or more response parameters then each would be written to pxWriteBuffer in turn using the appropriate buffer_write_nnn() function.

  • For simplicity Listing 2 only shows query ID 1 being handled. In the real code the switch() statement includes a case for each query ID used by the demo.

  • xTaskGetTickCount() is just the standard FreeRTOS API function that returns the RTOS tick count value.



/* Define a text constant for query ID #1. */
#define sysQUERY_TICK_VALUE	 1

/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
                                              buffer_read_t* pxReadBuffer,
                                              buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;

    /*
     * The bullet points directly above this code listing provide an explanation of
     * the following code.
     */
    switch( request->query_id )
    {
        case sysQUERY_TICK_VALUE:

            /* Write the response parameter to pxWriteBuffer. */
            if( buffer_write_uint32( pxWriteBuffer, xTaskGetTickCount() ) == pdFAIL )
            {
                /* The response parameter would not fit in the write buffer. */
                xReturn = AER_REQ_RSP_TOO_LARGE;
            }
            else
            {
                /* The write buffer contains the value of the response parameter. */
                xReturn = AER_REQ_RESPONSE_READY;
            }
            break;
    }

    return xReturn;
}
						
Listing 2: Source code to handle query #1



Live demo query #2: Get network statistic

In the live demo query ID #2 is used to obtain one of three different network statistics.

Query ID #2: Get network statistic
Request Parameters:  The ID of the statistic being queried, received as a 32-bit unsigned integer 
Response Parameters:  The value of the network statistic that corresponds to the ID received as the request parameter, transmitted as a 32-bit unsigned integer 


The source code that handles query #2 is shown in Listing 3. The notes above listing 2 are also relevant to listing 3. In addition:

  • The request parameter (the ID of the statistic being queried) is not read from pxReadBuffer directly, but indirectly using the Nabto buffer_read_uint32() function. buffer_read_uint32() is used because in this case the request parameter is an unsigned 32-bit integer (uint32).

  • The value of the request parameter is set by the three radio buttons on the user interface. It is used to tell the networked device whether it should respond with:

    • The number of Ethernet packets it has received
    • The number of Ethernet packets it has sent
    • The number of ARP packets it has generated

    prvGetNetworkStatistic() returns the value of the network statistic that corresponds to the value of the request parameter.

  • In this case there is only one request parameter, but if there were two or more request parameters then each would be read from pxReadBuffer in turn using the appropriate buffer_read_nnn() function.



/* Define a text constant for query ID #2. */
#define sysQUERY_NET_STAT  2

/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
                                              buffer_read_t* pxReadBuffer,
                                              buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;
unsigned long ulRequestParameter, ulStatValue;

    /*
     * The bullet points directly above this code listing provide an explanation
     * of the following code.
     */
    switch( request->query_id )
    {
        case sysQUERY_NET_STAT:

            /* Read the request parameter from pxReadBuffer. */
            if( buffer_read_uint32( pxReadBuffer, &ulRequestParameter ) == pdFAIL )
            {
                /* There are two few bytes remaining in pxReadBuffer to complete the
                read request. */
                xReturn = AER_REQ_TOO_SMALL;
            }
            else
            {
                ulStatValue = prvGetNetworkStatistic( ulRequestParameter );

                /* Write the response parameter to pxWriteBuffer. */
                if( buffer_write_uint32( pxWriteBuffer, ulStatValue ) == pdFAIL )
                {
                    /* The response parameter would not fit in the write buffer. */
                    xReturn = AER_REQ_RSP_TOO_LARGE;
                }
                else
                {
                    /* The write buffer contains the value of the response parameter. */
                    xReturn = AER_REQ_RESPONSE_READY;
                }
            }
    }

    return xReturn;
}
						
Listing 3: Source code to handle query #2




Live demo query #3: FreeRTOS command console

In the live demo query ID #3 is used to access the FreeRTOS command console.

Query ID #3: FreeRTOS command console
Request Parameters:  The command entered by the user, received as a raw data buffer 
Response Parameters:  The ascii text generated when the received command was executed, transmitted as a raw data buffer 


The source code that handles query #3 is shown in Listing 4. The notes above listing 2 and listing 3 are also relevant to listing 4. In addition:

  • Strings are handled as raw data. Both the request and the response parameters are strings, so the parameters are read from and written to their respective buffers using the Nabto buffer_read_raw() and buffer_write_raw() functions.

  • The structure buffer_t is used to describe raw data, rather than hold data directly. The structure member called data is used to point to a buffer that actually holds the data, and its member called size is used to hold the length of the data that is being pointed to.

  • prvProcessCommandString() calls FreeRTOS_CLIProcessCommand() (a standard FreeRTOS+CLI API function) to run the command. FreeRTOS_CLIProcessCommand() is not called directly because a small amount of post processing is necessary to convert the generated string into the format required by the user interface.



/* Define a text constant for query ID #3. */
#define sysQUERY_COMMAND_STRING  3

/* Dimensions local buffers to be large enough to hold one line of input/output. */
#define sysMAX_LINE_LENGTH  128

/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
                                              buffer_read_t* pxReadBuffer,
                                              buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;
buffer_t xRawBuffer;
static uint8_t ucLocalBuffer[ sysMAX_LINE_LENGTH ];

    /*
     * The bullet points directly above this code listing provide an explanation
     * of the following code.
     */
    switch( request->query_id )
    {
        case sysQUERY_COMMAND_STRING:
            /* The locally declared raw buffer is used to point to the locally
            declared ucLocalBuffer array. */
            xRawBuffer.data = ucLocalBuffer;
            xRawBuffer.size = sizeof( ucLocalBuffer );

            /* Read raw data from pxReadBuffer into the buffer pointed to by
            pxReadBuffer (pxReadBuffer is pointing to ucLocalBuffer). */
            if( buffer_read_raw( pxReadBuffer, &xRawBuffer ) != pdFALSE )
            {
                /* ucLocalBuffer now holds the command string.  Ensure it is
                terminated. */
                ucLocalBuffer[ xRawBuffer.size ] = 0x00;

                /* Execute the command.  xRawBuffer is now set to point to the
                output generated when the command was executed. */
                xRawBuffer.data = prvProcessCommandString( ucLocalBuffer );

                /* Update the length of data in the raw buffer to reflect the
                length of the string it now contains. */
                xRawBuffer.size = strlen( xRawBuffer.data );

                /* Write the raw buffer to the output buffer. */
                if( buffer_write_raw( pxWriteBuffer, &xRawBuffer ) == pdFALSE )
                {
                    xReturn = AER_REQ_RSP_TOO_LARGE;
                }
                else
                {
                    xReturn = AER_REQ_RESPONSE_READY;
                }
            }
            else
            {
                xReturn = AER_REQ_TOO_SMALL;
            }
            break;
    }

    return xReturn;
}
						
Listing 4: Source code to handle query #3











[ Back to the top ]    [ About FreeRTOS ]    [ FreeRTOS+ Sitemap ]    [ Main FreeRTOS Sitemap ]    [ ]


Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.