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

Printf only works with RTOS

Hi,

I have a working project for XC167 using RTX-166 Tiny.

However, when I remove the RTOS (see code change below), printf stops working. It now prints the first character and then stops. I have read that this could be an issue with user stack, would the RTOS have changed the configuration of this?
Memory model is HLarge.

I.e. code before:

#include <rtx166t.h>
#include "task.h"
#include <string.h>
#include <intrins.h>
#include <absacc.h>
#include <stdio.h>
#include <XC167.h>
#include "typedef.h"
#include "iodef.h"
#include "interrupts.h"

void task_init (void) _task_ TASK_INIT
{
        InitUART();

        for(;;)
        {
                printf("Hello!\n");
                _getkey();
        }

        os_delete_task (os_running_task_id ());
}

code after (with no RTOS selected in options):

//#include <rtx166t.h>
//#include "task.h"
#include <string.h>
#include <intrins.h>
#include <absacc.h>
#include <stdio.h>
#include <XC167.h>
#include "typedef.h"
#include "iodef.h"
#include "interrupts.h"

void main (void)
{
        InitUART();

        for(;;)
        {
                printf("Hello!\n");
                _getkey();
        }

//      os_delete_task (os_running_task_id ());
}


This second project just prings "H"

Any ideas?

Thanks.

Parents
  • Hello!

    Try to place explicitly the code for putchar into your C module (the putchar is being used by printf). Also, verify if InitUART is free of any OS-related code; check if putchar/_getkey-via-UART mechanism is supposed to be by means of polling or interrupt(s) - check if the UART's and global interrupts are enabled if needed.

    Besides it, _getkey may need to be explicitly placed into your C module as well. The function is used by getchar.

    A simplified example (note: this is XC2287M code), somewhere in main.c:

    #include <stdio.h>
    
    signed char putchar (signed char c)  { // used by printf
      while (!(U0C0_PSR & 0x2000));        //  wait until TBUF is empty
      U0C0_PSCR     |= 0x2000;             //  clear transmit buffer indication flag
      U0C0_TBUF00    = c;                  //  output character
      return (c);
    }
    
    int x_iskey(void) {
      if( (U0C0_PSR & 0x4000) == 0 ) return 0;
      return 1;
    }
    
    signed char x_getkey (void)  {         // synonymic function, _getkey replacement
      char c;                              // may also be just defined as _getkey
    
      while (!(U0C0_PSR & 0x4000));
      c = (char) U0C0_RBUF;
      U0C0_PSCR |= 0x4000;                 //  clear receive indication flag
      return (c);
    }
    
    

    Regard this like a small trick to bypass standard library code with your custom one.

    Look into getkey.c, putchar.c in you Keil's subfolder \c166\lib\.

    For details, you may want to check with http://www.keil.com/support/docs/2601.htm and links therein - e.g. http://www.keil.com/support/docs/2014.htm. There quite a few threads discussing printf via UART stuff.

    Regards,
    Nikolay.

Reply
  • Hello!

    Try to place explicitly the code for putchar into your C module (the putchar is being used by printf). Also, verify if InitUART is free of any OS-related code; check if putchar/_getkey-via-UART mechanism is supposed to be by means of polling or interrupt(s) - check if the UART's and global interrupts are enabled if needed.

    Besides it, _getkey may need to be explicitly placed into your C module as well. The function is used by getchar.

    A simplified example (note: this is XC2287M code), somewhere in main.c:

    #include <stdio.h>
    
    signed char putchar (signed char c)  { // used by printf
      while (!(U0C0_PSR & 0x2000));        //  wait until TBUF is empty
      U0C0_PSCR     |= 0x2000;             //  clear transmit buffer indication flag
      U0C0_TBUF00    = c;                  //  output character
      return (c);
    }
    
    int x_iskey(void) {
      if( (U0C0_PSR & 0x4000) == 0 ) return 0;
      return 1;
    }
    
    signed char x_getkey (void)  {         // synonymic function, _getkey replacement
      char c;                              // may also be just defined as _getkey
    
      while (!(U0C0_PSR & 0x4000));
      c = (char) U0C0_RBUF;
      U0C0_PSCR |= 0x4000;                 //  clear receive indication flag
      return (c);
    }
    
    

    Regard this like a small trick to bypass standard library code with your custom one.

    Look into getkey.c, putchar.c in you Keil's subfolder \c166\lib\.

    For details, you may want to check with http://www.keil.com/support/docs/2601.htm and links therein - e.g. http://www.keil.com/support/docs/2014.htm. There quite a few threads discussing printf via UART stuff.

    Regards,
    Nikolay.

Children