µTasker Forum > µTasker general
User Documentation Source Code
mark:
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: ---#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)
...
};
--- End code ---
6 Second Example – The Task being configured by another
--- Code: ---{ “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
--- End code ---
7. Third Example – Adding a Queue to Your Task and getting it to do a bit more Work
--- Code: ---{ "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 );
}
}
}
}
--- End code ---
*****************************************************************************
mark:
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
internship2:
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 ?
mark:
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
internship2:
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 :(
Navigation
[0] Message Index
[#] Next page
Go to full version