When I run the following code
#include <stdio.h>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
const uint8_t Symbols[] = {
0xCA,0x04,// size
0x0B, // width
0x0B, // height
0x00, // first char
0x04, // char count
0x01, 0x02, 0x03, 0x04,// char widths
// font data
0x00, 0x00, 0x20, 0x00, 0xF0, 0x07, 0x08, 0x04, 0x84, 0x07, 0x84, 0x07, 0x84, 0x07, 0x0E, 0x04, 0xF0, 0x07, 0x20, 0x00, 0x00, 0x00, // 0
0x10, 0x01, 0x08, 0x01, 0x04, 0x01, 0x04, 0x01, 0x08, 0x01, 0x10, 0x01, 0x10, 0x01, 0x08, 0x01, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, // 1
0x18, 0x00, 0xFF, 0x07, 0x18, 0x00, 0x00, 0x00, 0x80, 0x01, 0xFF, 0x07, 0x80, 0x01, 0x00, 0x00, 0x0C, 0x00, 0xFF, 0x07, 0x0C, 0x00, // 2
0x00, 0x02, 0x80, 0x05, 0x60, 0x04, 0x18, 0x04, 0x04, 0x04, 0x72, 0x05, 0x04, 0x04, 0x18, 0x04, 0x60, 0x04, 0x80, 0x05, 0x00, 0x02 // 3
};
typedef struct
{
uint16_t size; //2
uint8_t width; //1
uint8_t height; //1
uint8_t first_char; //1
uint8_t char_count; //1
uint8_t *font_widths;
uint8_t *font_data;
} _graphics_font;
_graphics_font* test;
uint8_t* font_st;
uint8_t temp;
int main(void)
{
test = (_graphics_font*)&Symbols;
font_st = (uint8_t*)&test->font_widths;
temp = font_st[0]+font_st[1]+font_st[2]+font_st[3]; //1+2+3+4 = 10
printf("temp=%d",temp);
return 0;
}
in C, I'm expecting that the pointer font_st will point exactly after the 6-th Byte of the Symbols array. Therefore the result printed should be 10. Instead of that the pointer is allocated to the 9-th byte, missing every time 2 bytes and wrongly to my expectations is printing 7 as a result. Why and how could that be?
Important update is that the using instead the line:
temp = font_st[-2]+font_st[-1]+font_st[0]+font_st[1]; //1+2+3+4 = 10
works.
This behaviour is most likely caused by struct padding.
Try the following:
#include <stdio.h>
#pragma pack(push, 1)
.... (all other code)
#pragma pack(pop)
As to the location of single elements in a struct, read about padding and packing, e.g. Structure padding and packing.
You could try it like this:
typedef struct glyph {
uint8_t char_width;
uint8_t[] glyph_data;
} glyph_t;
typedef struct font_t {
uint16_t size; //2
uint8_t width; //1
...
glyph_t[] glyphs;
} font_t;
That way, you can avoid some issues you are facing due to the dynamic addresses of the data, i.e. those which depend on the value of char_count.
Of course, if the size of glyph_data is not a constant, you have to provide your own access logic, like
uint8_t* p_glyph = (uint8_t*)(font->glyph_data[0]);
for ( int i = 0; i < requiredCharIndex; i++ ) {
p_glyph += total_size_of_glyph_in_bytes( (glyph_t*)p_glyph );
}
glyph_t* result = (glyph_t*)p_glyph;
test = (_graphics_font*)Symbols;
font_st = (uint8_t*)test->font_widths;
I didn't check that, but at simple sight I would say that &s was wrong in that context. Symbols and test are already pointers, so you are referencing to the address to that pointers.
You are not initializing correctly the two pointers in your struct.
test = (_graphics_font*)&Symbols;
On this line you are copying byte by byte from Symbols to test, which means that font_widths will point to the address made up by combining 0x01, 0x02, 0x03, 0x04, which contains garbage data.
Why 4 bytes? because every pointer in C has a size of 4 bytes regardless of the data it is pointing to.
Moreover, font_data will have the same behaviour.
Solution:
You have to use memcpy:
test->font_widths = (uint8_t*)memcpy(test->font_widths, Symbols + 6, 4*sizeof(uint8_t));
The same goes for font_data.
Related
In Libtomcrypt crypto library, AES encryption/decryption are implemented in two different way .
Use of lookup table of size 8KB (encryption)/5KB (decryption).
Use of lookup table of size 2KB (encryption)/2KB (decryption). In this case LTC_SMALL_CODE is true.
This is the source code of aes_tab.c and aes.c.
#ifdef LTC_SMALL_CODE
#define Te0(x) TE0[x]
#define Te1(x) RORc(TE0[x], 8)
#define Te2(x) RORc(TE0[x], 16)
#define Te3(x) RORc(TE0[x], 24)
#define Td0(x) TD0[x]
#define Td1(x) RORc(TD0[x], 8)
#define Td2(x) RORc(TD0[x], 16)
#define Td3(x) RORc(TD0[x], 24)
#define Te4_0 0x000000FF & Te4
#define Te4_1 0x0000FF00 & Te4
#define Te4_2 0x00FF0000 & Te4
#define Te4_3 0xFF000000 & Te4
#else
#define Te0(x) TE0[x]
#define Te1(x) TE1[x]
#define Te2(x) TE2[x]
#define Te3(x) TE3[x]
#define Td0(x) TD0[x]
#define Td1(x) TD1[x]
#define Td2(x) TD2[x]
#define Td3(x) TD3[x]
#endif /* ENCRYPT_ONLY */
#endif /* SMALL CODE */
The following C code performs AES encryption and decryption using libtomcrypt crypto library.
However, the code invokes AES implementation that uses 8KB/5KB lookup table
(means LTC_SMALL_CODE condition becomes false).
//aes_tom_example.c
#include <tomcrypt.h>
static const unsigned char key[] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
int main()
{
unsigned char text[]="hello world!";
unsigned char enc_out[80];
unsigned char dec_out[80];
symmetric_key skey;
int keysize = 32;
int status;
status = aes_keysize(&keysize);
status = aes_setup(key, 32, 0, &skey);
status = aes_ecb_encrypt(text,enc_out,&skey);
status = aes_ecb_decrypt(enc_out, dec_out, &skey);
int i;
printf("original:\t");
for(i=0;*(text+i)!=0x00;i++)
printf("%c ",*(text+i));
printf("\nencrypted:\t");
for(i=0;*(enc_out+i)!=0x00;i++)
printf("%X ",*(enc_out+i));
printf("\ndecrypted:\t");
for(i=0;*(dec_out+i)!=0x00;i++)
printf("%c ",*(dec_out+i));
printf("\n");
return 0;
}
Compile and run as below ,
gcc aes_tom_example.c -o aes -ltomcrypt
./aes
Sample Output
original: h e l l o w o r l d !
encrypted: AE 21 D5 A5 5E D5 F1 EF 6D FC E5 30 60 34 3D 12
decrypted: h e l l o w o r l d !
My questions are:
How to modify this C code so that it invokes the #ifdef LTC_SMALL_CODE condition part (means 2KB lookup table based implementation code invoked )?
How to run the above code with LTC_SMALL_CODE condition true?
Do I need some parameter before calling SETUP (aes_setup) function ? Or Do I need to pass some parameters at the time of compilation/run time?
It would be great if anyone can provide some link or sample code.
I am using Ubuntu 16.04 / Debian 8. gcc v-4.9.
typedef struct BO2Offsets
{
struct Prestige
{
u32 offset = 0x000000;
char data[13] = { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C
};
};
} BO2Offsets;
This is a very amateur question with what I'm sure is going to be a very simple answer, but I can't resolve the problem. I have a .h file with his corresponding .cpp file, but for some reason whenever I try to compile with gcc, I keep getting errors:
declaration does not declare anything // line 10
expected ':', ',', ';', '}' or 'attribute' before '=' token // line 5
I would like use BO2Offsets like that:
BO2Offsets BO2;
BO2.Prestige.offset;
EDIT2:
Resolved, thank's :)
typedef struct BO2Offsets BO2Offsets;
struct BO2Offsets
{
struct Prestige
{
u32 offset;
char data[13];
} prestige;
};
You are probably using C compiler, but the code is C++ (that too C++14). You need to change the compiler (or toolset), or change the code so that it compiles with C compiler.
EDIT: Which line? Does it say struct Prestige is not utilized?
Based on your edit:
typedef struct Prestige
{
u32 offset = 0x000000;
char data[13] = { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C
};
} prestige; // Small letters
...
BO2Offsets BO2;
BO2.prestige.offset;
I've used small letters for the variable, so that it is clearly different from the type Prestige.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I know that people usually define macro with a single value, such as:
#define PIN0 0x01
but what does it mean by this one with multiple values?
#define POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
Supposedly, I need to send the packets 0x02, 0x01, 0x00.... sequentially. If not using this macro, I will probably use an array. However, the toolchain generate this macro to me but I don't know how to use this to send the packets. It doesn't look like the array definition of macro. Does anyone know how I shall use this?
Not really sure what you're asking about the packets (some more code would help) but:
char vals[] = { POWER_UP };
size_t i;
for (i = 0; i < sizeof(vals); ++i) {
/* do something with vals[i] */
}
//test.c
#define POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
POWER_UP
#only preprocessing
>gcc -E test.c
# 1 "test.c"
# 1 "<command-line>"
# 1 "test.c"
0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
As you can see it will replace the macro will your list of values.
It simply expands to 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80 whenever the POWER_UP macro is referenced.
my USART is receiving a string from a "black box" and the string contains two doubles and few hex values. The string is placed in my buffer rbuf.buf with a total size of 32 characters. Normally I receive 19 characters but few times extra erroneous characters at the end. The buffer typically looks like this (in hex):
0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x20, 0x36, 0x37, 0x2e, 0x38, 0x39, 0x20, 0x37, 0x41, 0x41, 0x20, 0x0a, 0x0d, 0x00, ...
I want to extract the two doubles 123.45 and 67.89 and have among several other examples tried following:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
...
void buffer_to_float(void)
{
static char string1[10] = "";
char *string2;
for(uint8_t i=0;i<6;i++)
{
char c = rbuf.buf[i]; // this is a char but how do I make it a pointer?
string2 = strcat ( string1, c ); // ... "char" is incompatible with "char*" ...
}
double R = atof(string2);
printf("%lf\n", R);
}
I know I'm doing something silly here but what?
I use an interrupt routine for receiving the string, should I do the extraction there or should this routine be as short/quick as possible?
Thanks for telling me how silly I am, I think I need it ;-)
You can use the sscanf function to read your two float values:
char bla[] = {0x31, 0x32, 0x33, 0x2e,
0x34, 0x35, 0x20, 0x36,
0x37, 0x2e, 0x38, 0x39,
0x20, 0x37, 0x41, 0x41,
0x20, 0x0a, 0x0d, 0x00};
float a, b;
sscanf(bla, "%f %f", &a, &b);
printf("%f %f\n", a, b);
I am getting an error message "expression must have constant value" when initializing an array of structures with an external constant integer.
File1.c:
const unsigned char data1[] =
{
0x65, 0xF0, 0xA8, 0x5F, 0x5F,
0x5F, 0x5F, 0x31, 0x32, 0x2E,
0x31, 0xF1, 0x63, 0x4D, 0x43,
0x52, 0x45, 0x41, 0x54, 0x45,
0x44, 0x20, 0x42, 0x59, 0x3A,
0x20, 0x69, 0x73, 0x70, 0x56,
// ...
};
const unsigned int data1_size = sizeof(data1);
File2.c:
const unsigned char data2[] =
{
0x20, 0x44, 0x61, 0x74, 0x61,
0x20, 0x52, 0x6F, 0x77, 0x20,
0x3D, 0x20, 0x34, 0x38, 0x12,
//...
};
const unsigned int data2_size = sizeof(data2);
Get_Byte.c:
extern const unsigned char * data1;
extern const unsigned int data1_size;
extern const unsigned char * data2;
extern const unsigned int data2_size;
struct Array_Attributes
{
const unsigned char * p_data;
const unsigned int size;
};
const struct Array_Attributes Data_Arrays[] =
{
{data1, data1_size}, // Error message is for data1_size here.
{data2, data2_size}, // Another error message generated for data2_size here.
};
I have also removed the const qualifier from the size field of Array_Attributes and get the same error message.
Why is the compiler complaining about a constant value expression when data1_size and data2_size are const unsigned int but in a different translation unit?
I want a constant array of [array address, array size] which is generated at compile time.
I am using Green Hills ccarm 4.24, on Windows XP, C language NOT C++.
C's const qualifier has little to do with what the compiler considers a constant expression, in this case. In an initializer, ie
const struct attributes attrs[] = {
{ expr1, expr2 },
...
}
expr1 and expr2 must have very specific forms to be acceptable to the compiler. The upshot of these restrictions is that the expressions can be evaluated without fetching from program variables, since these aren't in existence at compilation.
You're attempting to use data1_size and data2_size, which are not compile time constants by these rules.
By the way, the declarations
const unsigned char data1[] = { ... };
and
extern const unsigned char *data1;
are not compatible and will lead to a bug in your code. The latter should be
extern const unsigned char data1[];