* [Buildroot] endian issue @ 2010-05-15 13:47 Marcel 2010-05-15 14:09 ` Grant Edwards 2010-05-15 14:19 ` Lionel Landwerlin 0 siblings, 2 replies; 10+ messages in thread From: Marcel @ 2010-05-15 13:47 UTC (permalink / raw) To: buildroot Hi, I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. I currently have most of my things working but run into an issue which is endian related. My driver outputs it's data in big-endian mode (ADC data). This is fine with me.I added a package to buildroot with my own software that talks to the driver. This package than transfers the results either over ethernet, usb or rs232. This all works great as long as I don't perform any calculations in the package that I added. When I do so, all data will be messed up and I'm sure it's related to endiannes. I think my package is compiled in little-endian mode and I'm quite sure this is the issue. I did some byte swapping to proof it's the issue and this byte swapping makes things fine. Is there any way to compile my package in big-endian mode from buildroot ? Or is there another way I should force this ? Best regards, Marcel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 13:47 [Buildroot] endian issue Marcel @ 2010-05-15 14:09 ` Grant Edwards 2010-05-15 14:19 ` Lionel Landwerlin 1 sibling, 0 replies; 10+ messages in thread From: Grant Edwards @ 2010-05-15 14:09 UTC (permalink / raw) To: buildroot On 2010-05-15, Marcel <korgull@home.nl> wrote: > I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. > > I currently have most of my things working but run into an issue > which is endian related. > > My driver outputs it's data in big-endian mode (ADC data). Oops. The 9g45 is a little-endian part. > This is fine with me. Apparently not, since you're complaining about how it breaks things. ;) > I added a package to buildroot with my own software that talks to the > driver. This package than transfers the results either over ethernet, > usb or rs232. This all works great as long as I don't perform any > calculations in the package that I added. That's because your processor is running in little-endian mode. Doing calculations on big-endian data using a little-endian part (or vice versa) doesn't work. > When I do so, all data will be messed up and I'm sure it's related to > endiannes. n Indeed it is. > I think my package is compiled in little-endian mode I would hope so, since you're running it on a little-endian part. > and I'm quite sure this is the issue. The issue is your driver. Change your driver to return data in the format expected by your processor (that's little-endian in the case of the 9g45). Then use standard macros (hton(), htons(), htonl()) to convert data to "network order" before you ship it out via Ethernet or USB. [Don't ask me why Atmel chose little-endian when they designed the AT91 peripherals. For anything with a network interface, big-endian makes a lot more sense to me. But that debate has been going on for 40 years...] > I did some byte swapping to proof it's the issue and this byte > swapping makes things fine. > > Is there any way to compile my package in big-endian mode from > buildroot ? Yes. But doing so will result in object files that don't work. In fact you won't even be able to link them. > Or is there another way I should force this ? No, you shouldn't force this. You should fix your driver. Really. -- Grant ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 13:47 [Buildroot] endian issue Marcel 2010-05-15 14:09 ` Grant Edwards @ 2010-05-15 14:19 ` Lionel Landwerlin 2010-05-15 14:43 ` Grant Edwards 2010-05-15 15:18 ` Marcel 1 sibling, 2 replies; 10+ messages in thread From: Lionel Landwerlin @ 2010-05-15 14:19 UTC (permalink / raw) To: buildroot Le samedi 15 mai 2010 ? 15:47 +0200, Marcel a ?crit : > Hi, > > I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. > > I currently have most of my things working but run into an issue which is > endian related. > > My driver outputs it's data in big-endian mode (ADC data). This is fine with > me.I added a package to buildroot with my own software that talks to the > driver. This package than transfers the results either over ethernet, usb or > rs232. This all works great as long as I don't perform any calculations in the > package that I added. When I do so, all data will be messed up and I'm sure > it's related to endiannes. > I think my package is compiled in little-endian mode and I'm quite sure this > is the issue. I did some byte swapping to proof it's the issue and this byte > swapping makes things fine. The endianness configuration of your processor isn't something you can usually change 'on-the-fly'. It's usually set up early in the boot process. So you have to choose whether you want to compile all your system in big or little endian, you can select that from the buildroot architecture configuration (arm -> little, armeb -> big, for example). > > Is there any way to compile my package in big-endian mode from buildroot ? > Or is there another way I should force this ? > You can't select that for 1 package, it's for the whole system or nothing. Otherwise, the smartest approch would be to make endian detection (at compile time or at running time) to adapt your processing algorithm. Regards, -- Lionel Landwerlin ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 14:19 ` Lionel Landwerlin @ 2010-05-15 14:43 ` Grant Edwards 2010-05-15 15:26 ` Marcel 2010-05-15 15:18 ` Marcel 1 sibling, 1 reply; 10+ messages in thread From: Grant Edwards @ 2010-05-15 14:43 UTC (permalink / raw) To: buildroot On 2010-05-15, Lionel Landwerlin <llandwerlin@gmail.com> wrote: > Le samedi 15 mai 2010 ?? 15:47 +0200, Marcel a ??crit : >> >> I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. >> >> I currently have most of my things working but run into an issue which is >> endian related. > > The endianness configuration of your processor isn't something you > can usually change 'on-the-fly'. It's usually set up early in the > boot process. While the endian configuration of the ARM9 core can be changed, the AT91 peripherals are little-endian. In theory, he should be able to run the ARM9 core in big-endian mode, but a running uC core without any working peripherals is surprisingly useless. > So you have to choose whether you want to compile all your system in > big or little endian, you can select that from the buildroot > architecture configuration (arm -> little, armeb -> big, for > example). In this case, he has to choose little-endian. [I've never seen an ARM-based uController that had peripherals with configurable endianess -- are there any?] >> Is there any way to compile my package in big-endian mode from >> buildroot? Or is there another way I should force this? > > You can't select that for 1 package, it's for the whole system or > nothing. Otherwise, the smartest approch would be to make endian > detection (at compile time or at running time) to adapt your > processing algorithm. Yep, the OP's should driver should return data in host-order. Otherwise, he'll have to suffer the guilt of knowing that a few years from now some poor sod who inherits the code will have a stroke from the effort required to resist the urge to track down the OP and slap him silly. -- Grant ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 14:43 ` Grant Edwards @ 2010-05-15 15:26 ` Marcel 2010-05-15 16:33 ` Thomas Petazzoni ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Marcel @ 2010-05-15 15:26 UTC (permalink / raw) To: buildroot On Saturday 15 May 2010 04:43:29 pm Grant Edwards wrote: > On 2010-05-15, Lionel Landwerlin <llandwerlin@gmail.com> wrote: > > Le samedi 15 mai 2010 ?? 15:47 +0200, Marcel a ??crit : > >> I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. > >> > >> I currently have most of my things working but run into an issue which > >> is endian related. > > > > The endianness configuration of your processor isn't something you > > can usually change 'on-the-fly'. It's usually set up early in the > > boot process. > > While the endian configuration of the ARM9 core can be changed, the > AT91 peripherals are little-endian. In theory, he should be able to > run the ARM9 core in big-endian mode, but a running uC core without > any working peripherals is surprisingly useless. > > > So you have to choose whether you want to compile all your system in > > big or little endian, you can select that from the buildroot > > architecture configuration (arm -> little, armeb -> big, for > > example). > > In this case, he has to choose little-endian. That's very clear. > [I've never seen an ARM-based uController that had peripherals with > configurable endianess -- are there any?] > > >> Is there any way to compile my package in big-endian mode from > >> buildroot? Or is there another way I should force this? > > > > You can't select that for 1 package, it's for the whole system or > > nothing. Otherwise, the smartest approch would be to make endian > > detection (at compile time or at running time) to adapt your > > processing algorithm. > > Yep, the OP's should driver should return data in host-order. > > Otherwise, he'll have to suffer the guilt of knowing that a few years > from now some poor sod who inherits the code will have a stroke from > the effort required to resist the urge to track down the OP and slap > him silly. If I wish to do that, how do I detect the endianness of a sytem and do I need to reformat my data in my drivers for this ? If so, isn't that a pure waste of cpu cycles for the sake of reusable code ? If I can do this without any speed sacrifice than I will do it, if not....than it's simply not an option for this system. Best regards, Marcel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 15:26 ` Marcel @ 2010-05-15 16:33 ` Thomas Petazzoni 2010-05-15 16:37 ` Lionel Landwerlin 2010-05-15 16:45 ` Grant Edwards 2 siblings, 0 replies; 10+ messages in thread From: Thomas Petazzoni @ 2010-05-15 16:33 UTC (permalink / raw) To: buildroot On Sat, 15 May 2010 17:26:57 +0200 Marcel <korgull@home.nl> wrote: > If I wish to do that, how do I detect the endianness of a sytem and > do I need to reformat my data in my drivers for this ? If so, isn't > that a pure waste of cpu cycles for the sake of reusable code ? > If I can do this without any speed sacrifice than I will do it, if > not....than it's simply not an option for this system. If your driver is in the kernel, tust use the kernel functions be16_to_cpu(), be32_to_cpu(), etc. They will automatically do the appropriate conversion depending on the CPU endianess. Thomas -- Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 15:26 ` Marcel 2010-05-15 16:33 ` Thomas Petazzoni @ 2010-05-15 16:37 ` Lionel Landwerlin 2010-05-15 16:45 ` Grant Edwards 2 siblings, 0 replies; 10+ messages in thread From: Lionel Landwerlin @ 2010-05-15 16:37 UTC (permalink / raw) To: buildroot Le samedi 15 mai 2010 ? 17:26 +0200, Marcel a ?crit : > On Saturday 15 May 2010 04:43:29 pm Grant Edwards wrote: > > On 2010-05-15, Lionel Landwerlin <llandwerlin@gmail.com> wrote: > > > Le samedi 15 mai 2010 ?? 15:47 +0200, Marcel a ??crit : > > >> I'm using an Atmel sam9g45 using buildroot with linux 2.6.33. > > >> > > >> I currently have most of my things working but run into an issue which > > >> is endian related. > > > > > > The endianness configuration of your processor isn't something you > > > can usually change 'on-the-fly'. It's usually set up early in the > > > boot process. > > > > While the endian configuration of the ARM9 core can be changed, the > > AT91 peripherals are little-endian. In theory, he should be able to > > run the ARM9 core in big-endian mode, but a running uC core without > > any working peripherals is surprisingly useless. > > > > > So you have to choose whether you want to compile all your system in > > > big or little endian, you can select that from the buildroot > > > architecture configuration (arm -> little, armeb -> big, for > > > example). > > > > In this case, he has to choose little-endian. > > That's very clear. > > > [I've never seen an ARM-based uController that had peripherals with > > configurable endianess -- are there any?] > > > > >> Is there any way to compile my package in big-endian mode from > > >> buildroot? Or is there another way I should force this? > > > > > > You can't select that for 1 package, it's for the whole system or > > > nothing. Otherwise, the smartest approch would be to make endian > > > detection (at compile time or at running time) to adapt your > > > processing algorithm. > > > > Yep, the OP's should driver should return data in host-order. > > > > Otherwise, he'll have to suffer the guilt of knowing that a few years > > from now some poor sod who inherits the code will have a stroke from > > the effort required to resist the urge to track down the OP and slap > > him silly. > > If I wish to do that, how do I detect the endianness of a sytem and do I need > to reformat my data in my drivers for this ? If so, isn't that a pure waste of > cpu cycles for the sake of reusable code ? > If I can do this without any speed sacrifice than I will do it, if not....than > it's simply not an option for this system. > > Best regards, > Marcel > A basic example of detection (copy pasta from here http://www.allegro.cc/forums/print-thread/592785) => Uint32 Value32; Uint8 *VPtr = (Uint8 *)&Value32; VPtr[0] = VPtr[1] = VPtr[2] = 0; VPtr[3] = 1; if(Value32 == 1) printf("I'm big endian\n"); else printf("I'm little endian\n"); <= Some packages make this detection within configure script using such code (which is problematic with cross compilation because you can't run target code on the host) and then use some #ifdef BIG_ENDIAN etc... Of course doing endian translation costs more than doing nothing. -- Lionel Landwerlin ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 15:26 ` Marcel 2010-05-15 16:33 ` Thomas Petazzoni 2010-05-15 16:37 ` Lionel Landwerlin @ 2010-05-15 16:45 ` Grant Edwards 2010-05-15 17:53 ` Marcel 2 siblings, 1 reply; 10+ messages in thread From: Grant Edwards @ 2010-05-15 16:45 UTC (permalink / raw) To: buildroot On 2010-05-15, Marcel <korgull@home.nl> wrote: > If I wish to do that, how do I detect the endianness of a sytem For user space: /usr/include/endian.h For kernel code: /usr/src/linux/include/linux/byteorder.h > and do I need to reformat my data in my drivers for this? That's up to you to decide. Based on your original posting, I was under the impression you needed to do calculations on your data on the 9g45. If you need to be able to do calculations on your data on the 9g45, then that data has to be little-endian. If you need to do calculations on big-endian input data and generate a big-endian output stream, and the 9g45 doesn't have the throughput to do the byte-swapping, then you probably need to choose a different (probably big-endian) part. Many parts that are aimed more squarely at network stuff are big-endian. Perhaps one of the Intel IXP network processors (but not the PXA parts) or Motorola PPC chips [you can check with your local distributor to find out the nom du jour for company/product-line]. If the peripheral produces big-endian data, you don't need to do any computations with that data, and you want to ship out big-endian data, then, no you don't have a problem. Just make sure that you put in plenty of warning comments so that later when somebody does decide to add some computations on the 9g45 they have an easier time figuring out why it doesn't work. Better yet, since wise maintainers generally ignore comments, you could use an opaque data type for the data since it's just a blob of bytes and not a numeric value. A structure containing a single field that's an array of 4 bytes should make a good opaque 32-bit type. That way whoever has to maintain your code won't fall into the trap you'd be setting if you declare something as a numeric type when it really isn't. > If so, isn't that a pure waste of cpu cycles for the sake of reusable > code? If you didn't want to do calculations on data on the 9g45, what exactly was the problem you were asking about in your OP? > If I can do this without any speed sacrifice than I will do it, if > not....than it's simply not an option for this system. Sorry, I have no way of knowing what your requirements are nor of knowing the cost of producing little-endian data in your driver. Perhaps you can fix the board layout to correctly connect whatever peripheral is providing big-endian data? Then you'd only have to do the byte-swapping once: after you've done the calculations on the 9g45 and before you ship it out via Ethernet or USB. -- Grant ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 16:45 ` Grant Edwards @ 2010-05-15 17:53 ` Marcel 0 siblings, 0 replies; 10+ messages in thread From: Marcel @ 2010-05-15 17:53 UTC (permalink / raw) To: buildroot On Saturday 15 May 2010 06:45:50 pm Grant Edwards wrote: > On 2010-05-15, Marcel <korgull@home.nl> wrote: > > If I wish to do that, how do I detect the endianness of a sytem > > For user space: > > /usr/include/endian.h > > For kernel code: > > /usr/src/linux/include/linux/byteorder.h > > > and do I need to reformat my data in my drivers for this? > > That's up to you to decide. > > Based on your original posting, I was under the impression you needed > to do calculations on your data on the 9g45. If you need to be able to > do calculations on your data on the 9g45, then that data has to be > little-endian. > > If you need to do calculations on big-endian input data and generate a > big-endian output stream, and the 9g45 doesn't have the throughput to > do the byte-swapping, then you probably need to choose a different > (probably big-endian) part. Many parts that are aimed more squarely > at network stuff are big-endian. Perhaps one of the Intel IXP network > processors (but not the PXA parts) or Motorola PPC chips [you can > check with your local distributor to find out the nom du jour for > company/product-line]. > > If the peripheral produces big-endian data, you don't need to do any > computations with that data, and you want to ship out big-endian data, > then, no you don't have a problem. Just make sure that you put in > plenty of warning comments so that later when somebody does decide to > add some computations on the 9g45 they have an easier time figuring > out why it doesn't work. > > Better yet, since wise maintainers generally ignore comments, you > could use an opaque data type for the data since it's just a blob of > bytes and not a numeric value. A structure containing a single field > that's an array of 4 bytes should make a good opaque 32-bit type. That > way whoever has to maintain your code won't fall into the trap you'd be > setting if you declare something as a numeric type when it really isn't. > > > If so, isn't that a pure waste of cpu cycles for the sake of reusable > > code? > > If you didn't want to do calculations on data on the 9g45, what > exactly was the problem you were asking about in your OP? > > > If I can do this without any speed sacrifice than I will do it, if > > not....than it's simply not an option for this system. > > Sorry, I have no way of knowing what your requirements are nor of > knowing the cost of producing little-endian data in your driver. > > Perhaps you can fix the board layout to correctly connect whatever > peripheral is providing big-endian data? Then you'd only have to do > the byte-swapping once: after you've done the calculations on the 9g45 > and before you ship it out via Ethernet or USB. Well, I need to do quite a lot of calculation so I decided it's wise to make my driver output the data in little-endian format, than perform the calculations and at the very end convert if to big endian before moving it out via ethernet or USB. My calculations involve quite a lot of matrix multiplying in floating point so conversions in there wouldn't be nice either. So, the only good choice would be to output the data from my driver in little-endian format. There's no cost of cycles in my driver whether I output little or big endian data. The data comes in two bytes from a 16bit ADC and can be stored in any order in my array. I basically read a stream from this ADC. Having both big and little supported in the driver may cost some overhead which I don't want. However since this driver is also used on another platform I will use the suggested methods from the other posts to make the driver independent of the host endian format and try to reduce the overhead to a minimum. Thanks for all the great replies. Best regards, Marcel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Buildroot] endian issue 2010-05-15 14:19 ` Lionel Landwerlin 2010-05-15 14:43 ` Grant Edwards @ 2010-05-15 15:18 ` Marcel 1 sibling, 0 replies; 10+ messages in thread From: Marcel @ 2010-05-15 15:18 UTC (permalink / raw) To: buildroot On Saturday 15 May 2010 04:19:42 pm Lionel Landwerlin wrote: > The endianness configuration of your processor isn't something you can > usually change 'on-the-fly'. It's usually set up early in the boot > process. > So you have to choose whether you want to compile all your system in big > or little endian, you can select that from the buildroot architecture > configuration (arm -> little, armeb -> big, for example). That's clear. My board is being developed from an environment I got from in-circuit. arm is selected (not armeb) and indeed the packages are compiled in little endian format. Are there any additional items I should be aware of when switching from arm to armeb ? > > Is there any way to compile my package in big-endian mode from buildroot > > ? Or is there another way I should force this ? > > You can't select that for 1 package, it's for the whole system or > nothing. > Otherwise, the smartest approch would be to make endian detection (at > compile time or at running time) to adapt your processing algorithm. Well, the biggest issue I have is that my data that gets send out to the host PC must be in big-endian format. My drivers work this way too so the best would be if everything is big-endian so that I can transfer data from my drivers, through the package to the host PC without touching the data. I could leave everything in little endian format but I would than have to reformat my data before sending it out. Although this is not all that difficult I don't like to waste time in that process. Thanks for your reply, Marcel ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-05-15 17:53 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-15 13:47 [Buildroot] endian issue Marcel 2010-05-15 14:09 ` Grant Edwards 2010-05-15 14:19 ` Lionel Landwerlin 2010-05-15 14:43 ` Grant Edwards 2010-05-15 15:26 ` Marcel 2010-05-15 16:33 ` Thomas Petazzoni 2010-05-15 16:37 ` Lionel Landwerlin 2010-05-15 16:45 ` Grant Edwards 2010-05-15 17:53 ` Marcel 2010-05-15 15:18 ` Marcel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox