This page describes how the serial drivers work and how to access them.
Introduction
The Serial communication can be both synchronous or asynchronous.
Here you can see how it works (unidirectional case):
stdio.h
(printf(), scanf(), ...)
Using When you use functions like printf(), scanf(), puts(), gets() etc... inside your code, Miosix redirects them to one of the microcontroller's serial ports, called the default serial port. This is defined in miosix/config/arch/<your_arch>/<your_board>/board_settings.h
, along with the default baudrate and other related configurations. The file looks like this:
const unsigned int defaultSerial=1; //default serial = USART1
const unsigned int defaultSerialSpeed=115200; //baudrate
const bool defaultSerialFlowctrl=false; //use rts/cts
#define SERIAL_1_DMA //use the DMA
WARNING: printf() is very heavy and can significantly modify the timings if used inside drivers. For this reason, we suggest instead the use of TRACE() throughout the code. TRACE() works as a normal printf() if DEBUG is defined (see below example), otherwise it does not perform any operation.
You can find an example in the Hello Skyward tutorial page.
fnctl.h
(other serial ports)
Using A part from the default serial port, Miosix offers access to up to 3 USARTs in STM32 microcontrollers. In arch/common/drivers/serial_stm32.cpp
you can find the 3 USARTs enabled by default. Here is the pinout:
USART | TX | RX | CTS | RTS | STM32F429ZI | STM32F407VG |
---|---|---|---|---|---|---|
1 | PA9 | PA10 | PA11 | PA12 | default | |
2 | PA2 | PA3 | PA0 | PA1 | ||
3 | PB10 | PB11 | PB13 | PB14 | default |
Miosix gives the possibility to access these USART ports through Unix-like device files. In particular, to access a particular USART of your microcontroller (e.g. USART2) you should modify the bspInit2() method inside the Board Support Package as follows:
void bspInit2()
{
#ifdef WITH_FILESYSTEM
/**
* Pointer to file system.
*/
intrusive_ref_ptr<DevFs> devFs = basicFilesystemSetup(SDIODriver::instance())
/**
* Open serial port, accessible as '/dev/gps', on USART2 with baudrate 115200.
*/
devFs->addDevice("gps", intrusive_ref_ptr<Device>(new STM32Serial(2,115200)));
#endif //WITH_FILESYSTEM
}
After that, you can easily use the device as follows:
#include <fcntl.h>
//...
int fd=open("/dev/gps",O_RDWR); //open serial port named gps
if(fd<0) printf("Cannot open /dev/auxtty");
char buffer[11]; //Buffer is 10 chars + '\0'
read(fd, buffer, 10); //Read 10 chars
write(fd, buffer, 10); //Write 10 chars
Pay attention to the baudrate at which the used port is set!
Reading/Writing from a PC
To communicate with a board from your PC you will need a USB-TTL driver, or you can do it via the Discovery's USB cable if the feature is enabled in your Discovery board.
Once your USB-TTL dongle is attached to the PC, you will need to connect the RX and TX of the dongle to the TX and RX of the decided serial port in your Discovery (ATTENTION: RX discovery<-->TX usb dongle and vice-versa).
Then you can open a communication using:
- Putty in Windows: Select the Session tab on the left panel and select Serial as "Connection type". You will need to know the COM port to which the Discovery is attached (you can find it out in Control Pane > Device Manager).
-
GTKTerm on Linux: Configuration > Port >
/dev/ttyUSB0
and select baudrate (115200 for the default serial). You can also usescreen
orminicom
.
In both cases, you will need to set the correct port and baudrate, and you may need install some drivers for the USB dongle to make things work.
Auxtty USART (STM32F407VG only)
For the STM32F407VG board, there's also another serial port, called auxtty
: you need to remove the comment from the board_settings.h
in order to use it:
//#define AUX_SERIAL "auxtty" UNCOMMENT THIS TO OPEN THE SERIAL
const unsigned int auxSerialSpeed=9600;
const bool auxSerialFlowctrl=false;
USART driver
The driver for the USART peripheral permits to use all the USART/UART peripherals of any board, setting the wanted baudrate. All the pins linked to the various USART/UART peripherals are defined in the USART.h header file in the format of uNtxM or uNrxM (N = id of the peripheral; M = [absent, 1 or 2] in order to distinguish among different pins with same function; e.g. u1tx1, u1rx1, u5tx, u5rx). An example of usage is in /src/tests/drivers/usart/test-usart.cpp
. The USART header and cpp files can be found at /src/shared/drivers/usart
.
USARTInterface
This class is the abstract class that represents a USART peripheral. It has some abstract methods in order to expose some common features:
-
init
: initializes the peripheral -
read
: reads in a buffer at most a specified number of bytes -
write
: a blocking write method on the peripheral, to send binary data -
writeString
: a blocking write method for strings, that sends also the final '\0' character -
initPins
: initializes the pins with the appropriate alternate functions
USART
This is a low level implementation of the USART driver. It supports all the USART/UART peripherals (from 1 to 8), there are low level parameters that can be configured (word length, parity bits, stop bits, oversampling. Also, this driver could be extended in order to implement more features of the peripheral. Some notable methods of this driver are:
-
IRQhandleInterrupt
: used to handle the read, fills up the queue while theread
method empties it; - Constructors: There are two constructors, one will initialize the peripheral with custom pins and the other will initialize automatically the peripheral with the default pins. Moreover, it will enable the peripheral clock, set the baudrate register and the other parameters with the default values. As parameter we can pass also the size of the queue, with the default being usart_queue_default_capacity = 256.
-
init
: initializes the peripheral enabling his interrupts, enabling the interrupts in the NVIC and setting the pins with the appropriate alternate functions. All the setup phase must be done before the initialization of the peripheral. The pins must be initialized before calling this function. - Destructor: Disables the flags for the generation of the interrupts, disables the IRQ from the NVIC, disables the peripheral and removes his pointer from the ports list.
STM32SerialWrapper
This is a wrapper of the miosix driver STM32Serial. It supports only the USART 1, 2 and 3. For reading long messages with low baudrates it's needed to wait some milliseconds between the sending and the receiving of the message. Some notable methods of this driver are:
- Constructors: There are two constructors, one will initialize the peripheral with custom pins and the other will initialize automatically the peripheral with the default pins.
-
init
: Creates a device that represents the serial port, adds it to the file system and opens the file that represents the device. - Destructor: Removes the device from the list of the devices and closes the file of the device.