This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Best way to redirect Serial I/O?

I have got 3x buffered serial ports working fine, Uart0, Uart1, Bitbanged Uart3. I can transfer chars between them in any order so they are fine.

They are named
Sin0, Sout0, Sin1, Sout1, Sin3, Sout3.

In one example file it said that if the user provides putchar and getchar, the higher level functions such as printf will use the user's version. I take it that this means that if the library detects something is already defined then the library version will not get compiled - is this correct?

I ask because I want to be able to use the higher level I/O functions on any of my 3x I/O ports. From the help file I suspect _getkey,sscanf,puts, ungetchar,gets,scanf,vpritf,printf,sprintf,vsprintf all operate via getchar and putchar - is this so?

So I am thinking that either to use #if.. #endif somehow, or to write a version of putchar and getchar that run the required comport routines.

something like
Commout=Sout2, (stores a pointer of run address of Sout2)
Commin=Sin2 (same)

So Putchar runs the function Sout2 and Getchar runs Sin2, until a redirection selects a different I/O port.

I can kind of work this out in assembler, but I am not that sure about how to do it in C.

I would really appreciate a "best approach" suggestion. I am probably asking a simple question, but right now I just dont have a handle on how to do it..

Parents
  • "In one example file it said that if the user provides putchar and getchar, the higher level functions such as printf will use the user's version. I take it that this means that if the library detects something is already defined then the library version will not get compiled - is this correct?"

    Not quite.
    The Libraries are already compiled; it is the Linker that looks in the Library for any symbols that are left undefined after linking all your code.
    Thus, if a definition for getchar is found in your code, it is used - if it isn't, the definition from the library is used.

Reply
  • "In one example file it said that if the user provides putchar and getchar, the higher level functions such as printf will use the user's version. I take it that this means that if the library detects something is already defined then the library version will not get compiled - is this correct?"

    Not quite.
    The Libraries are already compiled; it is the Linker that looks in the Library for any symbols that are left undefined after linking all your code.
    Thus, if a definition for getchar is found in your code, it is used - if it isn't, the definition from the library is used.

Children
  • Thanks since posting I have been "playing". The switch statement seemed an obvious choice. This works fine. I understand the linker-library relationship now. Is this a good solution or is there a better way? I have not yet investigated the hint about function pointers.

    I had to use a none standard _getkey() to get around the _getkey and getchar waiting for input. I am not sure how I can use the regular _getkey definition with resorting to an RTOS.

    Quite pleased with myself really, I am way down on the C learning curve, 2 weeks of using C and the ARM. But at least catching on. Any critism/help is appreciated. Thanks!

    /*-----------------------------------------------------
    _getkey normally waits until a character is received.  This version checks serial port and returns immediately with char or 0 if no char available
    -----------------------------------------------------*/
    int getkey0 (void)  {
    int k;  // Read character from Serial Port
      k = com_0_getchar ();
      if (k != -1) return ((unsigned char)k);
      else return (0x00);
    }
    //-----------------------------------------------------
    int getkey1 (void)  {
    // similar code
    }
    //-----------------------------------------------------
    // Putchar and _getkey use the commport selected
    //-----------------------------------------------------
    int putchar(int c)
    {
            switch (comm)
            {
                    case 0: com_0_putchar(c); break;
                    case 1: com_1_putchar(c); break;
                    default: break;
            }       return(c);
    }
    
    int _getkey(void)  {
    int c;
            switch (comm)
            {       case 0: c=getkey0(); break;
                    case 1: c=getkey1(); break;
                    default: break;
            }   return (c);
    }
    //-----------------------------------------------------
    void main (void)
    {
    com_1_initialize (); // interrupt driven serial I/O
    com_1_baudrate (9600); // @15mh/z
    com_0_initialize (); // interrupt driven serial I/O
    com_0_baudrate (9600); // @15mh/z
    
    comm=0;
    printf ("Comm%u Serial I/O\r\n\r\n",comm);
    comm=1;
    printf ("Comm%u Serial I/O\r\n\r\n",comm);
    
    while (1)
      {
    unsigned char c;
    int i;
      while (1) { // endless loop
            comm=1;
            c=_getkey(); // get a char from Uart1
            if (c!=0) putchar(c); // if a char send to Uart1
            comm=0;
            c=_getkey(); // get a char from Uart0
            if (c!=0) putchar(c); // if a char send to Uart0
    
            for (i=0; i<100000; i++) {}  // waste time
      }
      }
    }