htons problem with K60? MQX bug?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

htons problem with K60? MQX bug?

2,303 Views
jpa
Contributor IV
The code htons(&server_address.sin_port, 10000); appears to work on the M52259EVB, but not on the TWR-K60. Both running MQX 3.7 & CW10.1. If I change the code to simply server_address.sin_port = 10000; on the K60, it seems to work. Is this an MQX bug or stupid user error? I'd have thought that if it's the latter, it would have been broken for both processors. The whole point is that it should do the same thing regardless of the endian of the processor, right? John
9 Replies

1,384 Views
butok
NXP Employee
NXP Employee

Hi Guys,


This is the feature of RTCS (not a bug).

server_address.sin_port must be in the Host endian. You should not use htons() for port numbers in the RTCS Socket- API.

I know, it is confusing, especially if you have experience with other TCP/IP stacks.

Best regards,

Andrey Butok

1,384 Views
BryGuyH
Contributor IV

Depends on your perspective - POSIX dictates .sin_port to be network byte order. Because MQX is supposed to be posix compliant it is a deviation from spec and consequently an implementation bug in RTCS on little-endian machines.

Ref: IEEE Std 1003.1 2004 <netinet/in.h>

0 Kudos
Reply

1,384 Views
butok
NXP Employee
NXP Employee

Hi,

You are correct.

But the MQX is not fully POSIX compliant. So this is the feature :smileywink:

It is not easy to change it. This approach was used by RTCS from beginning. And changing it will require modification of all existing RTCS applications.

BTW:      Some time ago, I was confused as you and wanted to change it. But it is unreal.

               If you still believe that it must be changed, you may try to report it as the bug via a customer-service request.

Thanks,

Andrey Butok

1,384 Views
David_Wu
Contributor III

sorry to hijack this thread - I had another issue related to htonl or htnos in pcb.h (MQX4)

See the definition here:

#define htonl(p,x) (((uint_8_ptr)(p))[0] = ((x) >> 24) & 0xFF, \

                    ((uint_8_ptr)(p))[1] = ((x) >> 16) & 0xFF, \

                    ((uint_8_ptr)(p))[2] = ((x) >>  8) & 0xFF, \

                    ((uint_8_ptr)(p))[3] =  (x)        & 0xFF, \

                    (x))

The problem is the MACRO  definition - this is not compliant to other system where on Linux for example below(man htonl) and htnol(&x, x) just did not work - I have to use another variable to save x - {int y = x; htnol(&x, y); }

This looks to me just wrong.

NAME

       htonl, htons, ntohl, ntohs - convert values between host and network byte order

SYNOPSIS

       #include <arpa/inet.h>

       uint32_t htonl(uint32_t hostlong);

       uint16_t htons(uint16_t hostshort);

       uint32_t ntohl(uint32_t netlong);

       uint16_t ntohs(uint16_t netshort);

0 Kudos
Reply

1,384 Views
butok
NXP Employee
NXP Employee

You are right, htonl(p,x) is not compliant with common API.

I do not know why it was done this way (and probably it should be fixed).

But you can use ntohl(x) that has only one input parameter. I know, it has different purpose but in fact it does the same thing.

0 Kudos
Reply

1,384 Views
David_Wu
Contributor III

right - then htonl(p, x) should  refine as

#define htonl(p) ntohl(p)

how simple is that!

0 Kudos
Reply

1,384 Views
BryGuyH
Contributor IV

htons means to convert from host to network short. Network is always big endian so if you're on a little endian machine (pretty much everybody these days) it needs to do a conversion. You only need to do conversion of data you're stuffing into TCP/UDP packets (which is really just limited to headers and specific protocols - nothing says your own protocol has to be big endian) so there is no reason to be using htons on the address port assignment since that is being used by the TCP/IP stack which will convert whatever it needs to.

(Edit: Apparently not all TCP/IP stacks do the conversion of address and port numbers for you - it appears the MQX implementation in this regard may be non-standard so if you're working with ported application code you might have to pay close attention to it)

0 Kudos
Reply

1,384 Views
DavidS
NXP Employee
NXP Employee

Hi John,

Something to look at is that ColdFire is big endian and Kinetis is little endian architecture.

I looked at the MQX source and Kinetis htons calls a macro that does byte swapping.  Maybe it shouldn't????

 

From pcb.h:

#define

htons(p, x) { *(uint_16*)(p) = HOST_TO_BE_SHORT(x); }

 

From mqx.h:

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
    #define HOST_TO_BE_SHORT(n)           (n)      <--- ColdFire

.

.

.
#else // (PSP_ENDIAN == MQX_BIG_ENDIAN)

    #define HOST_TO_BE_SHORT(n)           _PSP_SWAP2BYTE(n)    <--- Kinetis

 

Regards,

David

0 Kudos
Reply

1,384 Views
emilien
Contributor III

Hi,

 

  Same problem here.

I'll do further investigation but if somoene has a fix, he/she is welcome.

 

Best regards,

 

 

edit: Sorry, it was a stupid user error in my case...

 

-- 

Emilien

0 Kudos
Reply