MOD5213 iprintf() error for UL and ULL types?
-
- Posts: 85
- Joined: Mon Apr 28, 2008 7:32 am
MOD5213 iprintf() error for UL and ULL types?
On the MOD5213, iprintf() seems to have a problem with printing unsigned long (UL) and unsigned long long (ULL) values with more than 9 digits. The code below shows output of UL and ULL values > 1,000,000,000 (10 digits). Only the last 9 digits are printed by iprintf(), while all digits are produced correctly by printf(). Is this a known issue with the MOD5213 library? I'm pretty sure this works correctly on the MOD5234.
Joe
// define and initialize UL with 10 digits (max) and ULL with 20 digits (max)
unsigned long long ULL = (0xFFFFFFFF << 32) + 0xFFFFFFFF;
unsigned long UL = 0xFFFFFFFF;
// print UL and ULL values using iprintf() and printf()
iprintf( "iprintf: UL = %lu, ULL = %llu\r\n", UL, ULL );
printf ( "printf: UL = %lu, ULL = %llu\r\n", UL, ULL );
// incorrect output (least sig. 9 digits) for iprintf(). correct output for printf().
iprintf: UL = 294967295 ULL = 294967295
printf: UL = 4294967295 ULL = 18446744073709551615
Joe
// define and initialize UL with 10 digits (max) and ULL with 20 digits (max)
unsigned long long ULL = (0xFFFFFFFF << 32) + 0xFFFFFFFF;
unsigned long UL = 0xFFFFFFFF;
// print UL and ULL values using iprintf() and printf()
iprintf( "iprintf: UL = %lu, ULL = %llu\r\n", UL, ULL );
printf ( "printf: UL = %lu, ULL = %llu\r\n", UL, ULL );
// incorrect output (least sig. 9 digits) for iprintf(). correct output for printf().
iprintf: UL = 294967295 ULL = 294967295
printf: UL = 4294967295 ULL = 18446744073709551615
Re: MOD5213 iprintf() error for UL and ULL types?
I just tried it on a 5272 (for one more data point) and it iprints correctly there as well. Does the MOD5213 have a unique stdio.h file? I would have thought all the platforms shared nburn\gcc-m68k\m68k-lef\include\stdio.h and I therefore assumed the code itself was in NetBurner.a not MOD5272.a, but you know what they say about assumptions.
Maybe try doing it with straight literals (no variables) like shown below and another data point might be to try cout.
<iostream>
std::cout<< 0xFFFFFFFF <<std::endl;
does too.
Maybe try doing it with straight literals (no variables) like shown below and another data point might be to try cout.
<iostream>
std::cout<< 0xFFFFFFFF <<std::endl;
does too.
- Attachments
-
- UnsignedLong.png (30.74 KiB) Viewed 9159 times
Re: MOD5213 iprintf() error for UL and ULL types?
I just took a quick glance at the 5213 data sheet, on second thought don't try cout, you'll probably run out of memory.
-
- Posts: 85
- Joined: Mon Apr 28, 2008 7:32 am
Re: MOD5213 iprintf() error for UL and ULL types?
Tod,
MOD5213 iprintf() shows problem for both variables and literals.
MOD5234 iprintf() works fine.
I would not have guessed that iprintf() would be different for MOD5234 and MOD5213, but it seems to be. While searching for information on this problem, I found NetBurner history for NNDK 2.1, which include the item below. Perhaps this fix was never made to the iprintf() that gets linked to the MOD5213 library.
Version 1.78: Fixed library bug so iprintf and printf support long variables.
64-bit integer math (LL and ULL) works fine in the MOD5213. It's just the iprintf() that doesn't work correctly.
Joe
MOD5213 iprintf() shows problem for both variables and literals.
MOD5234 iprintf() works fine.
I would not have guessed that iprintf() would be different for MOD5234 and MOD5213, but it seems to be. While searching for information on this problem, I found NetBurner history for NNDK 2.1, which include the item below. Perhaps this fix was never made to the iprintf() that gets linked to the MOD5213 library.
Version 1.78: Fixed library bug so iprintf and printf support long variables.
64-bit integer math (LL and ULL) works fine in the MOD5213. It's just the iprintf() that doesn't work correctly.
Joe
-
- Posts: 85
- Joined: Mon Apr 28, 2008 7:32 am
Re: MOD5213 iprintf() error for UL and ULL types?
I did some searching around regarding GCC iprintf(), and stumbled on a discussion of NetBurner vs. Rabbit from 2004 that included the quote below from Paul Breed, NetBurner CTO. The 5213 has much less resources than the 5234, so maybe they are using a different library code base.
Joe
Paul, if you read this, could you let us know if the problems with "long" and "long long" are fixable for iprintf() in the MOD5213?In 5 years we have had exactly 3 GCC/NewLib problems. All were actualy in NewLib
1)Printf did not support long long variables.
2)malloc had a reentrancy problem.
3)floating point printf reentrancy problem.
Joe
Re: MOD5213 iprintf() error for UL and ULL types?
not sure the netbuner iprintf supports long long.
The bung in the unsigned long was also on the SBL2E platform and that got fixed.
To fix the problem
nburn\system_nn\nbiprintf.cpp
Change
From:
int decimallen( DWORD dw )
{
if ( dw >= 100000000 ) return 9;
if ( dw >= 10000000 ) return 8;
if ( dw >= 1000000 ) return 7;
if ( dw >= 100000 ) return 6;
if ( dw >= 10000 ) return 5;
if ( dw >= 1000 ) return 4;
if ( dw >= 100 ) return 3;
if ( dw >= 10 ) return 2;
return 1;
}
to:
int decimallen( DWORD dw )
{
if (dw >=1000000000 ) return 10;
if ( dw >= 100000000 ) return 9;
if ( dw >= 10000000 ) return 8;
if ( dw >= 1000000 ) return 7;
if ( dw >= 100000 ) return 6;
if ( dw >= 10000 ) return 5;
if ( dw >= 1000 ) return 4;
if ( dw >= 100 ) return 3;
if ( dw >= 10 ) return 2;
return 1;
}
The bung in the unsigned long was also on the SBL2E platform and that got fixed.
To fix the problem
nburn\system_nn\nbiprintf.cpp
Change
From:
int decimallen( DWORD dw )
{
if ( dw >= 100000000 ) return 9;
if ( dw >= 10000000 ) return 8;
if ( dw >= 1000000 ) return 7;
if ( dw >= 100000 ) return 6;
if ( dw >= 10000 ) return 5;
if ( dw >= 1000 ) return 4;
if ( dw >= 100 ) return 3;
if ( dw >= 10 ) return 2;
return 1;
}
to:
int decimallen( DWORD dw )
{
if (dw >=1000000000 ) return 10;
if ( dw >= 100000000 ) return 9;
if ( dw >= 10000000 ) return 8;
if ( dw >= 1000000 ) return 7;
if ( dw >= 100000 ) return 6;
if ( dw >= 10000 ) return 5;
if ( dw >= 1000 ) return 4;
if ( dw >= 100 ) return 3;
if ( dw >= 10 ) return 2;
return 1;
}
Re: MOD5213 iprintf() error for UL and ULL types?
The netburner small printf on the MOD5213 does not support long long.
(Previous post should fix the unsigned long problem., that fix is now checked in and should eventually appear in a release.)
It could be modified... but forcing the libraries to link in the 64 bit math stuff
would be a loss for most applications.
(Previous post should fix the unsigned long problem., that fix is now checked in and should eventually appear in a release.)
It could be modified... but forcing the libraries to link in the 64 bit math stuff
would be a loss for most applications.
-
- Posts: 85
- Joined: Mon Apr 28, 2008 7:32 am
Re: MOD5213 iprintf() error for UL and ULL types?
Hi Paul,
Thanks very much for your help. I made the source change and rebuilt the system_nn library, and got a good result for UL as shown below. The output of iprintf() is now 10 digits instead of 9. As you said, trying to print a ULL just prints 32 bits instead of 64.
iprintf: UL = 4294967295, ULL = 4294967295
printf: UL = 4294967295, ULL = 18446744073709551615
Regarding your last comment, you're saying that if iprintf() had been written to support 64-bit values, it would have caused all 64-bit math routines to be linked? Now that I look at the iprintf() source, I see that math operations are required for printing, so it makes sense. I'll experiment and see what happens to code size when 64-bit math is used, but no floating point is used. I had never used 64-bit integers on a NB project until I tried to make an integer version of Larry's StopWatch. If ever wanted to use that in a space-limited project on the 5213, I'd be better off trying to make a version limited to times that fit in 32 bits.
Joe
Thanks very much for your help. I made the source change and rebuilt the system_nn library, and got a good result for UL as shown below. The output of iprintf() is now 10 digits instead of 9. As you said, trying to print a ULL just prints 32 bits instead of 64.
iprintf: UL = 4294967295, ULL = 4294967295
printf: UL = 4294967295, ULL = 18446744073709551615
Regarding your last comment, you're saying that if iprintf() had been written to support 64-bit values, it would have caused all 64-bit math routines to be linked? Now that I look at the iprintf() source, I see that math operations are required for printing, so it makes sense. I'll experiment and see what happens to code size when 64-bit math is used, but no floating point is used. I had never used 64-bit integers on a NB project until I tried to make an integer version of Larry's StopWatch. If ever wanted to use that in a space-limited project on the 5213, I'd be better off trying to make a version limited to times that fit in 32 bits.
Joe
Re: MOD5213 iprintf() error for UL and ULL types?
Is this still the case, 9 years later? I'm having trouble using %Ld with sprintf() on NNDK 3.2 with the MODM7AE. Lockups, garbage characters, and the like.
I can print 64-bit ints with some of the other functions, just not sprintf().
I can print 64-bit ints with some of the other functions, just not sprintf().
Re: MOD5213 iprintf() error for UL and ULL types?
Hello,
Perhaps I am misunderstanding your question, but I ran a quick test on 3.2 with the MODM7 with the following results:
Output:
Application AppWiz started
printf ld uint32_t decimal: 305419896, 0x12345678
printf lu uint32_t decimal: 305419896, 0x12345678
sprintf ld uint32_t decimal: 305419896, 0x12345678
sprintf lu uint32_t decimal: 305419896, 0x12345678
printf lld uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
printf llu uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
sprintf lld uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
sprintf llu uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
Is there anything here different from what you are doing?
Perhaps I am misunderstanding your question, but I ran a quick test on 3.2 with the MODM7 with the following results:
Code: Select all
void UserMain(void * pd)
{
init();
WaitForActiveNetwork(TICKS_PER_SECOND * 5); // Wait up to 5 seconds for active network activity
StartHttp();
iprintf("Application %s started\n",AppName );
char buf[2048];
uint32_t uint32Int = 0x12345678;
printf("printf ld uint32_t decimal: %ld, 0x%lx\r\n", uint32Int, uint32Int);
printf("printf lu uint32_t decimal: %lu, 0x%lx\r\n", uint32Int, uint32Int);
sprintf(buf, "sprintf ld uint32_t decimal: %ld, 0x%lx", uint32Int, uint32Int);
printf("%s\r\n", buf);
sprintf(buf, "sprintf lu uint32_t decimal: %lu, 0x%lx", uint32Int, uint32Int);
printf("%s\r\n", buf);
uint64_t uint64Int = 0x123456789ABCDEF0;
printf("printf lld uint64_t decimal: %lld, 0x%llx\r\n", uint64Int, uint64Int);
printf("printf llu uint64_t decimal: %llu, 0x%llx\r\n", uint64Int, uint64Int);
sprintf(buf, "sprintf lld uint64_t decimal: %lld, 0x%llx", uint64Int, uint64Int);
printf("%s\r\n", buf);
sprintf(buf, "sprintf llu uint64_t decimal: %llu, 0x%llx", uint64Int, uint64Int);
printf("%s\r\n", buf);
while (1)
{
OSTimeDly(TICKS_PER_SECOND);
}
}
Application AppWiz started
printf ld uint32_t decimal: 305419896, 0x12345678
printf lu uint32_t decimal: 305419896, 0x12345678
sprintf ld uint32_t decimal: 305419896, 0x12345678
sprintf lu uint32_t decimal: 305419896, 0x12345678
printf lld uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
printf llu uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
sprintf lld uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
sprintf llu uint64_t decimal: 1311768467463790320, 0x123456789abcdef0
Is there anything here different from what you are doing?