DOES htonl() change byte order on BIG ENDIAN machine? - c

Literally confused about htonl(). In so many links I found that code to do htonl is :
#define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))
If the same code is ran on both the machines, it is going to swap the byte orders.
Example : uint32_t a = 0x1;
On Little Endian:
Addr value
100 1
101 0
102 0
103 0
After htonl(a)
Addr value
100 0
101 0
102 0
103 1
============================================
On Big Endian machine:
Addr value
100 0
101 0
102 0
103 1
After htonl(a)
Addr value
100 1
101 0
102 0
103 0
Does that mean that htonl() will change the order of the bytes irrespective of machine architecture ?

If you use it correctly then it should not swap bytes on big endian machines.
htonl is defined in a header which is architecture specific. Normally machine/endian.h will include your architecture specific header. If you redefine it then it will do what you set it to. If you want the real behaviour then you should always use the right architecture header. On big endian machines it's a no op. On little endian machines it's often linked to a specific processor instruction.

I think key to understanding the function is understanding its name.
The function htonl is:
H ost to
N etwork L ong
That is: it converts from the Host order to the Network defined (Big Endian) order.
Different hosts could have different representations:
Big-Ending
Little-Endian
even some other representation (imagine some new machine that works on base-3, or has Middle-Outwards representation?
Whatever the machine format, this function converts to a common Network format so the data can be easily, reliably sent to other machines on the network that may have different representations.
Once you understand the concept of Host / Network, then it shouldn't be hard to understand that Network order is Big-Endian, and any Host that is Big-Endian doesn't need any conversion at all.

Related

Bitmasking and Air724 LTE Module

Looking for a bit (pardon the pun) of help on this one.
I need to set the various band parameters on an Air724 modem as in the descriptor below for the AT*BAND= syntax.
I am in Australia and looking to use the Telstra FDD-LTE Band 3 only. I am seeking some help as to how to get the syntax correct please? That is the bit operations for bands.
Any help is greatly appreciated.
The solution is for an Arduino C compiler, so any C construct would be useful.
Thank you.
SYNTAX
AT*BAND=[<mode>[<GSMband>,<UMTSband>,<LTEbandH>,<LTEbandL>[,<roamingConfig>,<srvDomain>,<bandPriorityFlag>]]]
Note: <mode>: integer type
0 –GSM network
1 –UMTS network
2 –Dual mode(GSM and UMTS) (auto)
3 –Dual mode(GSM and UMTS) (GSM preferred)
4 –Dual mode(GSM and UMTS) (UMTS preferred)
5 –LTE network
6–Dual mode(GSM and LTE)(auto)
7–Dual mode(GSM and LTE)( GSM preferred)
8–Dual mode(GSM and LTE)(LTE preferred)
9–Dual mode(UMTS and LTE)(auto)
10–Dual mode(UMTS and LTE)(UMTS preferred)
11–Dual mode(UMTS and LTE)(LTE preferred)
12–Trip mode(auto)
13–Trip mode(GSM preferred)
14–Trip mode(TD preferred)
15–Trip mode(LTE preferred)
<GSMband>: integer type <GSMband> is a sum of integers each representing a GSM band
(in other words bit mask)
1 –PGSM 900 (standard or primary)
2 –DCS GSM 1800
4 –PCS GSM 1900
8 –EGSM 900 (extended)
16 –GSM 450
32 –GSM 480
64 –GSM 850
<UMTSband>: integer type <UMTSband> is a sum of integers each representing a UMTS
band (in other words bit mask)
1 –UMTS_BAND_1
2 –UMTS_BAND_2
4 –UMTS_BAND_3
8 –UMTS_BAND_4
16 –UMTS_BAND_5
32 –UMTS_BAND_6
64 –UMTS_BAND_7
128 –UMTS_BAND_8
256 –UMTS_BAND_9
<LTEbandH>: integer type <LTEbandH> is a sum of integers each representing a TDD
LTEband (in other words bit mask)
32 –TDLTE_BAND_38
64 –TDLTE _BAND_39
128 –TDLTE _BAND_40
256 –TDLTE _BAND_41
<LTEbandL> integer type <LTEbandL>is a sum of integers each representing a FDDers each representing a TDDLTEband (in other words bit mask)
32 –TDLTE_BAND_38
64 –TDLTE _BAND_39
128 –TDLTE _BAND_40
256 –TDLTE _BAND_41
<LTEbandL> integer type
<LTEbandL>is a sum of integers each representing a FDD
1 –FDDLTE_BAND_1
4 –FDDLTE _BAND_3
8 –FDDLTE _BAND_4
64– FDDLTE _BAND_7
65536 –FDDLTE _BAND_17
524288 –FDDLTE _BAND_20
<roamingConfig>: integer value
0 –not support
1 –support
2 –no change
<srvDomain>: integer value
0 –CS only
1 –PS only
2 –CS and PS
3 –ANY
4 –no change
<bandPriorityFlag>
0 –default
1 –TD-LTE
2 –FDD-LTE
AT*BAND=6,0,0,0,4
how to get the syntax correct please? That is the bit operations for bands
Ignore bit operations. The text states:
integer type is a sum of integers each representing a GSM band
So for example if you want to support UMTS bands 1. 4 and 9: then you see that 1 –UMTS_BAND_1 with 8 –UMTS_BAND_4 with 256 –UMTS_BAND_9 so you add the numbers 1 + 8 + 256 = 265 and you send the value 265.
Anyway, if you would convert the numbers to binary:
0b000001 –UMTS_BAND_1
0b000010 –UMTS_BAND_2
0b000100 –UMTS_BAND_3
0b001000 –UMTS_BAND_4
... etc. ...
Then you can see that each number has s single bit set. Addition of such numbers is equal to AND bit masking such numbers, as each bit is unqiue..

Find out if an object on a specific address is a pointer

I Have a PC Program that is communicating over a TCP/IP Connection to an Embedded board (Infineon XE169 (C166 Family)).
This PC Program request what data is stored on a certain address.
The PC Program is uC/Probe, and I cannot change how this program is working.
uC/Probe for example sends this message:
____________________________________________________________________________________________________________
| Prefix | Length |Pkt_nr|Unused| Format | read size | Address to read |Unused|Postfix|
|--------------------|-----------|------|------|-----------|-----------|----------------------|------|-------|
|0x75 0x43 0x50 0x72 | 0x00 0x08 | 0x00 | 0x00 | 0x02 0x00 | 0x04 0x00 | 0xDC 0x3E 0x61 0x00 | 0x00 | 0x2F |
|u C P r | 8 | 0 | 0 | 2 | 4 | 0x613EDC | 0 | / |
|____________________|___________|______|______|___________|___________|______________________|______|_______|
This is a message to request the data from address 0x613EDC and read 4 bytes from there.
When looking in the .map file I can see that at this location the OSTCBCurPtr variable is placed.
This variable is an OS_TCB* thus at the requested address is the address placed where this variable is pointing to.
I've now manually looked in the .map file what kind of variable is placed on the address. But can I get the variable type trough the C code on the Embedded board. All I want to know is if the object that lies on that specific location is a pointer or not, if it's an uint16_t, uint8_t, char or whatever is unimportant to me.
Background information, why I want to know this
The Embedded board will sent back the requested data to the uC/Probe program. But the pointers are stored in a strange way in the XE169 chip.
The pointer of above example is for example stored like this:
_______________________________________
| Address | 0 | 1 | 2 | 3 |
|-----------|------|------|------|------|
|0x00613EDC | 0xE6 | 0x1F | 0x84 | 0x01 |
|___________|______|______|______|______|
Because the value's are stored little endian this would result in the number
0x01841FE6.
This number is currently send back to uC/Probe. But his number isn't the correct location of the, a little calculation has to be done to get to the actual address location.
We have to take apart this 32bits number and split it into 2 16 bit numbers.
Then we get:
Hex: 0x0184 and 0x1FE6
Bits: 0b0000000110000100 and 0001111111100110
Now the 16 upper bits have to move 2 bits to the right. The 2 least significant bits of these upper 16 bits become the 2 most significant bits on the lower 16 bits.
This results into:
Hex: 0x0061 and 0x1FE6
Bits: 0b0000000001100001 and 0001111111100110
When we paste these 2 16 bit numbers back to the 32 bit number we have the address where the pointer is pointing to:
0x00611FE6
And this is the number I have to sent back to uC/Probe.
This calculation only has to happen for when uC/Probe requests pointers, for non pointers it just needs to send back the data read from the given address.
That's why I need to know if the requested data is a pointer, hopefully someone can help me with this.

What does (size + 7) & ~7 mean?

I'm reading the Multiboot2 specification. You can find it here. Compared to the previous version, it names all of its structures "tags". They're defined like this:
3.1.3 General tag structure
Tags constitutes a buffer of structures following each other padded on u_virt size. Every structure has
following format:
+-------------------+
u16 | type |
u16 | flags |
u32 | size |
+-------------------+
type is divided into 2 parts. Lower contains an identifier of
contents of the rest of the tag. size contains the size of tag
including header fields. If bit 0 of flags (also known as
optional) is set if bootloader may ignore this tag if it lacks
relevant support. Tags are terminated by a tag of type 0 and size
8.
Then later in example code:
for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
+ ((tag->size + 7) & ~7)))
The last part confuses me. In Multiboot 1, the code was substantially simpler, you could just do multiboot_some_structure * mss = (multiboot_some_structure *) mbi->some_addr and get the members directly, without confusing code like this.
Can somebody explain what ((tag->size + 7) & ~7) means?
As mentioned by chux in his comment, this rounds tag->size up to the nearest multiple of 8.
Let's take a closer look at how that works.
Suppose size is 16:
00010000 // 16 in binary
+00000111 // add 7
--------
00010111 // results in 23
The expression ~7 takes the value 7 and inverts all bits. So:
00010111 // 23 (from pervious step)
&11111000 // bitwise-AND ~7
--------
00010000 // results in 16
Now suppose size is 17:
00010001 // 17 in binary
+00000111 // add 7
--------
00011000 // results in 24
Then:
00011000 // 24 (from pervious step)
&11111000 // bitwise-AND ~7
--------
00011000 // results in 24
So if the lower 3 bits of size are all zero, i.e. a multiple of 8, (size+7)&~7 sets those bits and then clears them, so no net effect. But if any one of those bits is 1, the bit corresponding to 8 gets incremented, then the lower bits are cleared, i.e. the number is rounded up to the nearest multiple of 8.
~ is a bitwise not. & is a bitwise AND
assuming 16 bits are used:
7 is 0000 0000 0000 0111
~7 is 1111 1111 1111 1000
Anything and'd with a 0 is 0. Anything and'd with 1 is itself. Thus
N & 0 = 0
N & 1 = N
So when you AND with ~7, you essentially clear the lowest three bits and all of the other bits remain unchanged.
Thanks for #chux for the answer. According to him, it rounds the size up to a multiple of 8, if needed. This is very similar to a technique done in 15bpp drawing code:
//+7/8 will cause this to round up...
uint32_t vbe_bytes_per_pixel = (vbe_bits_per_pixel + 7) / 8;
Here's the reasoning:
Things were pretty simple up to now but some confusion is introduced
by the 16bpp format. It's actually 15bpp since the default format is
actually RGB 5:5:5 with the top bit of each u_int16 being unused. In
this format, each of the red, green and blue colour components is
represented by a 5 bit number giving 32 different levels of each and
32786 possible different colours in total (true 16bpp would be RGB
5:6:5 where there are 65536 possible colours). No palette is used for
16bpp RGB images - the red, green and blue values in the pixel are
used to define the colours directly.
& ~7 sets the last three bits to 0

Need explain a code in embedded program

I am completely new to embedded programming, I'm examining the code below and trying to understand how it work, but I really got stuck.
The program is used to count and print out the numbers from 0 to 9.
So can someone please explain the line const uint8_t ? why do I need an array of heximal number here?
#include <avr/io.h>
#include <util/delay.h>
#include "debug.h"
const uint8_t segments[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6};
int main(void) {
uint8_t i=0; //s
int g;
init_debug_uart0();
/* set PORT A pins as outputs */
DDRA = 0xFF;
for (;;) {
PORTA = segments[i];
printf("%d\n\r",i);
_delay_ms(1000);
if (i >=9) {
fprintf(stderr , "Count Overflow\n\r"); i = 0;
scanf("%d", &g);
}else
i++;
}
}
And a final question, does anyone know good sources to read about embedded programming? Currently i'm learning about the IIMatto, 8-bits processor and it has 32-registers, designed in Harvard architecture and has 1 level pipeline.
The const uint8_t segments[10] = {0xFC,0x60,0xDA, ... simple defines a constant 10-byte array of bytes.
Code does not need an array of hexadecimal, it could have been decimal.
But consider the benefit of
0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6
// versus
252,96,218,...
A casual inspection shows that the number of bits set in each byte is
6,2,5,5,...
This just happens to match the number of segments set in a 7-segment display of the digits 0,1,2,3 ...
Closer inspection of the bits set will detail which bit activate what segment.
Other methods could be employed to get this mapping of 7-segment to digit, but showing the data in hexadecimal is one step closer than decimal.
Perhaps code could be like (the proper segment mapping is TBD).
typedef enum {
LED7_a = 1 << 0,
LED7_b = 1 << 1,
LED7_c = 1 << 2,
LED7_d = 1 << 3,
LED7_e = 1 << 4,
LED7_f = 1 << 5,
LED7_g = 1 << 6,
LED7_dp = 1 << 7
} LED7_Segment_t;
/* ****************************************************************************
7 Segment Pattern
Layout
aaa
f b
f b
ggg
e c
e c
ddd dp
**************************************************************************** */
const uint8_t segments[] = {
/*'0*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f ,
/*'1*/ LED7_b | LED7_c ,
/*'2*/ LED7_a | LED7_b | LED7_d | LED7_e | LED7_g,
/*'3*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_g,
/*'4*/ LED7_b | LED7_c | LED7_f | LED7_g,
/*'5*/ LED7_a | LED7_c | LED7_d | LED7_f | LED7_g,
/*'6*/ LED7_a | LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
/*'7*/ LED7_a | LED7_b | LED7_c ,
/*'8*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
/*'9*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_f | LED7_g};
First of all, ask yourself where is segments used, what is it used for, how is it used?
Hints:
Where: Used to assign a value to PORTA
What: PORTA Is an output from an embedded system. Perhaps to an external device. segments is used to store outputs.
How: Each time around the loop, the value i is incremented. i is used as the index for segments when its value is assigned to PORTA.
Also: A hexadecimal number, specifically 2 digits long, is a byte which is 8 bits. Look on your microcontroller for up to 8 pins labelled "PORTA"
When writing to PORTA (an I/O port) you are concerned with the state of individual I/O lines associated with each bit.
To display a specific set of segments representing a digit on a 7-segment display, you have to write a specific bit pattern - one bit for each segment you wish to light. The segments array is indexed by the digit you want to display, and the value at that index represents the bit pattern on PORTA required to light the segments that represent that digit.
The reason hexadecimal is used is because there is a direct mapping of single hexadecimal digit to exactly four binary digits, so hex is a compact way of representing bit patterns. For an experienced embedded developer, mentally converting a bit-pattern to hex and vice versa becomes second nature. If the values were decimal, the representation would bear no direct relationship to the bit pattern, and the conversion or mental visualisation of the bit pattern less simple.
The hex digit to binary pattern conversion is as follows:
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111
0xFC = 11111100
0x60 = 1100000
0xDA = 11011010
....
you need an array of hex numbers, most probably you have connected some sort of device to portA, and in this device
0xFC or 11111100 means display 0,(when portA pins 7,6,5,4,3,2, are high and 1,0 are low this device will display 0
0x60 or 11000000 means display 1(when PortA pins 7,6 are high and the rest low, this device will display 1.
and so on..
The memory locations in the microcontroller are 8 bits wide so 16 I/O will require two 8 bit registers called PORTA and PORTB. in your case its only 8bits wide ie. 8 I/O pins per PORTA, another 8 for PORTB and so on.
the outputs of these ports are controlled by the 8bits..
Suppose we wish to turn on an LED which we are going to connect to bit 4 on PORTB. We first of all have to instruct the microcontroller to ensure that PORTB bit 4 is an output.(the micro needs to know if ports are outputs are inputs you cant just plug stuff in)
in a pic micro you would say TRIA = 0x00010000 this tell the micro portB4 is an output.Now that we have said its an output, PORTA = 0b00010000 sets this portB4 to a high voltage, in other words this will illuminate the LED or whatever you have connected to the port.
PORTA = 0b00000000 // turns off PORTA outputs,
PORTA = 0b10000000 // turns on PORTA pin 7
The hexadecimal values its just a notation, the first letter represents the first 4 bits of your int and the other the other four bits because you are declaring a const uint8 variable wich means an unsigned integer of 8 bits, this is an integer but without sign, the bit of the sign is removed, so it can store 2^8 posibles values.
I'm just answering the first question. Hope it help!!

Converting 8 bits to a scaled 12 bits equivalent

I need to convert an 8 bit number (0 - 255 or #0 - #FF) to its 12 bit equivalent (0 - 4095 or #0 - #FFF)
I am not wanting to do just a straight conversion of the same number. I am wanting to represent the same scale, but in 12 bits.
For example:-
0xFF in 8 bits should convert to 0xFFF in 12 bits
0x0 in 8 bits should convert to 0x0 in 12 bits
0x7F in 8 bits should convert to 0x7FF in 12 bits
0x24 in 8 bit should convert to 0x249 in 12 bits
Are there any specific algorithms or techniques that I should be using?
I am coding in C
Try x << 4 | x >> 4.
This has been updated by the OP, changed from x << 4 + x >> 4
If you are able to go through a larger domain then this may help:
b = a * ((1 << 12) - 1) / ((1 << 8) - 1)
It is ugly but preserves scaling almost as requested. Of course you can put constants.
What about:
x = x ?((x + 1) << 4) - 1 :0
I use mathematical equation y=mx+c
Assuming low range of values is zero.
You can scale your data by a factor of m (Multiple for increasing range and divide for decreasing)
Ex.
My ADC data was 12 bit. Range in integer =0 to 4095
I want to shrink this data in range 0 to 255.
m=(y2-y1/x2-x1)
m=(4095-0/255-0)
m=16.05 = 16
So data received in 12 bits is divided by 16 to convert to 8 bits.
This conversion is linear in nature.
Hope this is also a good idea.
Image Link

Resources