Construct 4-byta data from int - arrays

I have a device (hardware I cannot modify) that I have to communicate with data bytes. The problem I am experiencing is that I cannot simply send value converted to byte. As an example, I have value of 23, that has to be converted into the 4-byte command:
byte[0] -> MSB
byte[1] -> Mid Hi
byte[2] -> Mid Lo
byte[3] -> LSB
I cannot simply convert 25 -> 0x19 and use it like that. I am not a person who understands much of a lower-level language, I am truly trying to learn, but I know I have to shift bytes. My assumption is something like this:
int value = 23;
byte[0] = (value >> 24) & 0xFF;
byte[1] = (value >> 16) & 0xFF;
byte[2] = (value >> 8) & 0xFF;
byte[3] = value & 0xFF;
Is this correct? Will this produce outcome I am looking for? As an example how would you translate FF FF FF FB back to INT (based on the description above):
MSB: ff
Mid Hi: ff
Mid Lo:: ff
LSB: fb
What does this represent?

Related

Can anyone explain to me what this shifting means under this circumstance: uint16_t register0 = (instruction >> 9) & 0x7

I'm trying to write a VM (LC-3), and on this ADD instruction I encountered this statement. Basically the "register0" is the DR register, but I don't really understand what is actually shifting and why 9. Also the AND operator with the 0x7 value.
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
| 0001 | DR | SR1 |0| 00| SR2 |
Could anyone please explain it to me in detail?
ADD {
/* destination register (DR) */
uint16_t r0 = (instr >> 9) & 0x7;
/* first operand (SR1) */
uint16_t r1 = (instr >> 6) & 0x7;
/* whether we are in immediate mode */
uint16_t imm_flag = (instr >> 5) & 0x1;
if (imm_flag) {
uint16_t imm5 = sign_extend(instr & 0x1F, 5);
reg[r0] = reg[r1] + imm5;
} else {
uint16_t r2 = instr & 0x7;
reg[r0] = reg[r1] + reg[r2];
}
update_flags(r0);
}
What it's doing is isolating the 3 bits that represent the DR register so they become a standalone number.
Let's say the entire sequence looks like this:
1110101101101011
^^^
DR
Shifting 9 bits right gives this:
1110101
and & 0x7 (bitwise AND) isolates the 3 lowest bits:
101
Similar operations are performed to isolate the values of SR1 and the immediate mode flag. Depending on that flag, SR2 may also be required, but as it's already in the lowest 3 bits, no shifting is needed.

CRC16 CCITT code - how to adapt manufacturer sample source

I try to create a code that would read data from RFID reader module. In order to do this I need to do CRC16 CCITT calculation.
I have found C source code for the CRC16 checksum calculation in the reader manufacturer application technical datasheet http://www.card-sys.com/manuals/framer_eng.pdf
Unfortunately this is just a part of code not a full working example.
When the RFID reader is put in automatic mode, it automatically sends 11 bytes every time it reads a tag. CRC - this value is calculated using all of the bytes except the last two bytes which are the CRCH (CRC high byte) and CRCL (CRC low byte).
When I read RFID tag from a reader I got 11 bytes transferred... i.e. (hex) 01 0B 03 01 06 87 DB C7 FF E5 68. Last two bytes E5 68 are the CRC16 checksum for the message. In order to confirm the data is OK I need to calculate the same CRC16 against 01 0B 03 01 06 87 DB C7 FF at the destination point.
I tried putting everything together in one piece, but I do not have much experience with C programing and my code does not work.
Here is the source code:
#include <stdio.h>
#include <stdlib.h>
// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
int i, byte;
unsigned short C;
*CRC = 0;
for (byte = 1; byte <= Bytes; byte ++, Data ++)
{
C = ((*CRC >> 8) ^ *Data) << 8;
for (i = 0; i < 8; i ++)
{
if (C & 0x8000)
C = (C << 1) ^ 0x1021;
else
C = C << 1;
}
*CRC = C ^ (*CRC << 8);
}
}
int main(void)
{
puts("Test...");
unsigned char * Data16="10ac0501ff";
unsigned short * CRC=0;
unsigned char Bytes16=4;
CRC16(Data16,CRC,Bytes16);
puts(CRC);
return EXIT_SUCCESS;
}
What I would like to do is learn how to use manufacturer code in working example - means how to get crc16 calculated.
Could you please help me with this? Thanks.
Using your source code I created the following program.
#include <stdio.h>
#include <stdlib.h>
// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
int i, byte;
unsigned short C;
*CRC = 0;
for (byte = 1; byte <= Bytes; byte++, Data++)
{
C = ((*CRC >> 8) ^ *Data) << 8;
for (i = 0; i < 8; i++)
{
if (C & 0x8000)
C = (C << 1) ^ 0x1021;
else
C = C << 1;
}
*CRC = C ^ (*CRC << 8);
}
}
int main(void)
{
// When I read RFID tag from a reader I got 11 bytes transferred... i.e.
// (hex)01 0B 03 01 06 87 DB C7 FF E5 68.
// Last two bytes E5 68 are crc16.
// In order to confirm the data is OK I need to calculate the same crc16
// against 01 0B 03 01 06 87 DB C7 FF at the destination point.
unsigned char Data16[] = { 0x01, 0x0B, 0x03, 0x01, 0x06, 0x87, 0xDB, 0xC7, 0xFF };
unsigned short CRC = 0;
unsigned char Bytes16 = 9;
CRC16(Data16, &CRC, Bytes16);
printf(" CRC calculated is %x\n", CRC);
return EXIT_SUCCESS;
}
The output is CRC calculated is e568.
There are a couple of changes I made.
First is the data I used which is from your comment on the RFID tag reader output.
When I read RFID tag from a reader I got 11 bytes transferred... i.e.
(hex) 01 0B 03 01 06 87 DB C7 FF E5 68. Last two bytes E5 68 are
crc16. In order to confirm the data is OK I need to calculate the same
crc16 against 01 0B 03 01 06 87 DB C7 FF at the destination point. You
are probably right about the Data16[]... I will change this later
today and let you know what current status is. Thanks for helping :)
I used a length of the data that excludes the checksum. So the length in the frame data is 0x0B or 11 and since the checksum is 2 bytes, I used 11 - 2 or 9 for the length.
Finally I changed the definition of the variable CRC to unsigned short CRC = 0; and when calling the CRC function, I used the address of operator as in CRC16(Data16, &CRC, Bytes16);.
Frame format for serial transmission
From the documentation you referenced there are two types of frames or messages whose formats are as follows:
Command frame:
module address (1 byte) unique address of each module in network
frame length (1 byte) full length of frame (includes 2 byte checksum)
command (1 byte) command code which is an even value
parameters (variable length) optional parameters depending on command
CRCH (1 byte) upper byte of the CRC16
CRCL (1 byte) lower byte of the CRC16
Answer frame:
module address (1 byte) unique address of each module in network
frame length (1 byte) full length of frame (includes 2 byte checksum)
answer(1 byte) answer code which is an odd value
parameters (variable length) optional parameters depending on command
operation code (1 byte) command execution status
CRCH (1 byte) upper byte of the CRC16
CRCL (1 byte) lower byte of the CRC16

How I get the value from the Immediate part of a 32 Bit sequence in C?

I built a virtual machine in C. And for this I have the Instruction
pushc <const>
I saved the command and the value in 32 Bit. The First 8 Bit are for the command and the rest for the value.
8 Bit -> Opcode
24 Bit -> Immediate value
For this I make a macro
#define PUSHC 1 //1 is for the command value in the Opcode
#define IMMEDIATE(x) ((x) & 0x00FFFFFF)
UPDATE:
**#define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))**
Then I load for testing this in a unsigned int array:
Update:
unsigned int code[] = { (PUSHC << 24 | IMMEDIATE(2)),
(PUSHC << 24 | SIGN_EXTEND(-2)),
...};
later in my code I want to get the Immediate value of the pushc command and push this value to a stack...
I get every Instruction (IR) from the array and built my stack.
UPDATE:
void exec(unsigned int IR){
unsigned int opcode = (IR >> 24) & 0xff;
unsigned int imm = (IR & 0xffffff);
switch(opcode){
case PUSHC: {
stack[sp] = imm;
sp = sp + 1;
break;
}
}
...
}
}
Just use a bitwise AND to mask out the lower 24 bits, then use it in the case:
const uint8_t opcode = (IR >> 24) & 0xff;
const uint32_t imm = (IR & 0xffffff);
switch(opcode)
{
case PUSHC:
stack[sp] = imm;
break;
}
I shifted around the extraction of the opcode to make the case easier to read.

Convert Bytes to Int / uint in C

I have a unsigned char array[248]; filled with bytes. Like 2F AF FF 00 EB AB CD EF .....
This Array is my Byte Stream which I store my Data from the UART (RS232) as a Buffer.
Now I want to convert the bytes back to my uint16's and int32's.
In C# I used the BitConverter Class to do this. e.g:
byte[] Array = { 0A, AB, CD, 25 };
int myint1 = BitConverter.ToInt32(bytes, 0);
int myint2 = BitConverter.ToInt32(bytes, 4);
int myint3 = BitConverter.ToInt32(bytes, 8);
int myint4 = BitConverter.ToInt32(bytes, 12);
//...
enter code here
Console.WriteLine("int: {0}", myint1); //output Data...
Is there a similiar Function in C ? (no .net , I use the KEIL compiler because code is running on a microcontroller)
With Regards
Sam
There's no standard function to do it for you in C. You'll have to assemble the bytes back into your 16- and 32-bit integers yourself. Be careful about endianness!
Here's a simple little-endian example:
extern uint8_t *bytes;
uint32_t myInt1 = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);
For a big-endian system, it's just the opposite order:
uint32_t myInt1 = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];
You might be able to get away with:
uint32_t myInt1 = *(uint32_t *)bytes;
If you're careful about alignment issues.
Yes there is. Assume your bytes are in:
uint8_t bytes[N] = { /* whatever */ };
We know that, a 16 bit integer is just two 8 bit integers concatenated, i.e. one has a multiple of 256 or alternatively is shifted by 8:
uint16_t sixteen[N/2];
for (i = 0; i < N; i += 2)
sixteen[i/2] = bytes[i] | (uint16_t)bytes[i+1] << 8;
// assuming you have read your bytes little-endian
Similarly for 32 bits:
uint32_t thirty_two[N/4];
for (i = 0; i < N; i += 4)
thirty_two[i/4] = bytes[i] | (uint32_t)bytes[i+1] << 8
| (uint32_t)bytes[i+2] << 16 | (uint32_t)bytes[i+3] << 24;
// same assumption
If the bytes are read big-endian, of course you reverse the order:
bytes[i+1] | (uint16_t)bytes[i] << 8
and
bytes[i+3] | (uint32_t)bytes[i+2] << 8
| (uint32_t)bytes[i+1] << 16 | (uint32_t)bytes[i] << 24
Note that there's a difference between the endian-ness in the stored integer and the endian-ness of the running architecture. The endian-ness referred to in this answer is of the stored integer, i.e., the contents of bytes. The solutions are independent of the endian-ness of the running architecture since endian-ness is taken care of when shifting.
In case of little-endian, can't you just use memcpy?
memcpy((char*)&myint1, aesData.inputData[startindex], length);
char letter = 'A';
size_t filter = letter;
filter = (filter << 8 | filter);
filter = (filter << 16 | filter);
filter = (filter << 32 | filter);
printf("filter: %#I64x \n", filter);
result: "filter: 0x4141414141414141"

Binary 0000 to FFFF using C

I am trying to program using C to write binary data to a .bin file and just iterate through to write from 0000 to FFFF. I figured I would use fopen with a 'wb' tag and then be able to write binary data but I'm unsure how to iterate from 0000 to FFFF using C. Thanks for any help.
Here's my code now:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f = fopen("binary.bin", "wb");
unsigned long i;
//if(f == NULL) { ...error handling... }
for(i = 0x0000; i <= 0xFFFF; i++){
// Write something to the file, e.g. the 16-bit (2 byte) value of "i"
unsigned short someData = i;
fwrite(&someData, 1, 2, f);
}
fclose(f);
return 0;
//printf("Hello World\n");
getchar();
}
This will output 00 00 01 00 02 00 ...
Here's my question now. Isn't this supposed to read out 00 00 00 01 00 02...Shouldn't there be an extra '00' at the beginning?
Also, I've been trying to see how could I copy it and extend it therefore making it 0000 0000 0001 0001 etc?
[Update: I just copied the fwrite line and did it again and it solved this problem]
This is a simple example of writing some binary numbers to a file.
FILE *f = fopen("yourfile", "wb");
if(f == NULL) { ...error handling... }
for(unsigned long i = 0x0000; i <= 0xFFFF; ++i)
{
// Write something to the file, e.g. the 16-bit (2 byte) value of "i"
unsigned short someData = i;
fwrite(&someData, 1, 2, f);
}
fclose(f);
Note that the variable i here must be bigger than 16-bit so that it does not wrap around (see my comments on the other answers). The long type guarantees a size of at least 32 bit.
for (int i = 0x0000; i <= 0xffff; ++i)
To loop from 0 to 0xffff, both inclusive, you do:
for (i=0; i <= 0xffff; ++i)
Now, the first interesting question is, what should be the type of i? In C, an unsigned int is guaranteed to hold values in the range [0, 0xffff], which means that i <= 0xffff will always be true for unsigned int i; if UINT_MAX is 0xffff. so i can't be a type of size smaller or equal to unsigned int. long or unsigned long is the smallest type guaranteed to be able to store 0xffff + 1 portably. So, we need i to be of unsigned long or long type. In C99, you can make things easier by including stdint.h and then using uint32_t type.
The second interesting question is, what do you want to write? Is your file's layout going to be:
00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07
...
FF F8 FF F9 FF FA FF FB FF FC FF FD FF FE FF FF
or do you want to write values to a file using your favorite data type above and then be able to read them back again quickly? For example, if int is 32 bits, and your system is little-endian, writing those values will give you a file such as:
00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 ...
If you want the first, you have to make sure you write two bytes per number, in the correct order, and that endian-ness of your OS doesn't affect the output. The easiest way to do so is probably something like this:
for (i=0; i <= 0xff; ++i) {
unsigned char values[2];
values[0] = (i & 0xff00) >> 8;
values[1] = i & 0xff;
fwrite(values, 1, 2, fp);
}
If you want the second, your life is easier, particularly if you don't care about endian-ness:
for (i=0; i <= 0xff; ++i) {
fwrite(&i, sizeof i, 1, fp);
}
will write your values so you can read them back on the same system with the same kind of variable.
for (i = 0x0000; i <= 0xFFFF; ++i)
To control the Endianess of your output, you will have to write the bytes (octets) yourself:
for (unsigned int i = 0; // Same as 0x0000
i <= 0xFFFF;
++i)
{
unsigned char c;
c = i / 256; // In Big Endian, output the Most Significant Byte (MSB) first.
fputc(/*...*/);
c = i % 256;
fputc(/*...*/);
}
This is a preferred method when the file must be Big Endian. This will ensure the byte ordering regardless of the processor's endianess. This can be adjusted to output in Little Endican as well.
Alternate method for portably writing bytes in big endian style: check out htons and htonl (and their inverses).
These convert from whatever format your machine uses (Intel chips are little endian, as several people have pointed out) into "Network" order (big endian). htons does this in 16-bit words; htonl in 32-bit words. As an added benefit, if your program is on a Big Endian machine, these compile out to no-ops. They're defined in <arpa/inet.h> or <netinet/in.h>, depending on the system.
BSD (and Linux) also provide(s) a collection of routines named things like htobe16 (host to big endian 16-bit) in <endian.h>.
These also help save the overhead of writing one byte at a time.
If you do want to extract high bytes / low bytes yourself, you probably should also use bit masking to do it. Your compiler might be smart enough to convert divide/modulo into bit masks, but if it doesn't, you'll have deplorable performance (division is slow).
{
unsigned int x = 0xdead;
unsigned char hi = (x & 0xff00) >> 8;
unsigned char lo = (x & 0x00ff);
}
{
unsigned long int x = 0xdeadbeef;
unsigned char by0 = (x & 0xff000000) >> 24;
unsigned char by1 = (x & 0x00ff0000) >> 16;
unsigned char by2 = (x & 0x0000ff00) >> 8;
unsigned char by3 = (x & 0x000000ff);
}
(It looks like gcc is smart enough to do the optimization out of the division, though… nice.)

Resources