skip to Main Content

Stack Overflow,

I desperately need help getting a BeagleBone Black UART to work from a C program.
The code that I am attempting to use is listed below. The code came from Chapter 8 of Derek Molloy’s “Beaglebone” book.

The code compiles without any warnings or errors and seems to run. The program passes the sanity checks that are built into the C code below. The program finishes by printing “Finished sending the message, exiting.” to the console.

The fundamental reason that I think the UART4 is not sending data is that I see no activity on P9/13 when monitoring with a nice digital O’scope. I have also tried monitoring the port by way of a PC running a terminal program.

I am convinced the C-program is reading my command-line message (e.g. “testing123”) correctly. I modified to code to print the message to the console and it printed the message as expected. I also modified the code run in a loop to make it easier to monitor P9/13 with the O’scope. The O’scope shows a constant 3.3VDC on the P9/13.

I also blindly tried a pull-down resistor. The port does not provide much current. A 2k Ohm resistor loaded the port to about 0.2 Volts.

I verified that ttyO4 and ttyS4 are in /DEV, whatever that means.

I am not certain what version of Debian that I am using. I monitored the “header” output from J1 and found this:
Debian GNU/Linux 9 ebb ttyS0
BeagleBoard.org Debian Image 2019-08-03

Also, I found this:
Machine ID: 229f313330aab6c19873bdc15d4645c7
Boot ID: b74381516ae64aefa37415709164f0e4
Operating System: Debian GNU/Linux 9 (stretch)
Kernel: Linux 4.14.108-ti-r113
Architecture: arm

Do I need to enable the UART port or pins? If so, how do I do this and how do I confirm it was successfully done? Do I need to hardwire the control lines (e.g. CTS, RTS)? Do I need to edit the uEnv.txt file?

I am almost certain my board is a rev-c.

As a final note, I tried a similar C-code from the “Bad to the Bone” book with similar unfavorable results.

Any help will be greatly appreciated.

Thanks,

Norm

/* Simple send message example for communicating with the
*  UART that is connected to a desktop PC.  */

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#incl`ude<string.h>

int main(int argc, char *argv[]){
   int file, count;
   if(argc!=2){
       printf("Please pass a message string to send, exiting!n");
       return -2;
   }
   if ((file = open("/dev/ttyO4", O_RDWR | O_NOCTTY | O_NDELAY))<0){
      perror("UART: Failed to open the device.n");
      return -1;
   }
   struct termios options;
   tcgetattr(file, &options);
   options.c_cflag = B115200 | CS8 | CREAD | CLOCAL;
   options.c_iflag = IGNPAR | ICRNL;
   tcflush(file, TCIFLUSH);
   tcsetattr(file, TCSANOW, &options);

   // send the string plus the null character
   if ((count = write(file, argv[1], strlen(argv[1])+1))<0){
      perror("UART: Failed to write to the output.n");
      return -1;
   }
   close(file);
   printf("Finished sending the message, exiting.n");
   return 0;

2

Answers


  1. Depending on your image and kernel…

    1. Try /dev/ttyS4
    2. Or try /dev/bone/uart/4

    Also…I am pretty sure config-pin was available in kernel 4.14.x even though that kernel is EOL from their org.

    If you come across /dev/ttyS4 not working, try config-pin for your specific pins used…

    Login or Signup to reply.
  2.  ////////////////////////////////////////
     // blinkLED.c
     // Blinks the P9_14 pin based on the P9_18 pin
     // Wiring:
     // Setup:
     // See:
     ////////////////////////////////////////
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #define MAXSTR 100
    
    int main() {
      FILE *fpbutton, *fpLED;
      char LED[] = "50";   // Look up P9.14 using gpioinfo | grep -e chip -e P9.14
      char button[] = "7"; // Look up P9.42 using gpioinfo | grep -e chip -e P9.18
      char GPIOPATH[] = "/sys/class/gpio";
      char path[MAXSTR] = "";
    
      // Make sure LED is exported
      snprintf(path, MAXSTR, "%s%s%s", GPIOPATH, "/gpio", LED);
      if (!access(path, F_OK) == 0) {
        snprintf(path, MAXSTR, "%s%s", GPIOPATH, "/export");
        fpLED = fopen(path, "w");
        fprintf(fpLED, "%s", LED);
        fclose(fpLED);
      }
     
      // Make it an output LED
      snprintf(path, MAXSTR, "%s%s%s%s", GPIOPATH, "/gpio", LED, "/direction");
      fpLED = fopen(path, "w");
      fprintf(fpLED, "out");
      fclose(fpLED);
    
      // Make sure bbuttonutton is exported
      snprintf(path, MAXSTR, "%s%s%s", GPIOPATH, "/gpio", button);
      if (!access(path, F_OK) == 0) {
        snprintf(path, MAXSTR, "%s%s", GPIOPATH, "/export");
        fpbutton = fopen(path, "w");
        fprintf(fpbutton, "%s", button);
        fclose(fpbutton);
      }
     
      // Make it an input button
      snprintf(path, MAXSTR, "%s%s%s%s", GPIOPATH, "/gpio", button, "/direction");
      fpbutton = fopen(path, "w");
      fprintf(fpbutton, "in");
      fclose(fpbutton);
    
      // I don't know why I can open the LED outside the loop and use fseek before
      //  each read, but I can't do the same for the button.  It appears it needs
      //  to be opened every time.
      snprintf(path, MAXSTR, "%s%s%s%s", GPIOPATH, "/gpio", LED,    "/value");
      fpLED    = fopen(path, "w");
      
      char state = '0';
    
      while (1) {
        snprintf(path, MAXSTR, "%s%s%s%s", GPIOPATH, "/gpio", button, "/value");
        fpbutton = fopen(path, "r");
        fseek(fpLED, 0L, SEEK_SET);
        fscanf(fpbutton, "%c", &state);
        printf("state: %cn", state);
        fprintf(fpLED, "%c", state);
        fclose(fpbutton);
        usleep(250000);   // sleep time in microseconds
      }
    }
    

    This is older source that may or may not work depending on your kernel/image and date in time of said kernel.

    Also…

    line 15 and line 16 show gpioinfo as a command. On the BBB, one can find many pins that are available and in what format which is usually default.

    Calling config-pin during the source may help or you can have it preset w/ a .dtbo file in /boot/uEnv.txt. Overlays are, was, and still are a thing w/ the am335x on the BBB.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search