Source code for Serial (class?)

I’m probably being rather slow, but is there somewhere I can download the source code for the higher level thingies that are described in “Core code (firmware)” section of the documents. I thought this might be in the core-common-lib download from the open source section of the site, but this all looks to be much lower level.

I only ask because I am trying to port some code I wrote some time ago for an mbed board. When wading through the masses of compiler errors the one thing it doesn’t complain about is references to Serial as if it were a class or a structure. For example the following constructor seems to compile without error:

SerialPacketTransmitter( Serial *p ) :
port( p )
{
}

This is odd because I am not defining Serial and I thought the definition for Serial provided in the Spark libraries was an instance of a class, not a class itself, but if the above compiles then it seems to be treating Serial as if it were a class. It would be really helpful if I could look at the source code and find out exactly what kind of a beast a Serial is.

You looked at the right place, but the wrong house :wink:

https://github.com/spark/firmware

This is where you’ll find spark_wiring_usartserial.h & .cpp for Serial1 and spark_wiring_usbserial.h & .cpp for Serial.

The last statements in the respective cpp’s do instanciate the objects Serial and Serial1 of class USBSerial respectively USARTSerial.

@ScruffR has pointed you to the right spot. Looking at the code, the USBSerial class is extern’ed as “Serial” and the cpp instantiates a USBSerial object called Serial. So it is both a type and an instance. (It’s floor wax and a dessert topping–it’s two products in one!)

The type you wanted in your class is likely to be “Stream” so it can point to any of the serial port objects.

1 Like

No. My mistake. On closer inspection of the compiler error messages there is an error “‘Serial’ does not name a type”, so there really is no definition of the Serial class. Looks like I will have to use either USBSerial or USARTSerial to represent a serial port. Given they have so much in common I am surprised they don’t derive from a common base class which would make my job much easier.
Anyway, thanks for the help.

As @bko mentioned you may use Stream as base class.

1 Like

Yes, you can, but then you cannot use all the methods defined in USBSerial and USARTSerial (other than the ones inherited from Stream). My point is that the same (or similar) methods are declared in both USBSerial and USARTSerial and if these were declared in a common abstract base class (say SerialPort) that inherits from Stream then you could just pass around a SerialPort and use these methods without knowing whether you are using a USBSerial or a USARTSerial. As it is, if I pass around a Stream then I am limited to using the methods declared by Stream.

Stream inherits from Print and so you have all the print methods too. This is how it is was designed to work. You are supposed to use Stream so that you can pass a Serial (of any flavor) or an Ethernet (on an Arduino) or TCPClient or TCPServer or a Wire (i2c) or an SD.

Maybe you should give us an example of a public Serial method you want to call that you can’t and we will find a way to make it work. Everything in the public interface is available to you.

2 Likes

I see. I didn’t realise Stream has so many high level functions. In other languages I am used to Stream working at a fairly low level, in a byte by byte manner and not having the ability to write out integers as formatted text (for example). Looking at the Stream class I see it can do quite a lot, as well as inheriting all the methods of Print.
However, there are still some minor problems. If I pass a Stream around I won’t have access to the “begin” method because it is not declared as virtual, and as far as I can tell it is not defined in Stream. Even if it is, if you call it like this:

void someFunc( Stream *s ) {
s->begin( 38400 );

}

it will call the Stream class’s version of begin, not the version declared in USARTSerial or USBSerial. So this means you cannot write a function that takes any kind of serial port and sets the baud rate. Admittedly you can set the baud rate before you call the function, like this:

Serial.begin( 38400 );
SomeFunc( &Serial );

but this still constitutes an incompatibility in that you cannot treat USARTSerial and USBSerial in exactly the same way. Never mind, it’s not a show stopper, I can work around it, and Stream is certainly a lot more powerful than I thought.

1 Like

Not every class that inherits from Stream (and Print) has a begin() method; some have connect() instead, for instance. They could have made a wider interface with more pure virtual methods but then Serial would have a connect() that did nothing and TCPClient would have a begin() that did nothing. I bet they thought that would confuse people, so they just made the data handling common, not the setup and tear down code. I agree it is not perfect, but it does make life a lot easier.

What I would suggest is a class called SerialPort derived from Stream. This would have begin as a pure virtual method and USARTSerial and USBSerial would derive from SerialPort. This means only serial ports have a begin method and wouldn’t have to implement methods like connect.

That’s nice, but it would not be Arduino compatible.