I am trying to write a program that will be installed on a Linux MCU (Raspberry Pi) that will read serial data coming to it from yet another MCU (something homegrown that I will
Have you find Linux documentation of SPI ?
There are couple good documents: spi-summary and spidev.
There is also example in file spidev_fdx.c, where read()
is used for SPI device.
But usually reading from SPI is handled by ioctl()
function.
On Unix everything is a file
If the spi_bcm2708
driver installed correctly there should be a /dev/whatever
file for the device ( or several for accessing the device in different ways).
If one wasn't created automatically you can make an entry with mknod
User space code simply has to open the /dev/whatever
file as if it was any other regular file and read/write data from it. That's the whole point of Unix.
edit: that's exactly what the code in the linked question is doing, it's opening the terminal /dev/ttyS0
as a file with open() and reading/writing to it.
I am trying to write a program that will be installed on a Linux MCU (Raspberry Pi) that will read serial data coming to it from yet another MCU (something homegrown that I will build myself).
[MCU is not the proper term to use. The Raspberry Pi uses a SoC (System on a Chip). A microcontroller would be a cheaper & simpler device than a SoC. If you want to use a TLA, then use SBC, single board computer.]
[You are misusing the terms "serial port" and "serial data". Today, because of the ubiquity of PCs, "serial port" has come to exclusively refer to EIA/RS-232 asynchronous serial connections. SPI. USB. I2C, TWI, SATA et cetera should not be referred to as "serial" connections unless you are explaining how they work.]
In Linux the SPI device driver is often implemented as a *platform driver" rather than a character driver. Therefore such a driver would not have file operations, or fops, to perform open(), read(), write() or close(). Such operation are for target devices, which the platform device connects to the system. As a consequence, platform devices do not have device nodes in /dev
like target devices do. SPI is in the same category as USB and PCI; they are all buses and typically implemented as platform drivers.
My understanding was that I could use SPI to read data from the connected MCU device, and that I would not need to write my own device driver for that device. Is this true?
The answer depends on whether the kernel you use has a SPI char device exposed for your user program to use. But if the SPI driver is a platform driver, then a device driver for your custom SBC would have to be implemented. This target device would need a node in /dev
, major and minor numbers assigned and a driver associated with those numbers. This driver would utilize the platform operations that the SPI driver provides or use the Linux SPI API to perform the transfers. The SPI and its driver are merely conduits for transferring data between this processor and the target device. LIke SATA and PCI, the user is rarely aware of these (internal) buses that connect peripheral devices to the computer.
linux/drivers/spi/spi_bcm2708.c
is a platform driver. It has no fops to support/perform open(), read(), write() or close() operations. It registers itself as a SPI master, so other (target) drivers can use the SPI API for its services.
IMO you would be better off implementing an EIA/RS-232 link between the RPI and your custom SBC. If non-canonical (raw) transfers were used, then probably 99% of the code you write will be reusable if/when you convert/upgrade to a SPI connection. A 3-wire serial connection with no flow control is similar to a SPI connection, but with no master/slave hierarchy imposed, a simpler HW interface, and longer possible cable lengths.
Beware that you may not be able to achieve fast transmission rates with long SPI distances using whatever cable you rig up. The 10s of Mbps rates for SPI are typically achieved on multilayer boards with ground planes and short traces.