Hello. We are having a problem reading the data sent from our ESP32 to a Bela Mini. The Arduino code is simply sending sensor values to the serial port.
We know that the two devices are communicating correctly, using linux screen commands in the terminal.
But we are having issues with the read() function that is supposed to give us the values from our ESP32. It gives us a segmentation fault error.
alt text

The read() function comes from the unistd.h library and has the following documentation:
http://pubs.opengroup.org/onlinepubs/000095399/functions/read.html?fbclid=IwAR2rQ6R9qzpf89tBXctlyOH6PT6YgyVv4X-jwUn9aW8jCGFBH8VN5Mmw6wQ

#include <Bela.h>
// C library headers
#include <stdio.h>
#include <string.h>
#include <iostream>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()

int serial_port = open("/dev/ttyUSB0", O_RDWR);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
void readTouchData(void*);
AuxiliaryTask touch;


bool setup(BelaContext *context, void *userData)
{
	struct termios tty;
	memset(&tty, 0, sizeof (tty));
	int serial_port = open("/dev/ttyUSB0", O_RDWR);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
    if(serial_port == -1)						/* Error Checking */
        printf("\n  Error! in Opening ttyUSB0  ");
    else
        printf("\n  ttyUSB0 Opened Successfully ");
        
  	// Set in/out baud rate to be 115200
        cfsetispeed(&tty, B115200); //in
	cfsetospeed(&tty, B115200); //out
	
	touch = Bela_createAuxiliaryTask(readTouchData, 50, "auxxTask");
}


void render(BelaContext *context, void *userData)
{
	Bela_scheduleAuxiliaryTask(touch);
}


void readTouchData(void*){
	rt_printf("HELLO");
	// Allocate memory for read buffer, set size according to your needs
	char read_buf [256];
	memset(&read_buf, '\0', sizeof(read_buf));

	// Read bytes. The behaviour of read() (e.g. does it block?,
	// how long does it block for?) depends on the configuration
	// settings above, specifically VMIN and VTIME
	int num_bytes = read(serial_port, &read_buf, sizeof(read_buf));

	// n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error.
	if (num_bytes < 0) {
	    rt_printf("Error reading: %s", strerror(errno));
	}
}


void cleanup(BelaContext *context, void *userData)
{

}

    ryjobil 1) Using rt_printf() from the AuxiliaryTask readTouchData() should be the c <stdlib.h> printf (Bela devs can confirm whether this is a problem). My hunch is this could be bad since I think rt_printf() is either using out-of-scope memory or best-case triggering a large number of Xenomai/Kernel switches.

    a) an AuxiliaryTask is still a Xenomai task
    b) It is fine to use rt_printf() from non-Xenomai context, though pointless, and you cannot use it to debug multi-thread applications, or segfaults, because the printing will not happen as soon as the command is executed, but at some later point when the printing thread runs.

      FYI here is some code to talk to a serial LCD which illustrates one method of signaling between render() and Aux task:
      https://github.com/transmogrifox/Bela_Misc/blob/master/audio_level_meter/render.cpp

      giuliomoro a) an AuxiliaryTask is still a Xenomai task

      Thanks for clearing my misunderstanding. Does code run from an AuxiliaryTask execute on DSP resources, but only as a lower priority task that does not block render()? If this is the case, then what code structure would need to be used for background operations done in Kernal mode?

      Sorry if I'm taking this off-topic, I can start another thread if this starts to pull off course.

      ryjobil 2) Function render() schedules Auxiliary Task on every RT processing cycle -- likely more frequently than the Aux task can complete.

      giuliomoro would you agree this is a potential cause for a segfault?

        ryjobil Thanks for clearing my misunderstanding. Does code run from an AuxiliaryTask execute on DSP resources,

        The code all executes on the CPU. There is not such a thing as dedicated "DSP resources".

        ryjobil , but only as a lower priority task that does not block render()?

        so it runs on the same "resources" (CPU) as the audio thread, but at a lower priority (as long as the priority you set is < BELA_AUDIO_PRIORITY).

        ryjobil If this is the case, then what code structure would need to be used for background operations done in Kernal mode?

        A Xenomai task can switch between primary ("Xenomai") and secondary ("Linux") mode as needed. This is mostly fine for most applications, though if sometimes you just want to use just a regular thread, just create one withpthread.

        ryjobil would you agree this is a potential cause for a segfault?

        no, again scheduling it while it's already running should be a no-op, so no reason for segfault, afaik.

        An issue I see with the code is:

        > int serial_port = open("/dev/ttyUSB0", O_RDWR);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter   */

        Is this really supposed to work? Move the call to open() to setup(). Currently you are opening it in both places, but the serial_port variable used by readTouchData() is the global one, no the one you open in setup().
        To test if the reading work, just try to read() (maybe in a loop?) from within setup(), just after you cfsetospeed().

        Also, that setup() function should be returning true at the end, don't you get a compiler warning?

        arandomaccount Hello. We are having a problem reading the data sent from our ESP32 to a Bela Mini. The Arduino code is simply sending sensor values to the serial port.

        As for serial, check out this file here. Don't get distracted by the actual data I am sending; the stuff to do serial is all in there. Also, check out the comments in this other thread.