Author Topic: User Documentation Source Code  (Read 21768 times)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
User Documentation Source Code
« on: March 06, 2009, 04:01:51 PM »
Hi All

During the course of updates of user documents the example source code is being added to this thread to enable quick copying of the related code examples.

Regards

Mark

*****************************************************************************

µTasker User Guide – First Steps for New Users

5.   Adding a New Task to Your Project

Code: [Select]
#include "config.h"                        // include all project headers if this is a new file

extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
    static unsigned char ucCounter = 0;

    fnDebugMsg("Hello, World! Test number ");
    fnDebugDec(ucCounter++, 0);                      // note that V1.3 code used an addition , 0 due to a change in this function's use
    fnDebugMsg("\r\n");
}

#define DEMO_UART    1        // use UART 1 (the UART connector on the board) )

#define SERIAL_PORT_0   '3' // if we open UART channel 0 we simulate using com3 on the PC
or
#define SIM_COM_EXTENDED // this uses the value literally and not the ASCII value, which otherwise restricts to COM1..9
#define SERIAL_PORT_0   3 // if we open UART channel 0 we simulate using com3 on the PC

extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable); // prototype

#define TASK_MY_FIRST_TASK      'x'  // my first task's reference

const UTASK_TASK ctNodes[] = {
  DEFAULT_NODE_NUMBER,    // configuration the single node
  TASK_WATCHDOG,
  ...
  TASK_MY_FIRST_TASK,     // add the task to the configuration
  0,                      // end of single configuration

  // insert more node configurations here if required
  0                       // end of configuration list
};

const UTASKTABLEINIT ctTaskTable[] = {
{ "Wdog",fnTaskWatchdog,NO_QUE,0,(DELAY_LIMIT)(0.2 * SEC),  UTASKER_GO}, // watchdog task (runs immediately and then periodically)
   ...
{ "x marks my first task!!", fnMyFirstTask, NO_QUE,(DELAY_LIMIT)(5 * SEC), (DELAY_LIMIT)(2 * SEC),  UTASKER_STOP},      // my first task (runs after a delay of 5s and then periodically every 2s)
...
};

6      Second Example – The Task being configured by another

Code: [Select]
{  “x marks my first task!!”,
    fnMyFirstTask,
    NO_QUE,(DELAY_LIMIT)(NO_DELAY_RESERVE_MONO),
   (DELAY_LIMIT)(0),  UTASKER_STOP},   
   // my first task (a timer has been reserved for its use but not need activated)



if (!fnSetNewSerialMode(FOR_I_O)) {                 // open serial port for I/O
    return;                    // if the serial port could not be opened we quit
}
DebugHandle = SerialPortID;         // assign our serial interface as debug port
uTaskerStateChange(TASK_MY_FIRST_TASK, UTASKER_ACTIVATE);
                                    // activate the new task
uTaskerMonoTimer( TASK_MY_FIRST_TASK, (DELAY_LIMIT)(3 * SEC), 0 );
                                    // set periodic interval


7.    Third Example – Adding a Queue to Your Task and getting it to do a bit more Work

Code: [Select]
{   "x marks my first task!!",
    fnMyFirstTask,
    SMALL_QUEUE,
    (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO),
    (DELAY_LIMIT)(0),
    UTASKER_STOP},


fnInterruptMessage(TASK_MY_FIRST_TASK, WAKE_UP_LITTLE_BABY);

#define WAKE_UP_LITTLE_BABY   132


#define OWN_TASK            TASK_MY_FIRST_TASK
#define E_TIMER_PERIODIC    1


extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
    static unsigned char ucCounter = 0;
    QUEUE_HANDLE  PortIDInternal = ptrTaskTable->TaskID;         // queue ID for task input
    unsigned char ucInputMessage[HEADER_LENGTH];       // reserve space for simple messages

    while ( fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH )) { // check input queue
        switch ( ucInputMessage[MSG_SOURCE_TASK] ) {                   // switch on source
        case TIMER_EVENT:                                              // timer event
            if (E_TIMER_PERIODIC == ucInputMessage[MSG_TIMER_EVENT]) {
                fnDebugMsg("Test number ");
                fnDebugDec(ucCounter++, 0);                   // note that V1.3 code used an addition , 0 due to a change in this function's use
                fnDebugMsg("\r\n");
                if (ucCounter == 10) {
                    fnDebugMsg("Work done!!\r\n");
                    ucCounter = 0;
                }
                else {
                    uTaskerMonoTimer( OWN_TASK, (DELAY_LIMIT)(1*SEC), E_TIMER_PERIODIC );
                }
            }
            break;

        case INTERRUPT_EVENT:
            if (WAKE_UP_LITTLE_BABY == ucInputMessage[MSG_INTERRUPT_EVENT]) {
                fnDebugMsg("Hello World!!\r\n");
                uTaskerMonoTimer( OWN_TASK, (DELAY_LIMIT)(6*SEC), E_TIMER_PERIODIC );
            }
        }
    }
}

*****************************************************************************
« Last Edit: January 02, 2010, 11:57:48 PM by mark »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #1 on: August 25, 2009, 09:14:02 PM »
UART USER'S GUIDE

QUEUE_HANDLE fnOpenUART(void)
{
  TTYTABLE tInterfaceParameters;      // table for passing information to driver
  QUEUE_HANDLE SerialPortID;          // UART handle to be obtained during open
  tInterfaceParameters.Channel = 1;   // set UART channel for serial use
  tInterfaceParameters.ucSpeed = SERIAL_BAUD_19200;           // baud rate 19’200
  tInterfaceParameters.Rx_tx_sizes.RxQueueSize = 256;         // input buffer size
  tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 512;         // output buffer size
  tInterfaceParameters.Task_to_wake = TASK_APPLICATION;       // wake task on rx

#ifdef SUPPORT_FLOW_HIGH_LOW
  tInterfaceParameters.ucFlowHighWater = 80;      // set the flow control high in %
  tInterfaceParameters.ucFlowLowWater = 20;       // set the flow control low in %
#endif

  tInterfaceParameters.usConfig =
                        (CHAR_8 + NO_PARITY + ONE_STOP + USE_XON_OFF + CHAR_MODE);

#ifdef SERIAL_SUPPORT_DMA
  tInterfaceParameters.ucDMAConfig = UART_TX_DMA;   // activate DMA on transmission
#endif
  if ((SerialPortID = fnOpen( TYPE_TTY, FOR_I_O, &tInterfaceParameters )) != 0) {
    // open the channel with defined configurations (initially inactive)
    fnDriver(SerialPortID, ( TX_ON | RX_ON ), 0 );  // enable rx and tx
  }
  return SerialPortID;               // return the serial port handle for this UART
}


Code 1 – example of UART initialization



    SerialPortID = fnOpen(
                   TYPE_TTY,              // serial interface driver type (UART)
                   FOR_I_O,               // for use as input/output device (Rx/Tx)
                   &tInterfaceParameters);// configuration details


Code 2 – the fnOpen() function used to open a serial interface



    fnDriver(
              SerialPortID,                       // the serial interface handle
              ( TX_ON | RX_ON ),                  // enable rx and tx
               0 );                               // unused parameter in this case

Code 3 – the fnDriver() function used to enable receiver and transmitter



extern void fnApplication(TTASKTABLE *ptrTaskTable)
{
    unsigned char ucInputByte;
    while (fnRead( SerialPortID, &ucInputByte, 1) != 0) {
        while (ucInputByte--) {
            toggle_output();
        }
    }
}

Code 4 – a task receiving characters from a UART with handle SerialPortID



extern void fnApplication(TTASKTABLE *ptrTaskTable)
{
    QUEUE_TRANSFER length;
    unsigned char ucInputBuffer[100];
    while ((length = fnMsgs(SerialPortID)) != 0) {// get number of waiting bytes
        if (length > sizeof(ucInputBuffer)) {     // ensure buffer can’t be overrun
            length = sizeof(ucInputBuffer);
        }
        fnRead(SerialPortID, ucInputBuffer, length);     // read to a local buffer
    }
}

Code 5 – a task filling a buffer from a UART with handle SerialPortID




    fnWrite(SerialPortID, (unsigned char *)"1234567890", 10);

Code 6 – transmission of a string to a UART with handle SerialPortID



    if (fnWrite(SerialPortID, 0, 10) == 0) {
        fnDriver(SerialPortID, MODIFY_WAKEUP, (MODIFY_TX | OWN_TASK));
                                                           // enable TX_FREE event
    }
    else {
        fnWrite(SerialPortID, (unsigned char *)"1234567890", 10);
    }


Code 7 – check of output buffer space before transmission




extern void fnDebug(TTASKTABLE *ptrTaskTable)
{
    QUEUE_HANDLE  PortIDInternal = ptrTaskTable->TaskID; // queue ID for task input
    unsigned char ucInputMessage[SMALL_MESSAGE];    // space for receiving messages
    while ( fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH)) { // read input
        switch ( ucInputMessage[ MSG_SOURCE_TASK ] ) {          // switch on source
        case INTERRUPT_EVENT:
            if (TX_FREE == ucInputMessage[MSG_INTERRUPT_EVENT]) {
                fnDisplayHelp(iMenuLocation);// continue sending further menu items
            }
            break;
    }
}

Code 8 – Example of specific handling the TX_FREE event




// Initialisation code for RS485 mode
//
tInterfaceParameters.usConfig |= INFORM_ON_FRAME_TRANSMISSION;
SerialPortID = fnOpen( TYPE_TTY, FOR_I_O, &tInterfaceParameters ):
...
fnDriver(SerialHandle, (MODIFY_CONTROL | CONFIG_RTS_PIN), 0);
                                              // configure RTS pin for control use
fnDriver(SerialHandle, (MODIFY_CONTROL | SET_RTS), 0);       // initially drive '0'



// Message transmission code for RS485 mode
//
fnDriver(SerialHandle, (MODIFY_CONTROL | CLEAR_RTS), 0);          // driver RTS ‘1’
fnWrite(SerialHandle, ucMessageData, length);   // start message frame transmission


Code 9 – Example of configuring for RS485 mode operation and controlling the RTS line when starting message frame transmission



// The UART is informing that it has just completed transmission of the last character in a frame.
// This is used to control RTS de-assertion, usually after a delay
//
extern void fnUARTFrameTermination(QUEUE_HANDLE Channel)
{
    if (Channel == 2) {
      //fnDriver(SerialHandle, (MODIFY_CONTROL | SET_RTS), 0);
                                      can only be used for certain processor types
        fnConfigureInterrupt(&timer_setup_RTS_negate);
                                                    // start delay to RTS negation
    }
}

Code 10 – example of controlling negation of the RTS line on message termination


static TIMER_INTERRUPT_SETUP timer_setup_RTS_negate;

timer_setup_RTS_negate.int_type = TIMER_INTERRUPT
timer_setup_RTS_negate.timer_reference = 2;
timer_setup_RTS_negate.int_priority = 3;
timer_setup_RTS_negate.int_handler  = fnTimer_RTS;
timer_setup_RTS_negate.timer_mode   = (TIMER_SINGLE_SHOT | TIMER_US_VALUE);
timer_setup_RTS_negate.timer_value  = 620;      // 620us delay before RTS negation


Code 11 – Example of RTS timer configuration



// Initialisation code for RS485 mode
//
fnDriver(SerialHandle, (MODIFY_CONTROL | CONFIG_RTS_PIN | SET_RS485_MODE), 0);
                                              // configure RTS pin for control use


Code 12 – Configuring for HW RS485 mode operation




extern QUEUE_TRANSFER fnNetworkTx(unsigned char *output_buffer, QUEUE_TRANSFER nr_of_bytes)
{
    fnWrite(SerialPortID, output_buffer, nr_of_bytes);
    fnWrite(SerialPortID2, output_buffer, nr_of_bytes);
    fnWrite(USB_handle, output_buffer, nr_of_bytes);
    return (fnSendBufTCP(Telnet_socket, output_buffer, nr_of_bytes, (TCP_BUF_SEND | TCP_BUF_SEND_REPORT_COPY)));
}


Code 13 – Example of sending debug output to multiple interfaces

Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #2 on: February 14, 2013, 03:28:59 PM »
Hi
when i try out the first code (5. Adding a New Task to You Projekt) i getting a problem
No source available for "0x0000678C (0x0000678C)() "
This problem i dont understand, is this because my UART not is mapped correct ?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #3 on: February 14, 2013, 06:03:20 PM »
Hi

Which IDE gives this error and when does it display it (building the project, executing ?)

It is recommended to first try building and testing with the simulator before moving to HW targets.

Regards

Mark

Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #4 on: February 15, 2013, 09:39:30 AM »
When i have the new Task in the projekt, i could not simulate, it make a problem with _fnMyNewTask. I took it away and try again, the simulate, but the debug still make same problem :(

Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #5 on: February 15, 2013, 10:15:57 AM »
Okay i have now startet a new project, and i have make the new task and its compile and debug without any problems, only that, that i newer get the hello world message out

Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #6 on: February 15, 2013, 10:25:07 AM »
In the simulation i get this error
Error   1   error LNK2001: unresolved external symbol _fnMyFirstTask   

and that i dont geth
« Last Edit: February 15, 2013, 11:59:22 AM by internship2 »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #7 on: February 15, 2013, 01:58:56 PM »
Hi

In the simulator you need to add your new file to the VisualStudio project - then it will not be missing when linking.

Regards

Mark

Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #8 on: February 18, 2013, 02:31:51 PM »
Hi Mark
Thanks i have now done the simulation.
When i debug o wont the text to be written out, is this possible? 

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #9 on: February 18, 2013, 03:55:11 PM »
Hi

When simulating the debug message outputs go to a UART that can be hooked to a physical UART on the PC. Alternatively, and generally more practical, is to use a virtual COM port loop back (com0com is recommended) so that this can be connected to a terminal emulator. This is descrived here: http://www.utasker.com/forum/index.php?topic=343.0

When a project with Ethernet is running it is also practical to connect to it via Telnet since the debug output is sent there instead when a connection exists.

Regards

Mark


Offline internship2

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: User Documentation Source Code
« Reply #10 on: February 20, 2013, 10:53:07 AM »
Hi Mark
I still geth in a lot of trouble doing the debug msg. I have try to debug, and my code newer get in to the seriel configuration wich i have make the configuration in app_hw_kinetis.h:
#ifdef SERIAL_INTERFACE
    #define WELCOME_MESSAGE_UART   "\r\n\nHello, world... KINETIS\r\n"
    #define NUMBER_EXTERNAL_SERIAL 0
    #define NUMBER_SERIAL   (UARTS_AVAILABLE)                            // the number of physical queues needed for serial interface(s)
    #define SIM_COM_EXTENDED                                             // COM ports defined from 1..255
    #define SERIAL_PORT_0    3                                           // if we open UART channel 0 we simulate using comx on the PC
  //  #define SERIAL_PORT_1    9                                           // if we open UART channel 1 we simulate using comx on the PC
   // #define SERIAL_PORT_2    9                                           // if we open UART channel 2 we simulate using comx on the PC
   // #define SERIAL_PORT_3    9                                           // if we open UART channel 3 we simulate using comx on the PC
   // #define SERIAL_PORT_4    13                                          // if we open UART channel 4 we simulate using comx on the PC
   // #define SERIAL_PORT_5    9                                           // if we open UART channel 5 we simulate using comx on the PC
#if defined TWR_K70F120M
        #define DEMO_UART    2                                           // use UART 2
    #elif defined TWR_K20N50M                                            // {2}
        #define DEMO_UART    1                                           // use UART 1
    #elif defined KWIKSTIK || defined TWR_K60F120M
        #define DEMO_UART    5                                           // use UART 5
    #else
        #define DEMO_UART    3                                           // use UART 3
    #endif

in config.h:

#define SERIAL_INTERFACE                                                 // enable serial interface driver
#ifdef SERIAL_INTERFACE
    #define SERIAL_STATS                                                 // keep statistics about serial interface use
    #define SUPPORT_MSG_MODE                                             // enable terminator recognition (MSG_MODE)
    #define SUPPORT_MSG_CNT                                              // enable the message counter mode (MSG_MODE_RX_CNT) - requires also SUPPORT_MSG_MODE
    #define WAKE_BLOCKED_TX                                              // allow a blocked transmitter to continue after an interrupt event
      //#define WAKE_BLOCKED_TX_BUFFER_LEVEL                             

I don't get it ! you now what i am doing wrong, i tryet to follow the link you send

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #11 on: February 20, 2013, 12:23:20 PM »
Hi

Assuming that you are using the TWR_K70F120M, this has its debug output on UART 2.

If you want UART2 to be mapped to COM3 on the PC you need

#define SERIAL_PORT_2    3

You can set other SERIAL_PORT_X values to 0 so that they are disabled.

Regards

Mark
« Last Edit: December 06, 2017, 04:09:19 AM by mark »

Offline Geoff

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: User Documentation Source Code
« Reply #12 on: December 06, 2017, 02:44:54 AM »
Sorry Mark to dredge up an old thread, but I'm trying to get the demo UART working in simulation.  Should your instruction above about mapping UART2 not actually be referring to SERIAL_PORT_2 rather than SERIAL_PORT_3

ie, is this correct for mapping UART2 to COM3 on the PC ?
Code: [Select]
#define SERIAL_PORT_2    3
and a related question about the DEMO_UART - is the number referring to the UART channel on the device, and hence is the correct way to define use of UART channel 0 (ie UART0) as follows
Code: [Select]
#define DEMO_UART 0

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: User Documentation Source Code
« Reply #13 on: December 06, 2017, 04:16:42 AM »
Geoff

Yes, there was a type (I edited it now).

To select the UART used as command line interface and general debug message output you select it with DEMO_UART.
This counts the same as the UARTs on the Kinetis.
#define DEMO_UART 0 is thus for UART0.

To connect UART0 to a COM port on the PC you can then use (assuming COM9)
#define SERIAL_PORT_0    9

If you want a virtual loop back (to a terminal emulator) you can use com0com to install some loop-backs. If you configure a loop-back between COM 9 and COM 10 you can open the terminal emulator on COM 10 (before you start the simulator) and then let the simulator run (check the status bar when it runs where it shows with UARTs have been opened and which virtual COM port connections that are using to be sure).

After changing the #define SERIAL_PORT_0  setting do a rebuild since otherwise VS doesn't always build the C++ file using the define and so it doesn't take. With the rebuild it is always good afterwards.

Regards

Mark