Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CDC Emulation buggy
07-01-2014, 06:00 PM,
#1
CDC Emulation buggy
Hi all. I guess the CDC function could be buggy since i experienced many weird situation.
First, I'm using the PIC32MX250F128 DIY board. Here a tiny example to exploit the problem.

Platform Linux OpenSuse 13.1 32bit
Minicom terminal emulator

I complied with the IDE X.4 this very simple code

Quote:
void setup() {
}
void loop() {
int i=5;
float a,b,c=3.14;
CDC.printf("* Pinguino Mystery CDC Behaviour *\r\n");
CDC.printf("* Board PIC32MX250F128B *\r\n");
for (i=1;i<50;i++) {
a=3.14;
b=i;
// c=a+b;
CDC.printf("Data = %f\r\n",c);
}
CDC.printf("\n\r");
delay(500);
}

In this case the example works and the "dmesg" linux command reports the recognition of the CDC RS232 emulation in this way. Minicom decode the flow at 57600 bps.

Quote:
[ 6068.698169] usb 2-1: Product: CDC RS-232 Emulation Demo
[ 6068.698172] usb 2-1: Manufacturer: Microchip Technology Inc.
[ 6068.702103] cdc_acm 2-1:1.0: This device cannot do calls on its own. It is not a modem.
[ 6068.702142] cdc_acm 2-1:1.0: ttyACM0: USB ACM device

but if you simply uncomment the line c=a+b; and recompile and upload the code to the board the CDC RS232 emulation stop to work

dmesg now reports
Quote:
[ 7038.160066] usb 2-1: USB disconnect, device number 98
and the minicom terminal don't see anymore the ttyACM0 device.

To further help in debugging process consider that if you subtituite the line b=i with b=1
the CDC emulator show up in dmesg but the minicom emulator is unable to work with.

Tnx for any help.
Fabio.
Reply
08-01-2014, 12:50 PM,
#2
RE: CDC Emulation buggy
I don't think it's a CDC issue but maybe a bug in printf function or more likely a cast issue.
I would try with b=(float)i;
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
08-01-2014, 05:19 PM, (This post was last modified: 08-01-2014, 05:51 PM by fcapozzi.)
#3
RE: CDC Emulation buggy
Hi regis, explicit casting does not change the behaviour.
Instead i found something interesting that seem to be related somewhat to the printf function.
If i compile the code in this way

Quote:
......
a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %f\r\n",a);
.....
printing a instead of c it work and the output is
Data = 3.14

but if i to print the two variables a and b in this way
Quote:
a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %f+%f\r\n",a,b);

the output is
Quote:
Data = inf+2.00
Data = inf+4.00
Data = inf+6.00
Data = inf+7.00
Data = inf+9.00
Data = inf+11.00
Data = inf+13.00
Data = inf+15.00
Data = inf+17.00
Data = inf+19.00
... and so on

Now the a variable is seen as "inf" that is weird.

As a test i tried to add a separate CDC printf only for a as before in this way
Quote:a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %f\r\n",a);
CDC.printf("Data = %f+%f\r\n",a,b);
since i was supposing that printf was bad with two variables but as in precedence the output is
Quote:Data = inf
Data = inf+1.00
... and so on

At this point i don't know what to think .. may be something happen at compilation time since the same statement CDC.printf("Data = %f\r\n",a);
acts differently according the presence of a statement that came after in the program flow ... which is very very odd.
However since in the printf there is something to print in both cases the execution was done and the ttyACM0 device work. Anyhow there is a bug underneath that need to be fixed for sure ...

N.B. A final test ... now i can exclude the printf function .. it should be something related to the way the compiler handle the loops ...

if i execute this code ....
Quote:
for (i=1;i<4;i++) {
a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %.4f\r\n",a);
CDC.printf("Data = %f+%f\r\n",a,b);
}

it works and the output is
Quote:

* Pinguino Mystery CDC Behaviour *
* Board PIC32MX250F128B *
Data = 3.1400
Data = 3.14+1.00
Data = 3.1400
Data = 3.14+2.00
Data = 3.1400
Data = 3.14+3.00

but if you change the number of loops in this way
Quote:for (i=1;i<5;i++) {
a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %.4f\r\n",a);
CDC.printf("Data = %f+%f\r\n",a,b);
}

the output is
Quote:* Pinguino Mystery CDC Behaviour *
* Board PIC32MX250F128B *
Data = inf
Data = inf+1.00
Data = inf
Data = inf+2.00
Data = inf
Data = inf+3.00
Data = inf
Data = inf+4.00

What do you think... ???

(08-01-2014, 12:50 PM)regis Wrote: I don't think it's a CDC issue but maybe a bug in printf function or more likely a cast issue.
I would try with b=(float)i;
Reply
08-01-2014, 06:05 PM,
#4
RE: CDC Emulation buggy
FYI, printf function is in p32/include/pinguino/core/printf.c
- try to rename a (I noticed some stange behaviour with GCC and some variable name)
- do you get the same error with int instead of float ?
- what happens if you make an int pointer to a and print this int with %d ? Do you always get the same value ?
- it looks like the value of a is altered by the "print float" function in printf.c ... bad pointer initialization ?
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
08-01-2014, 09:27 PM, (This post was last modified: 08-01-2014, 09:29 PM by pingotg.)
#5
RE: CDC Emulation buggy
I tried the original version on my Pinguino32 OTG and it works fine (with c=a+b uncommented). No crash. No disappearing ttyACM0.

I happen to have used an old IDE version (rev 3 399) as it's what I have at hand.

So it's maybe a change in the IDE or something to do with the board (how it's defined/support/whatever).

I tried an Olimex MX220 but it has too little flash even for such a simple sample.

Well, it doesn't have too little but the way the bootloader etc is done takes up too much. Looking forward to a smaller one or at least one that uses the available flash better Smile

John
Reply
09-01-2014, 11:57 AM,
#6
RE: CDC Emulation buggy
I've done the tests you suggest :

a) renaming the variable does not seem to help, neither change position declaration in the source
or putting the declaration out of the setup and loop functions in top position.

b) Made pointer to variable a and printed the hexadecimal address

Quote:
void setup() {
}
void loop() {
int i=1;
float a,b,c=3.14;
int ptr = &a;
CDC.printf("* Pinguino Mystery CDC Behaviour *\r\n");
CDC.printf("* Board PIC32MX250F128B *\r\n");
CDC.printf("* 1.ptr-> a = %04x\r\n",ptr);
for (i=1;i<10;i++) {
CDC.printf("* 2.ptr-> a = %04x\r\n",ptr);
a=3.14;
b=i;
c=a+b;
CDC.printf("Data = %f+%f\r\n",a,b);
}
CDC.printf("\n\r");
delay(500);
}

The output is
Quote:
* Pinguino Mystery CDC Behaviour *
* Board PIC32MX250F128B *
* 1.ptr-> a = a0007fb8
* 2.ptr-> a = a0007fb8
Data = inf+1.00
* 2.ptr-> a = a0007fb8
Data = inf+2.00
* 2.ptr-> a = a0007fb8
... and so on ...

the address is the same outside and inside the loop.
I also test to change the variable memory handling using the modifier "static" and
"volatile" fo a but with no luck.
Now i am going to see p32/include/pinguino/core/printf.c
to understand what happen.
It would be nice to test this program on several pinguino board to understand if this is linked with the processor type or is a compiler problem. I've several PIC processor ready available at my lab but it take time to assemble different pinguinos just to test ...

(08-01-2014, 06:05 PM)regis Wrote: FYI, printf function is in p32/include/pinguino/core/printf.c
- try to rename a (I noticed some stange behaviour with GCC and some variable name)
- do you get the same error with int instead of float ?
- what happens if you make an int pointer to a and print this int with %d ? Do you always get the same value ?
- it looks like the value of a is altered by the "print float" function in printf.c ... bad pointer initialization ?
Reply
09-01-2014, 12:04 PM,
#7
RE: CDC Emulation buggy
As I posted, it works for me. Please read what I posted.

John
Reply
09-01-2014, 01:16 PM,
#8
RE: CDC Emulation buggy
Your example doesn't work on a Pinguino 32MX250 when compiled with IDE X4 rev 959 .
So there is at least a difference between revisions 399 (John's version) and 959.
I made some tests and I can confirm that the problem comes from the conversion of i from int to float. I tried with double instead and everything was fine even if printf uses float instead of double ...

So

Code:
void loop()
{
    int   i;
    double b;

    for (i=0; i<50; i++)
    {
        b = (double)i;
        CDC.printf("Data = %f\r\n", b);
    }
}

works, but

Code:
void loop()
{
    int   i;
    float b;

    for (i=0; i<50; i++)
    {
        b = (float)i;
        CDC.printf("Data = %f\r\n", b);
    }
}

doesn't work.
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
09-01-2014, 01:52 PM,
#9
RE: CDC Emulation buggy
Just one note: tricky point about printf functions (in normal C) is, that it completely relies on the FORMAT string in order to identify / separate the variable part of its argument list (since it has no other clue), especially in terms of parameter SIZEs. So it is vitaly important to perfectly match BOTH (format string AND parameter list), or else odd things will happen.

Given this, plus Regis' observation, I'd guess printf just expects doubles for 'f' formatted arguments. (ANSI C should do this conversion implicitly, by the way.)
Reply
09-01-2014, 02:46 PM, (This post was last modified: 09-01-2014, 02:52 PM by pingotg.)
#10
RE: CDC Emulation buggy
So, the likely things might be the flags being passed to C compiler/linker (in the makefile) or the version of the compiler/linker.

I have
p32/bin/mips-elf-gcc --version
mips-elf-gcc (Pinguino C Compiler for PIC32) 4.5.2

Yes, any float should be passed as a double (not just in printf) but IIRC a float and double can be the same size.

For this gcc, sizeof gives
float 4
double 8

John
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)