Announcements
IMPORTANT: Cypress Developer Community is transitioning on October 20th. To learn more and be prepared for this change, check out our latest announcement.
cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1 MCU

jotic_1250681
New Contributor II

I need to put a few lines of code in an interrupt service routine (ISR) to print the value in a variable at the time of the interrupt.  Timing is not critical, this is just a test to check an operation.  I have a CY8CKIT-059 board and use a counter (Counter_3X) to create the interrupt.  Here is the ISR

*  Place your includes, defines and code here

********************************************************************************/

/* `#START Counter_3X_Done_intc` */

   

    extern void Counter_3X_Stop();      //Stop Counter_3X

    extern uint16 charindex;            //Value from main program

    char strMsg3X[30];                  //Set up array for characters to print   

    sprintf(strMsg3X,"CharIndex = %u\r\n",charindex);      //Line 34

    int UART_1_PutString(strMsg3X);                        //Line 35

   

/* `#END` */

The first line (Line 34 in boldface) produces the Build error, "expected ')' before string constant" and when I hover over the string, the cursor shows "expected identifier".

When I hover over Line 35, I read the following, "a parameter list without types is only allowed in a function definition."  I have no idea what this means.

I have attached an image of the error and warning messages.  All I need is a way to display a value on a terminal for tests.  No printing will occur in the finished code.  If you can suggest an alternate way to accomplish my testing goal, I welcome your ideas.  Thank you. --Jon

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

Hi,

So I tested it by myself using CY8CKIT-059.

I emulated your project with following schematic.

002-schematic.JPG

To make it work, I needed to modify the ISR as

(part of Counter_3X_Done.c)

============================

CY_ISR(Counter_3X_Done_Interrupt)

{

    #ifdef Counter_3X_Done_INTERRUPT_INTERRUPT_CALLBACK

        Counter_3X_Done_Interrupt_InterruptCallback();

    #endif /* Counter_3X_Done_INTERRUPT_INTERRUPT_CALLBACK */

    /*  Place your Interrupt code here. */

    /* `#START Counter_3X_Done_Interrupt` */

//    #include "project.h"

//    #include "stdio.h"

    extern void Counter_3X_Stop() ;

    extern void Counter_3X_ReadStatusRegister(void) ;

    extern uint16 charindex ;

    char strMsg3X[30] ;

  

    Counter_3X_Done_ClearPending() ;

    Counter_3X_ReadStatusRegister() ;

  

    sprintf(strMsg3X, "CharIndex = %u\r\n", charindex) ;

    UART_1_PutString(strMsg3X) ;

    /* `#END` */

}

============================

and the main.c

============================

#include "project.h"

#include "stdio.h"

uint16 charindex = 0 ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_1_PutString(str) ;

}

void init_hardware(void)

{

    UART_1_Start() ;

  

    Counter_3X_Done_ClearPending() ;

    Counter_3X_Done_Start() ;

    Counter_3X_WriteCounter(0) ;

    Counter_3X_Init() ;

    Counter_3X_Enable() ;

  

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void splash(void)

{

    sprintf(str, "PSoC LP5 Interrupt Test A (%s %s)\r\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

  

    splash() ;

    for(;;) {

        charindex++ ;

        CyDelay(100) ;

    }

}

============================

And the Tera Term log was

000-TeraTerm-LogA.JPG

So anyway, the project seems to be working.

But as I wrote earlier, having sprintf(), PutString() in ISR is not recommend because of a couple of reasons (IMHO)

(1) They usually take rather long time, where an ISR is expected return as soon as possible.

(2) They tend to allocate and/or move memory, which is also not good for an ISR, in some MCU it causes hang.

Meantime, in general, I don't want touch "system generated source/header", for example

"Counter_3X_Done.c" in this case.

I'd rather use Counter_3X_Done_StartEx() instead of Counter_3X_Done_Start() 

so that I can prepare the ISR in my source files.

In the following example, "counter_done_isr()".

I rewrote the program as below.

I used Counter_3X_Done_StartEx(),

and in the ISR I only saved charindex to a variable "value_at_int"

and print it in the main loop.

Note: Please forgive me for using sprintf() instead of snprintf() 😜

main.c

============================

#include "project.h"

#include "stdio.h"

volatile uint16_t value_at_int = 0 ;

volatile int counter_done_flag = 0 ;

uint16_t charindex = 0 ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_1_PutString(str) ;

}

CY_ISR(counter_done_isr)

{

    Counter_3X_ReadStatusRegister() ;

    Counter_3X_Done_ClearPending() ;

   

    counter_done_flag = 1 ;

    value_at_int = charindex ;

}

void init_hardware(void)

{

    UART_1_Start() ;

   

    Counter_3X_Done_ClearPending() ;

    Counter_3X_Done_StartEx(counter_done_isr) ;

    Counter_3X_WriteCounter(0) ;

    Counter_3X_Init() ;

    Counter_3X_Enable() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void splash(void)

{

    sprintf(str, "PSoC LP5 Interrupt Test B (%s %s)\r\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

   

    splash() ;

    for(;;) {

        charindex++ ;

       

        if (counter_done_flag) {

            counter_done_flag = 0 ;

            sprintf(str, "charindex = %d\n", value_at_int) ;

            print(str) ;

        }

        CyDelay(100) ;

    }

}

============================

The Tera Term Log was

001-TeraTerm-logB.JPG

moto

P.S. Attached are

int_test_190605A printing in the ISR

int_test_190605B printing in the main loop

View solution in original post

0 Likes
3 Replies
MotooTanaka
Esteemed Contributor

Hi,

In general, using print type function in an isr is not recommended.

Having said that, what I could notice was

>     int UART_1_PutString(strMsg3X);                        //Line 35

should be

<    UART_1_PutString(strMsg3X);                        //Line 35

Would you let me know, what kind of error(s) you will get after modifying the above?

moto

0 Likes
Len_CONSULTRON
Honored Contributor II

Jon,

Moto is correct.  The general principle I learned long ago is to only perform the bare minimum in ISRs.  Basically just gather the data and/or turn on something quickly.  What ever the ISR was truly intended for.  All other time intensive operations should be done at the higher-level Application SW.  sprintf()s and PutString() functions are time intensive and will probably use quite a bit of stack.  Inside an ISR, you've already used a bit a stack to get there.

If more processing is needed after executing an ISR, then set a signal (RAM flag for example) so that the Application task level can pick up the signal can execute the additional operations.

Len

PS:  I recommend using snprintf() instead of sprintf().  snprintf() is an ANSI-safe function.  It prevents string buffer overruns.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
MotooTanaka
Esteemed Contributor

Hi,

So I tested it by myself using CY8CKIT-059.

I emulated your project with following schematic.

002-schematic.JPG

To make it work, I needed to modify the ISR as

(part of Counter_3X_Done.c)

============================

CY_ISR(Counter_3X_Done_Interrupt)

{

    #ifdef Counter_3X_Done_INTERRUPT_INTERRUPT_CALLBACK

        Counter_3X_Done_Interrupt_InterruptCallback();

    #endif /* Counter_3X_Done_INTERRUPT_INTERRUPT_CALLBACK */

    /*  Place your Interrupt code here. */

    /* `#START Counter_3X_Done_Interrupt` */

//    #include "project.h"

//    #include "stdio.h"

    extern void Counter_3X_Stop() ;

    extern void Counter_3X_ReadStatusRegister(void) ;

    extern uint16 charindex ;

    char strMsg3X[30] ;

  

    Counter_3X_Done_ClearPending() ;

    Counter_3X_ReadStatusRegister() ;

  

    sprintf(strMsg3X, "CharIndex = %u\r\n", charindex) ;

    UART_1_PutString(strMsg3X) ;

    /* `#END` */

}

============================

and the main.c

============================

#include "project.h"

#include "stdio.h"

uint16 charindex = 0 ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_1_PutString(str) ;

}

void init_hardware(void)

{

    UART_1_Start() ;

  

    Counter_3X_Done_ClearPending() ;

    Counter_3X_Done_Start() ;

    Counter_3X_WriteCounter(0) ;

    Counter_3X_Init() ;

    Counter_3X_Enable() ;

  

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void splash(void)

{

    sprintf(str, "PSoC LP5 Interrupt Test A (%s %s)\r\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

  

    splash() ;

    for(;;) {

        charindex++ ;

        CyDelay(100) ;

    }

}

============================

And the Tera Term log was

000-TeraTerm-LogA.JPG

So anyway, the project seems to be working.

But as I wrote earlier, having sprintf(), PutString() in ISR is not recommend because of a couple of reasons (IMHO)

(1) They usually take rather long time, where an ISR is expected return as soon as possible.

(2) They tend to allocate and/or move memory, which is also not good for an ISR, in some MCU it causes hang.

Meantime, in general, I don't want touch "system generated source/header", for example

"Counter_3X_Done.c" in this case.

I'd rather use Counter_3X_Done_StartEx() instead of Counter_3X_Done_Start() 

so that I can prepare the ISR in my source files.

In the following example, "counter_done_isr()".

I rewrote the program as below.

I used Counter_3X_Done_StartEx(),

and in the ISR I only saved charindex to a variable "value_at_int"

and print it in the main loop.

Note: Please forgive me for using sprintf() instead of snprintf() 😜

main.c

============================

#include "project.h"

#include "stdio.h"

volatile uint16_t value_at_int = 0 ;

volatile int counter_done_flag = 0 ;

uint16_t charindex = 0 ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_1_PutString(str) ;

}

CY_ISR(counter_done_isr)

{

    Counter_3X_ReadStatusRegister() ;

    Counter_3X_Done_ClearPending() ;

   

    counter_done_flag = 1 ;

    value_at_int = charindex ;

}

void init_hardware(void)

{

    UART_1_Start() ;

   

    Counter_3X_Done_ClearPending() ;

    Counter_3X_Done_StartEx(counter_done_isr) ;

    Counter_3X_WriteCounter(0) ;

    Counter_3X_Init() ;

    Counter_3X_Enable() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void splash(void)

{

    sprintf(str, "PSoC LP5 Interrupt Test B (%s %s)\r\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

   

    splash() ;

    for(;;) {

        charindex++ ;

       

        if (counter_done_flag) {

            counter_done_flag = 0 ;

            sprintf(str, "charindex = %d\n", value_at_int) ;

            print(str) ;

        }

        CyDelay(100) ;

    }

}

============================

The Tera Term Log was

001-TeraTerm-logB.JPG

moto

P.S. Attached are

int_test_190605A printing in the ISR

int_test_190605B printing in the main loop

View solution in original post

0 Likes