Determine which variable use at runtime in Embedded C - c

There are two different makefiles for this firmware that I am working on.
Data Version 1 and Data Version 2. Both versions are using the same file called ble_communication.c in each own make file.
To differentiate between the two versions, we have two variables declared inside ble_communication.c
static uint8_t data_version1[] = {0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t data_version2[] = {0x01, 0x00, 0x00, 0x00, 0x00};
Inside the ble_communication.c file we have a function called
uint32_t start_broadcasting(void)
{
send_beacon(OPCODE, 0, /* determine data version here to send at runtime */, key);
}
My question is since we are using the same file ble_communication.c for both versions of the build, how can the code select which variable to use for its build during the runtime of the code? If it's Data Version 1, I want it to use data_version1[] and if's is Data Version 2 it uses data_version2[].
I can't use #ifndef switch statements as I am not allowed to use them due to the new design guidelines

To be honest, I would prefer to use the #ifdef, but here is a workaround for you.
Create two files with the desired data and select the required file at build time, using the makefile.
First, prepare two C files, ble_communication_data1.c and ble_communication_data2.c. Feel free to choose a clearer name.
Place the required data in each C file, but keep the names the same.
ble_communication_data1.c
uint8_t ble_communication_data[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
ble_communication_data2.c
uint8_t ble_communication_data[5] = {0x01, 0x00, 0x00, 0x00, 0x00};
Create a header file to access the data:
ble_communication_data.h
extern uint8_t ble_communication_data[5];
Modify the ble_communication.c so that it uses the common variable name:
#include "ble_communication_data.h"
uint32_t start_broadcasting(void)
{
send_beacon(OPCODE, 0, ble_communication_data, key);
}
Finally, in each of the makefiles, add the correct ble_communication_data C file to the list of files to be compiled.

Related

C contiguous data arrays

Say I have 2 arrays of data:
const uint8_t data1[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
const uint8_t data2[] = {0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
I would like to be able to read these individually, but also as one contiguous block of data.
eg: I could access data1[8] in the same way as data[0].
Reason: I have various const data definitions in some individual .c files that I'd rather not touch (font bitmaps) but I'd like to append some extra data to them (extra special characters). So I'd like to
#include <original font file>
const uint8_t extrafonts[] = {<more font bitmaps>};
Can this be done?
The only way to guarantee contiguous allocation in C is to use arrays of arrays. In this case it would seem that a const uint8_t [2][8] would solve all your problems, so use that if possible.
Otherwise, more advanced solutions could use structs and unions. These guarantee an order of allocation but come with the disadvantage that the compiler can insert padding anywhere. In this specific case it wouldn't be a problem on any real-world computer, since chunks of 8 bytes are aligned. If you have a standard C compiler, you can do this:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
struct
{
uint8_t data1 [8];
uint8_t data2 [8];
};
uint8_t data [16];
} data_t;
int main (void)
{
const data_t data =
{
.data1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07},
.data2 = {0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
};
for(size_t i=0; i<16; i++)
{
printf("%.2"PRIx8" ", data.data[i]);
}
}
Now you can access the arrays individually through data.data1/data.data2 or as one, with data.data.
In cases where you worry about struct padding, you'll have to add some non-standard #pragma pack(1) or similar compiler-specific instruction.
There is another alternative that might be applicable to your use case: Use external preprocessing.
Use your favorite scripting language with some regular expression magic to read original font source file, and append extra font data at the end of array. Then save it to new file and use that in compilation instead.
This might seem a lot of work at first, but c files which are generated by tools (which I assume is the case with your font bitmaps) tend to have predictable format that is not too hard to parse.
You could probably use:
struct ArrayPair
{
uint8_t data1[8];
uint8_t data2[8];
};
const struct ArrayPair data =
{
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
{ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }
};
Now you can probably get away with using:
data.data1[8]
It isn't very elegant. Your requirement is not sensible.
You said that these are 2 global arrays on different source files. So I am ignoring any options where you can group these with unions or structures.
Now the bad news: There is absolutely no guarantee that 2 global variables will end up next to each other in memory with standard C rules.
You can do this, but you need to use compiler specific extensions instead. You need to:
Use manual memory placement to place variables next to each other.
Disable any optimizations or other compiler features that might break your code because you are accessing array out of bounds.
Note that I am assuming that you are in system where resources are limited, for example, some embedded system. If that is not the case, then simply create third array, and merge 2 arrays at program startup.

Is there any way I could avoid using the array in PROGMEM in Arduino or modify it?

I am using the SSD1306 OLED with Arduino. I am trying to send the Bitmap data via HC-05 Bluetooth module, so I can display the Bitmap image on the OLED.
The problem I'm facing is :
const uint8_t frame1[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0xff, 0xff,...}
The above frame1[] array of preexisting Bitmap is of const type and gets stored in PROGMEM (has to be of const type) , and thus the array cannot be modified. Is there any other way I could display the received data or even, modify the frame1[] array to display the bitmap instantly as I get the bitmap data over Bluetooth?
PS : I'm using the U8g library for display
How about something like this:
uint8_t frame1[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,...};
You don't need to save the array in your arduinos PROGMEM,
you can also save it as a regular array.
That may only be a problem if your arduinos ram is too low,
so that the frame can only fit into PROGMEM - just try it

How to append another HEX value at the end of an existing byte array in C

I have searched on google and checked my findings on https://www.onlinegdb.com/
But so far, I am not satisfied with my trials and errors. Perhaps, I didn't know how to ask.
I am sure that this could be already very known by many people.
Normally I am reading HEX values from UART communication and placing in a buffer array.
But, for making things simpler, I give you that code snippet;
uint8_t buffer[20] = {0x7E, 0x00, 0x07, 0xAA, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xCC};
uint8_t newValue = 0x55;
My goal is to append newValue on buffer and that new value has to be seen after the last array value which is 0xCC in this case.
So, my question is how to do that efficiently?
Note that: One of my trials (works OK but not as I wanted);
buffer[11] = newValue ;
for(int i=0;i<sizeof(buffer);i++)
printf("%02x", buffer[i]);
But, then I need to know the position of the last value and increase the position by one which is 11 (0 based counting) in this case.

how to create image programmatically

Is it possible to create bitmap programmatically in C?
I want to pass it some text to draw, e.g.
createBitmapWithContents("Hello");
or
createBitmapWithContents("Hello \n other line");
And it should create bitmap which has "Hello" drawn in it (or draw second text respectively).
Also, the text "Hello" might be a Unicode string. Not necessarily English characters.
Preferably I would like to do this without using some third party libraries.
You'll need to do two different things :
Generate an image in memory that represents your string
Store that image into a file
Both can be done without external libraries (using simple predefined patterns of characters and storing as simple format such as BMP).
But note that it would be a lot easier to do this using a high-level image drawing library such as OpenCV or ImageMagick.
The first thing to do is to is to define a data structure to store your image, something like this:
struct Image {
int height, width;
unsigned char* pixels;
};
Then you'll have to generate the functions to allocate the image, free the image and maybe something to copy an image inside another one.
In order to print your character on your image, you would have to create predefined patterns like this:
char patternA[] = {
0x00, 0x00, 0xff, 0x00, 0x00
0x00, 0xff, 0x00, 0xff, 0x00
0x00, 0xff, 0x00, 0xff, 0x00
0x00, 0xff, 0xff, 0xff, 0x00
0x00, 0xff, 0x00, 0xff, 0x00
0x00, 0xff, 0x00, 0xff, 0x00
0x00, 0xff, 0x00, 0xff, 0x00
};
Image imageOfA;
imageOfA.width = 5;
imageOfA.height= 7;
imageOfA.pixels= patternA;
You can also read those patterns from image files or even better, from a font file (but without external libraries, you'll need to implement the file readers yourself).
Once you have your patterns of characters, you can combine those predefined images to create a new image corresponding to your input string.
Finally, you'll have to write your image structure into a file. For that, you can either use a low-level library (such as libjpeg or libpng) or you can implement it yourself using a simple file format (such as BMP).
The conclusion is that you really want to use a third party library to achieve what you want.
Did you try googling this?
There's quite a few things you could do, for example you can you can run loops to create your own matrix of pixels. check this link here

Use NSTextfield data to build an array of integers?

Im using the following code to send a hex string to an NSStreamoutput:
uint8_t mirandaroutecommand[] = { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x14 };
NSData *data = [[NSData alloc] initWithBytes:mirandaroutecommand length:sizeof(mirandaroutecommand)];
[hextooloutputStream write:[data bytes] maxLength:[data length]];
This works great but the problem is I need these hex values to come from NSTextfields on the user interface. I've tried to convert the NSTextfield data to an integer but that didn't work. Is there a way to use data from several NSTextfields to build an array of integers using hex values?
I've tried to find an existing topic covering this but I've had no luck.
The NSString methods integerValue and intValue assume a decimal representation and ignore and trailing gumph - so apply them to #"0x01" and they see 0 followed by some gumph (x01) which they ignore.
To read a hex value use NSScanner's scanHexInt: (or scanHexLongLong:):
unsigned scannedHexValue;
if ([[NSScanner scannerWithString:textFieldContents] scanHexInt:&scannedHexValue])
{
// value found
...
}
NSScanner is more powerful than just parsing a single value, so with the appropriate method calls you can scan a comma separated list of hex values if you wish.

Resources