RingBufferUint8 component together with Serial_LDD, and simply use the high level component called AsynchroSerial

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RingBufferUint8 component together with Serial_LDD, and simply use the high level component called AsynchroSerial

Jump to solution
2,015 Views
om
Contributor III

Hello

I looked at Erich blog, at the http://mcuoneclipse.com/2012/10/14/tutorial-printf-and-hello-world-with-the-freedom-kl25z-board/

The blog is very useful, and Erich efforts are not taken as granted.

Thanks a lot for doing all this stuff, for all of us.

(I wanted to reply there, but I don't know how)

A sort question:

Uarts 3,4,5 of K60 don't have buffers, so there is a risk to loose data.

What is the difference between using the new RingBufferUint8 component together with Serial_LDD, and simply use the high level component called AsynchroSerial (That has option to configure Input and Output buffer size) ?

BTW: till today I didn’t understand what to use. The LDD components or the high level components ?  and why this or the other.

(I don’t have OS)

Thanks a lot

  OM

1 Solution
700 Views
BlackNight
NXP Employee
NXP Employee

Hi OM,

>>"(I wanted to reply there, but I don't know how)"

at the bottom of each article there is a box where you can enter questions or comments.

About LDD or non-LDD, you might have a look at There is a Time and Date for both Worlds | MCU on Eclipse

In a nutshell:

  • non-LDD is what has been used before the advent of Kinetis/ColdFire+. So if you want to use a simpler interface of want to keep your applications compatible between different architectures (S08, S12, ColdFire,Kinetis, ...), then use the non-LDD version. Because my software needs to run on many different platforms, and I prefer the 'simpler is better' approach, I prefer to use the non-LDD drivers whenever possible.
  • LDD drivers are more designed to work with an environment where you need to pass back and forward device handles (e.g. with MQX). As such, they have an additional device handle in the interface which you need to care of. The good thing with this is that it is very generic. The downside is an additional parameter which mostly is not used in an non-RTOS environment. On one hand the argument is that the device handle makes things better with an RTOS, on the other hand the non-LDD drivers can be easily used with an RTOS (or any RTOS) too. You just need to have the proper protection in place for drivers if they are used by multiple tasks.

The good thing is that with MCU10.3 many of the LDD drivers have now non-LDD wrappers for it: that does not remove the (internal) overhead, but makes it at least usable beyond Kinetis/ColdFire+. The other thing is (as you noted) the LDD versions might not come with things like buffering (the non-LDD has Rx/Tx buffers, as you noticed). I invented the RingBuffer component at the time when there was just the LDD version for Kinetis, and such a ring buffer was required.

I recommend that you use the non-LDD (high level) components for above reasons. And then you do not need that ring buffer at least for AsynchroSerial, as it has such a ring buffer implemented in the driver.

At the end: different API's have their pros and cons. Choose what fits you best (or create your own one ;-))

I hope this helps.

View solution in original post

6 Replies
700 Views
Petr_H
NXP Employee
NXP Employee

Hi,

I woould just add that on Kinetis MCUs there is recommended to use the LDD component which are newer generation of component that should replace the legacy "high level components" like AsynchroSerial.

If you'd like to use buffering, the Serial_LDD allows to use your own string buffers. Here is a "from scratch" example that processes input by blocks of 10 characters, with interrupts enabled (otherwise you would have to call AS1_Main method of the component in your loop) :

Content in ProcessorExpert.c:

bool DataReceivedFlg = FALSE;

char OutData[] = "Hello!";

char SerialBuf[10];

char Received[10];

LDD_TError Error;

void main(void)

{

  . . .

  /* Start reception of a given number of characters (in this case 10),  passing pointer to the buffer */

  Error = AS1_ReceiveBlock(AS1_DeviceData, SerialBuf, 10);          

  for(;;) {

    if (DataReceivedFlg) {

        /* Do something with the data in Received string here. It only must take shorther than receiving other 10 characters.... */

        /* clear flag */

        DataReceivedFlg = FALSE;

        /* you can for example reply something back */

        Error = AS1_SendBlock(AS1_DeviceData, OutData, sizeof(OutData));

    }

    ...

  }

}

Content of Events.c:

extern volatile bool DataReceivedFlg;

void AS1_OnBlockReceived(LDD_TUserData *UserDataPtr)

{

  /* just move received data for main loop processing */

   memcpy(Received, SerialBuf, sizeof(Received));

  /* Set DataReceivedFlg flag */

  DataReceivedFlg = TRUE;

  /* Start reception again */

  Error = AS1_ReceiveBlock(AS1_DeviceData, SerialBuf, 10);

}

You can see some  simple examples on the Typical usage page from from the Serial_LDD component help (you can invoke it using "Help on component" pop-up menu command):

To use the printf, there is necessary to add ConsoleIO component to the project which automaticalle (which uses an inherited Serial_LDD) as erich described in his nice tutorial ( Tutorial: Printf() with (and without) Processor Expert | MCU on Eclipse ).

best regards

Petr Hradsky

Processor Expert Support Team

700 Views
bondansuwandi
Contributor I

Hi Petr,

I have question regarding to the serial_LDD example in "Help on component: pop -up menu". I tried this example with MQX-lite and I got some error due to Link Failed between "extern volatile bool DataReceiveFlg;" in the event.c and "volatile bool DataReceiveFlg = FALSE;" in the mqx_tasks.c. when I removed the "extern", the error solved, but I am not sure both DataReceiveFlg are linked or not.

Do you have any solution for this error?

Thanks,

Bondan

serial.jpg

0 Kudos
701 Views
BlackNight
NXP Employee
NXP Employee

Hi OM,

>>"(I wanted to reply there, but I don't know how)"

at the bottom of each article there is a box where you can enter questions or comments.

About LDD or non-LDD, you might have a look at There is a Time and Date for both Worlds | MCU on Eclipse

In a nutshell:

  • non-LDD is what has been used before the advent of Kinetis/ColdFire+. So if you want to use a simpler interface of want to keep your applications compatible between different architectures (S08, S12, ColdFire,Kinetis, ...), then use the non-LDD version. Because my software needs to run on many different platforms, and I prefer the 'simpler is better' approach, I prefer to use the non-LDD drivers whenever possible.
  • LDD drivers are more designed to work with an environment where you need to pass back and forward device handles (e.g. with MQX). As such, they have an additional device handle in the interface which you need to care of. The good thing with this is that it is very generic. The downside is an additional parameter which mostly is not used in an non-RTOS environment. On one hand the argument is that the device handle makes things better with an RTOS, on the other hand the non-LDD drivers can be easily used with an RTOS (or any RTOS) too. You just need to have the proper protection in place for drivers if they are used by multiple tasks.

The good thing is that with MCU10.3 many of the LDD drivers have now non-LDD wrappers for it: that does not remove the (internal) overhead, but makes it at least usable beyond Kinetis/ColdFire+. The other thing is (as you noted) the LDD versions might not come with things like buffering (the non-LDD has Rx/Tx buffers, as you noticed). I invented the RingBuffer component at the time when there was just the LDD version for Kinetis, and such a ring buffer was required.

I recommend that you use the non-LDD (high level) components for above reasons. And then you do not need that ring buffer at least for AsynchroSerial, as it has such a ring buffer implemented in the driver.

At the end: different API's have their pros and cons. Choose what fits you best (or create your own one ;-))

I hope this helps.

700 Views
om
Contributor III

Hi

The project with the hi-level AsynchroSerial is working with AS2_SendBlock and AS2_RecvBlock (is this the right way to work with the driver ???) but I can't find why the printf isn't printing to the UART.

I included stdio.h, I saw that printf goes to printftiny (inside) but nothing on the terminal :-(

Help, please :-(

Thanks a lot

  OM

0 Kudos
700 Views
BlackNight
NXP Employee
NXP Employee

Hi OM,

Well, printf() is not something to get start with, as printf() is probably one of the most complicated things for embedded :-( .

Yes, SendBlock() and ReceiveBlock() is what you can use.

Have a look here how printf() is working: Tutorial: Printf() with (and without) Processor Expert | MCU on Eclipse

If you can avoid using printf(), then you will be in a better shape.

If you need a command line interface or to print out things on a terminal, you might be better served with something like the 'Shell' component I use. That shell is using the AsynchroSerial component too.

An example project is here: mcuoneclipse/Examples/FRDM-KL25Z/Freedom_Shell at master · GitHub

I hope this helps.

700 Views
om
Contributor III

Hi Erich

Thanks for the fast response.

I just need two uarts, in the final project, but my boss asked me to show to him CLI (Command line interface) till tomorrow morning and I sit here without success :-(

The CLI is just for testing stuff.

I saw already example from freescale called I2C (with console interface), and it run here OK

do you recommend to use shell instead ?

I just thought to redirect the printouts to one of the COM PORTS, so the driver will stay AsynchroSerial (cause I don't know how to disable it, without completely delete it) and add printing functionality.

With ReceiveBlock() I need to sit in a loop and read the commands ?

0 Kudos