Constructing bitmask ? bitwise packet - objective-c

I have been wanting to experiment with this project Axon with an iOS app connecting over a tcp connection. Towards the end of the doc the protocol is explained as so
The wire protocol is simple and very much zeromq-like, where is a BE 24 bit unsigned integer representing a maximum length of roughly ~16mb. The data byte is currently only used to store the codec, for example "json" is simply 1, in turn JSON messages received on the client end will then be automatically decoded for you by selecting this same codec.
With the diagram
octet: 0 1 2 3 <length>
+------+------+------+------+------------------...
| meta | <length> | data ...
+------+------+------+------+------------------...
I have had experience working with binary protocols creating a packet such as:
NSUInteger INT_32_LENGTH = sizeof(uint32_t);
uint32_t length = [data length]; // data is an NSData object
NSMutableData *packetData = [NSMutableData dataWithCapacity:length + (INT_32_LENGTH * 2)];
[packetData appendBytes:&requestType length:INT_32_LENGTH];
[packetData appendBytes:&length length:INT_32_LENGTH];
[packetData appendData:data];
So my question is how would you create the data packet for the Axon request, I would assume some bit shifting, which I am not too clued up on.

Allocate 1 array of char or unsigned char with size == packet_size;
Decalre constants:
const int metaFieldPos = 0;
const int sizeofMetaField = sizeof(char);
const int lengthPos = metaFieldPos + sizeofMetaField;
const int sizeofLengthField = sizeof(char) * 3;
const int dataPos = lengthPos + sizeofLengthField;
If you got the data and can recognize begining of the packet, you can use constants above to
navigate by pointers.
May be these functions will help you (They use Qt, but you can easily translate them to library, that you use)
quint32 Convert::uint32_to_uint24(const quint32 value){
return value & (quint32)(0x00FFFFFFu);
}
qint32 Convert::int32_to_uint24(const qint32 value){
return value & (qint32)(0x00FFFFFF);
}
quint32 Convert::bytes_to_uint24(const char* from){
quint32 result = 0;
quint8 shift = 0;
for (int i = 0; i < bytesIn24Bits; i++) {
result |= static_cast<quint32>(*reinterpret_cast<const quint8 *>(from + i)) << shift;
shift+=bitsInByte;
}
return result;
}
void Convert::uint32_to_uint24Bytes(const quint32 value, char* from){
quint8 shift = 0;
for (int i = 0; i < bytesIn24Bits; i++) {
const quint32 buf = (value >> shift) & 0xFFu;
*(from + i) = *reinterpret_cast<const char *>(&buf);
shift+=bitsInByte;
}
}
QByteArray Convert::uint32_to_uint24QByteArray (const quint32 value){
QByteArray bytes;
bytes.resize(sizeof(value));
*reinterpret_cast<quint32 *>(bytes.data()) = value;
bytes.chop(1);
return bytes;
}

Related

I am trying to store and retrieve a TensorflowMicro buffer array as an Arduino MBED SDRAM pointer

The Arduino core is on github as ArduinoCore-mbed
I have had some success storing a camera buffer into Arduino MBED SDRAM, but that was fairly easy as the code was expecting a pointer when working with the camera. See code below:
SDRAMClass mySDRAM;
uint8_t *sdram_frame_buffer;
//uint8_t frame_buffer[320*320];
void setup() {
mySDRAM.begin();
sdram_frame_buffer = (uint8_t *)mySDRAM.malloc(320 * 320 * sizeof(uint8_t));
then in the main loop I did
if (cam.grab(sdram_frame_buffer) == 0){...
Note: I also do some frame alignment on the above code, but it still kind of works fine.
But now I want to store the entire TensorflowMicro c++ array
const unsigned char model_tflite[] = { 0x74, 0x69, 0x74, ...};
unsigned int model_tflite_len = 2640;
//which is later called as an array
model = tflite::GetModel(model_tflite); // name from the tflite converter model.h file
The problem here is that the Portenta has a max array size <= 1MB which is much less than the SDRAM max array size 8MB. What would be best would be to put the data for the Machine Learning model directly into SDRAM without using an array at all. Not sure if there is an easy way to do that.
Anyone have any suggestions?
Here is an example that runs on the Arduino Portenta
// Needed for SDRAM assignment on Arduino Portenta
#include <SDRAM.h>
#define ALIGN_PTR(p,a) ((p & (a-1)) ?(((uintptr_t)p + a) & ~(uintptr_t)(a-1)) : p)
SDRAMClass mySDRAM;
// assign values to a regular array
unsigned char model_tflite[] = {0x54, 0x46, 0x4c, 0x33};
unsigned int model_tflite_len = 4;
// define SDRAM pointer
unsigned char *sdram_mem;
unsigned char *sdram_tflite; // 32-byte aligned
void setup() {
Serial.begin(115200);
mySDRAM.begin(SDRAM_START_ADDRESS);
// setup SDRAM memory block
sdram_mem = (unsigned char *) SDRAM.malloc(4 + 32 /*alignment*/);
sdram_tflite = (unsigned char *)ALIGN_PTR((uintptr_t)sdram_mem, 32);
// THE PROBLEM
// How to assign the data directly to the allocated pointer memory
// without having to make an array as well
// The following traditional line works
// sdram_tflite = model_tflite;
// This line doesn't work
// sdram_tflite = {0x54, 0x46, 0x4c, 0x33};
// The following works, but is very clumsy
*(sdram_tflite + 0) = 0x54;
*(sdram_tflite + 1) = 0x46;
*(sdram_tflite + 2) = 0x4c;
*(sdram_tflite + 3) = 0x33;
}
void myShowArray( unsigned char b[], int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(b[k], HEX);
}
Serial.println();
}
void myShowPointer( unsigned char *b, int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(*(b + k), HEX);
}
Serial.println();
}
void loop() {
Serial.println("Regular array");
for (int i=0; i < model_tflite_len; i++){
Serial.println(model_tflite[i], HEX);
}
Serial.println();
Serial.println("SDRAM pointer as an array");
for (int i=0; i < model_tflite_len; i++){
Serial.println( *(sdram_tflite + i), HEX );
}
Serial.println();
Serial.println("Regular array passed as an array to the receiving function");
myShowArray(model_tflite, model_tflite_len);
Serial.println("Pointer passed as a pointer to the receiving function");
myShowPointer(sdram_tflite, model_tflite_len);
Serial.println("Pointer passed as an array to the receiving function");
myShowArray(*&sdram_tflite, model_tflite_len);
Serial.println("--------------------");
Serial.println();
delay(4000);
}
with output :
Regular array
54
46
4C
33
SDRAM pointer as an array
54
46
4C
33
Regular array passed as an array to the receiving function
54
46
4C
33
Pointer passed as a pointer to the receiving function
54
46
4C
33
Pointer passed as an array to the receiving function
54
46
4C
33
--------------------
// Needed for SDRAM assignment on Arduino Portenta
#include <SDRAM.h>
#define ALIGN_PTR(p,a) ((p & (a-1)) ?(((uintptr_t)p + a) & ~(uintptr_t)(a-1)) : p)
SDRAMClass mySDRAM;
// assign values to a regular array
unsigned char model_tflite[] = {0x54, 0x46, 0x4c, 0x33};
unsigned int model_tflite_len = 4;
// define SDRAM pointer
unsigned char *sdram_mem;
unsigned char *sdram_tflite; // 32-byte aligned
void setup() {
Serial.begin(115200);
mySDRAM.begin(SDRAM_START_ADDRESS);
// setup SDRAM memory block
sdram_mem = (unsigned char *) SDRAM.malloc(4 + 32 /*alignment*/);
sdram_tflite = (unsigned char *)ALIGN_PTR((uintptr_t)sdram_mem, 32);
// THE PROBLEM
// How to assign the data directly to the allocated pointer memory
// without having to make an array as well
// The following traditional line works
// sdram_tflite = model_tflite;
// This line doesn't work
// sdram_tflite = {0x54, 0x46, 0x4c, 0x33};
// The following works, but is very clumsy
// *(sdram_tflite + 0) = 0x54;
// *(sdram_tflite + 1) = 0x46;
// *(sdram_tflite + 2) = 0x4c;
// *(sdram_tflite + 3) = 0x33;
// Try this
// unsigned char buffer[8];
// memcpy(buffer,"\x20\x38\x00\x00\x0E\x82\x00\x06",8);
// yes this works fine!
memcpy(sdram_tflite, "\x54\x46\x4c\x33", model_tflite_len);
}
void myShowArray( unsigned char b[], int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(b[k], HEX);
}
Serial.println();
}
void myShowPointer( unsigned char *b, int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(*(b + k), HEX);
}
Serial.println();
}
void loop() {
Serial.println("Regular array");
for (int i=0; i < model_tflite_len; i++){
Serial.println(model_tflite[i], HEX);
}
Serial.println();
Serial.println("SDRAM pointer as an array");
for (int i=0; i < model_tflite_len; i++){
Serial.println( *(sdram_tflite + i), HEX );
}
Serial.println();
Serial.println("Regular array passed as an array to the receiving function");
myShowArray(model_tflite, model_tflite_len);
Serial.println("Pointer passed as a pointer to the receiving function");
myShowPointer(sdram_tflite, model_tflite_len);
Serial.println("Pointer passed as an array to the receiving function");
// myShowArray(*&sdram_tflite, model_tflite_len);
myShowArray(sdram_tflite, model_tflite_len);
Serial.println("--------------------");
Serial.println();
delay(4000);
}

Convert short array to byte array and vice-versa and int to byte array and vice-versa in Objective-c

I am confused to convert byte array to short vice-versa and also int to byte array vice-versa in Objective-C.
I have seen in Java like following
public static short byteArrayToShort(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get();
} else {
return b[0];
}
}
/**
* Short to byte array.
*
* #param value the value
* #return the byte[]
*/
public static byte[] shortToByteArray(short value) {
return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
/**
* Int to byte array.
*
* #param value the value
* #return the byte[]
*/
public static byte[] intToByteArray(int value) {
return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
}
/**
* Convert the byte array to an short starting from the given offset.
*
* #param b The byte array
* #return The integer
*/
public static int byteArrayToInt(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get();
} else {
return b[0];
}
}
In Objective-C I have tried like following:
//Byte to Short array
- (uint16_t*) byte2short:(uint8_t *)bytes size:(int)size{
uint16_t*shorts = (uint16_t*)malloc(size/2);
for (int i=0; i < size/2; i++){
shorts[i] = (bytes[i*2+1] << 8) | bytes[i*2];
}
return shorts;
}
//Short to Byte array
- (uint8_t *) short2byte:(uint16_t*)shorts size:(int)size{
uint8_t *bytes = (uint8_t *)malloc(size*2);
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint16_t) (shorts[i] & 0x00FF);
bytes[(i * 2) + 1] = (uint16_t) (shorts[i] >> 8);
shorts[i] = 0;
}
return bytes;
}
I have tried like this and also I dont have idea in conversion of int to Byte array in Objective-c.
Please suggest me
The problem with your code is that you are assuming that malloc somehow "knows" about the size of whatever is being allocated, in the same way that Java's array new knows the difference between allocating 5 ints and 5 shorts. Well, malloc does not. Unless you tell it otherwise, it allocates the required number of bytes. That's why when you do this
uint16_t*shorts = (uint16_t*)malloc(size/2);
and then write size/2 uint16_t into it, you overrun the buffer.
A proper way of allocating an array of primitives in C (and in Objective-C, which is a superset of C) is as follows:
size_t count = (size+1)/2; // Do not assume that size is even
uint16_t *shorts = malloc(sizeof(uint16_t)*count);
Now you have enough memory to fit all your shorts.
In your other function you should use
uint8_t *bytes = malloc(sizeof(uint8_t)*size*2);
Note that the cast is unnecessary in both cases. The type of bytes variable matters, though, because that's what determines the actual address written to in bytes[i * 2] and bytes[(i * 2)+1] expressions:
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint8_t) (shorts[i] & 0xFF);
bytes[(i * 2) + 1] = (uint8_t) (shorts[i] >> 8);
shorts[i] = 0;
}

checking bits in an NSData object

how do i check if bits 0-6 in an NSData object which is 0x0001 are equal to 1?
My code
const char *byte = [dataObject bytes];
for (int i=0; i<2; i++) {
char n = byte[i];
char buffer[9];
buffer[8] = 0; //for null
int j = 8;
while(j > 0)
{
if(n & 0x01)
{
buffer[--j] = '1';
//a bit is equal to 1 from my understanding
} else
{
buffer[--j] = '0';
}
n >>= 1;
}
}
says that bit 1 is a 1 which is clearly not true.
This runs on an iPhone which is a little Endian system
This is what I ended up learning
const char *byte = [fixtureStatusBasic bytes]; //objective c, puts the 2 bytes into *byte
char n = byte[0]; //first byte is now called n
if(n & 0b00111111){ //AND the byte "n" with 6 least significant bits set to 1 to see if any of the 6 bits is set to 1
//if this is true, and the program goes here, that means that one of the bits is set to 1
}
To see if bit 5 is set for example,
if(n & 0b00010000){
//5th least significant byte is set to 1.
}
thank you freenode.

Arduino replace code

I'm very new to Arduino and C programming.
I'm making a GPS speedo and I'm trying to read in some serial, store a value from a substring and echo it back via serial.
At the moment I'm having problems storing the substring.
I've gotten to the point where I'm able to get some data between < and >.
But the data doesn't come in like that. It's a NMEA data stream and the data I want is between ,N, and ,K,.
So I've been trying to replace ,N, with < and ,K, with > .
Just can't get it to work. I get error: request for member 'replace' in 'c', which is of non-class type 'char'
Here's my code so far....
int indata = 0;
int scrubdata = 0;
char inString[32];
int stringPos = 0;
boolean startRead = false; // is reading?
void setup() {
Serial.begin(4800);
}
void loop() {
String pageValue = readPage();
Serial.print(pageValue);
}
String readPage(){
//read the page, and capture & return everything between '<' and '>'
stringPos = 0;
memset( &inString, 0, 32 ); //clear inString memory
while(true){
if (Serial.available() > 0) {
char c = Serial.read();
c.replace(",N,", "<");
c.replace(",K,", ">");
if (c == '<' ) { //'<' is our begining character
startRead = true; //Ready to start reading the part
}
else if(startRead){
if(c != '>'){ //'>' is our ending character
inString[stringPos] = c;
stringPos ++;
}
else{
//got what we need here! We can disconnect now
startRead = false;
return inString;
}
}
}
}
}
By Default:
Serial.read() returns an int if you must process the data this way, try casting it to char with:
char c = (char) Serial.read();
Another way to do this:
Would be to seek your beginning string (discarding un-needed data) using Serial.find() then reading data until you met your end character ",K," with Serial.readBytesUntil()
Something like this would work quite well:
char inData[64]; //adjust for your data size
Serial.setTimeout(2000); //Defaults to 1000 msecs set if necessary
Serial.find(",N,"); //Start of Data
int bRead = Serial.readBytesUntil(",K,", inData, 64); //Read until end of data
inData[bRead] = 0x00; //Zero terminate if using this as a string
return inData;

UART0 to UART2 gateway (sort of) for AtMega2560

I connected a device to the UART0 of the AtMega2560. I want to transfer the UART0 data to the UART2 to view it on the Terminal(PC).
When I connect the device directly to the PC using an UART to serial device (FTDI) It sends the data nicely.
When I put the UART2 in the middle for said purpose, then It only sends the first line, specifically:
Ver V2DAPV142 On-Line: And then forgets. Sometimes it doesn't send the first line too.
Code:
#define UART0_BUFFER_SIZE 40
#define RX_WAIT 65000
volatile unsigned char UART0_rx_ArrUC85[UART0_BUFFER_SIZE];
volatile unsigned char UART0_rx_ArrLength = 0, UART0_rx_ArrIndex = 0;
void uart0_init( unsigned int baudrate )
{
UBRR0H = (unsigned char) (baudrate>>8);
UBRR0L = (unsigned char) baudrate;
UCSR0B = ( 1 << RXEN0 ) | ( 1 << TXEN0 ) | (1<<RXCIE0);
UCSR0C = ( 1 << USBS0 ) | ( 1 << UCSZ01 ) | ( 1 << UCSZ00 ); // 8N1
}
void USART2Init(UINT16 ubrr_value)
{
UBRR2L = ubrr_value;
UBRR2H = (ubrr_value>>8);
UCSR2C|=(3<<UCSZ20);
UCSR2B = (1<<RXEN2) | (1<<TXEN2);
}
ISR(USART0_RX_vect)
{
unsigned char recChar = UDR0;
if (UART0_BUFFER_SIZE > UART0_rx_ArrLength)
{
UART0_rx_ArrUC85[UART0_rx_ArrIndex++] = recChar;
UART0_rx_ArrLength = UART0_rx_ArrIndex;
}
}
void uart2_putchar(UINT8 data)
{
//Local variables
unsigned int i;
for( i = 0; !( UCSR2A & ( 1 << UDRE2 ) ); i++ ) // Wait for empty transmit buffer
{
if( i > RX_WAIT ) // How long one should wait
{
return ; // Give feedback to function caller
}
}
UDR2 = data; // Start transmitting
//return (int)data; // Cast and return int value
}
void uart2_puts(unsigned char *str)
{
UINT8 dat;
for( ;*str != '\0'; )
{
dat= *str++ ;
uart2_putchar(dat);
}
}
int main()
{
USART2Init(8);
uart0_init(103);
sei();
while(1)
{
if(UART0_rx_ArrLength>0)
{
uart2_puts((unsigned char *) UART0_rx_ArrUC85);
UART0_rx_ArrLength = UART0_rx_ArrIndex = 0;
}
}
}
What could be the issue.
I checked it with same and different baud rates too for UART0 and UART2.
The issue was circuitry power level. The power supply was not sufficient for the Pen-Drive ctrlr and the regulator was not able to source for its communication power level. Hence it was not working sometimes. Further we have tested it and drew a conclusion that after giving sufficient power to the Pen-Drive ctrlr using another power regulator, the above said communication takes nicely place. I hope this can help ppl to draw attention towards the possible circuitry issues.