Passing a 32-bit struct into an 32-bit integer function argument - objective-c

I have some straight C code in my Objective-C project. In one of the APIs I'm using, I can register for a callback with a function that takes an 32-bit integer parameter:
void Callback(Packet* packet, int32_t port);
I want to be able to send my callback two 16-bit ports instead of one 32-bit port. Naturally, I could just use bitwise operations, but I'd prefer something more explicit.
Here's my current solution with a union:
typedef struct {
int16_t port1;
int16_t port2;
} MultiPortStruct;
typedef union {
int32_t port;
MultiPortStruct portStruct;
} MultiPortAdaptor;
In the sender:
void registerCallback(int16_t port1, int16_t port2) {
MultiPortAdaptor adaptor;
adaptor.portStruct.port1 = port1;
adaptor.portStruct.port2 = port2;
int32_t port = adaptor.port
RegisterAPICallback(&myCallback, port);
}
In the callback:
void myCallback(Packet* packet, int32_t port) {
MultiPortAdaptor adaptor;
adaptor.port = port;
int16_t port1 = adaptor.portStruct.port1;
int16_t port2 = adaptor.portStruct.port2;
// do stuff
}
Is this approach correct or are there problems with it? (For example: should I zero out the adaptor unions? Is it OK to access different members of the same union?) Is there a simpler way?
UPDATE:
OK, I'm convinced: even if doing this is possible, it's probably not a great idea. I've decided to simply use a set of functions to do the bitwise operations for me:
int32_t SubPortsToPort(int16_t port1, int16_t port2)
int16_t PortToSubPort1(int32_t port)
int16_t PortToSubPort2(int32_t port)
So now all I have to do is this:
void registerCallback(int16_t port1, int16_t port2) {
int32_t port = SubPortsToPort(port1, port2);
RegisterAPICallback(&myCallback, port);
}
And in the callback:
void myCallback(Packet* packet, int32_t port) {
int16_t port1 = PortToSubPort1(port);
int16_t port2 = PortToSubPort2(port);
// do stuff
}
Less code, less worries!

First it is OK to store into one member and read from another member of the same union provided you only read bytes you have written - any others have unspecified values.
The issue with what you are doing is the possible introduction by the compiler of padding between fields, which would destroy your carefully arranged overlap. With current compilers & cpu architectures you will probably be OK, but there is no need to leave it to chance as there are a number of ways to fix the alignment of fields.
The simplest, though compiler dependent, method is to use the packed attribute:
typedef struct __attribute((packed))
{
int16_t port1;
int16_t port2;
} MultiPortStruct;
This simply instructs the compiler not to add any padding, so the above will always be 32-bits even on architectures which use, say, 4-byte alignment for 2-byte values.
This attribute is supported by Clang, GCC & LLVM (maybe not all versions?) - the compiler will tell you if it doesn't. If you are using a compiler which does not support the attribute (or an equivalent one) then you can look into using the C language _Alignof and _Alignas features.
HTH

With the "struct in a union trick" you have to take care, because the structure members can be padded:
There may be unnamed padding within a structure object, but not at its
beginning.
ISO/IEC 9899:TC3, 6.7.2.1 – 13
Therefore, …
typedef struct {
int16_t port1;
int16_t port2;
} MultiPortStruct;
… can have a layout as …
typedef struct {
int32_t port1;
int32_t port2;
} MultiPortStruct;
… if the implementation likes that.
So the overlay in the union will not work, even this is not very likely.
It would be similar with bitfields:
typedef struct {
int port1:16;
int port2:16;
} MultiPortStruct;
This is, because the compiler has to put the following bitfield into the same unit, if it fits, but can chose the unit.
An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
ibidem, 6.7.2.1 – 10
Therefore, it is theoretically possible, that an implementation choses int16 as allocation unit and places padding between the fields, even this makes no sense and is very unlikely.
As mentioned in the comment, there is nothing wrong with bitfields.

As others said, a struct might have padding (though unlikely). Another approach that would at least not have internal padding would be
typedef struct {
int16_t port[2];
} MultiPortStruct;
arrays never have internal padding and the first field of a struct is always at its start. Now theoretically this still could have padding at the end, so you should check with something like
_Static_assert(sizeof(MultiPortStruct)==2*sizeof(int16_t));

Related

printf implementation for embedded system

where can I find an almost complete implementation (float, width, etc.) suitable for embedded systems (few nested funtction call, low stack and ram usage, no heap, mo syscall)
Have you checked out ChibiOS's implementation of chvprintf? It's Apache-licensed and float-support (costly) is a compile-time option via define.
It's built with microcontrollers in mind. The macros are all pretty much only calls to a function pointer in the supplied BaseSequentialStream struct and you can replace them as you see fit. The var-args list is your regular stdarg.h implementation.
For transmitting on the serial port, the quickest thing is:
int32_t printfDebugSerial(const char *format, ...)
{
if (strlen(format) >200) return -1;
char tempBuff[256]; memset(tempBuff, 0, sizeof tempBuff);
va_list arg;
int32_t done;
va_start (arg, format);
done = (int32_t)vsprintf(tempBuff,format, arg);
va_end (arg);
pushMsgOnSerial((uint8_t*)tempBuff, done);
return done;
}
where pushMsgOnSerial() will be your board specific function for sending bytes on the serial port.

Writing Coverity model: pointer in struct ALWAYS points to tainted data

I reguarly check lwIP, a free TCP/IP stack with Coverity.
As a network stack, we have untrusted data coming in from the network which is stored in struct pbuf (some members omitted for clarity):
struct pbuf {
void *payload;
u16_t len;
u16_t ref;
};
My questions are:
1) I want to model that "void* payload" of struct pbuf ALWAYS points to tainted data, every access to it must be untrusted. How can I do this?
2) We use refcounting (u16_t ref). Is there any way to model refcounting in Coverity?

Write UART on PIC18

I need help with the uart communication I am trying to implement on my Proteus simulation. I use a PIC18f4520 and I want to display on the virtual terminal the values that have been calculated by the microcontroller.
Here a snap of my design on Proteus
Right now, this is how my UART code looks like :
#define _XTAL_FREQ 20000000
#define _BAUDRATE 9600
void Configuration_ISR(void) {
IPR1bits.TMR1IP = 1; // TMR1 Overflow Interrupt Priority - High
PIE1bits.TMR1IE = 1; // TMR1 Overflow Interrupt Enable
PIR1bits.TMR1IF = 0; // TMR1 Overflow Interrupt Flag
// 0 = TMR1 register did not overflow
// 1 = TMR1 register overflowed (must be cleared in software)
RCONbits.IPEN = 1; // Interrupt Priority High level
INTCONbits.PEIE = 1; // Enables all low-priority peripheral interrupts
//INTCONbits.GIE = 1; // Enables all high-priority interrupts
}
void Configuration_UART(void) {
TRISCbits.TRISC6 = 0;
TRISCbits.TRISC7 = 1;
SPBRG = ((_XTAL_FREQ/16)/_BAUDRATE)-1;
//RCSTA REG
RCSTAbits.SPEN = 1; // enable serial port pins
RCSTAbits.RX9 = 0;
//TXSTA REG
TXSTAbits.BRGH = 1; // fast baudrate
TXSTAbits.SYNC = 0; // asynchronous
TXSTAbits.TX9 = 0; // 8-bit transmission
TXSTAbits.TXEN = 1; // enble transmitter
}
void WriteByte_UART(unsigned char ch) {
while(!PIR1bits.TXIF); // Wait for TXIF flag Set which indicates
// TXREG register is empty
TXREG = ch; // Transmitt data to UART
}
void WriteString_UART(char *data) {
while(*data){
WriteByte_UART(*data++);
}
}
unsigned char ReceiveByte_UART(void) {
if(RCSTAbits.OERR) {
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
while(!PIR1bits.RCIF); //Wait for a byte
return RCREG;
}
And in the main loop :
while(1) {
WriteByte_UART('a'); // This works. I can see the As in the terminal
WriteString_UART("Hello World !"); //Nothing displayed :(
}//end while(1)
I have tried different solution for WriteString_UART but none has worked so far.
I don't want to use printf cause it impacts other operations I'm doing with the PIC by adding delay.
So I really want to make it work with WriteString_UART.
In the end I would like to have someting like "Error rate is : [a value]%" on the terminal.
Thanks for your help, and please tell me if something isn't clear.
In your WriteByte_UART() function, try polling the TRMT bit. In particular, change:
while(!PIR1bits.TXIF);
to
while(!TXSTA1bits.TRMT);
I don't know if this is your particular issue, but there exists a race-condition due to the fact that TXIF is not immediately cleared upon loading TXREG. Another option would be to try:
...
Nop();
while(!PIR1bits.TXIF);
...
EDIT BASED ON COMMENTS
The issue is due to the fact that the PIC18 utilizes two different pointer types based on data memory and program memory. Try changing your declaration to void WriteString_UART(const rom char * data) and see what happens. You will need to change your WriteByte_UART() declaration as well, to void WriteByte_UART(const unsigned char ch).
Add delay of few miliseconds after line
TXREG = ch;
verify that pointer *data of WriteString_UART(char *data) actually point to
string "Hello World !".
It seems you found a solution, but the reason why it wasn't working in the first place is still not clear. What compiler are you using?
I learned the hard way that C18 and XC8 are used differently regarding memory spaces. With both compilers, a string declared literally like char string[]="Hello!", will be stored in ROM (program memory). They differ in the way functions use strings.
C18 string functions will have variants to access strings either in RAM or ROM (for example strcpypgm2ram, strcpyram2pgm, etc.). XC8 on the other hand, does the job for you and you will not need to use specific functions to choose which memory you want to access.
If you are using C18, I would highly recommend you switch to XC8, which is more recent and easier to work with. If you still want to use C18 or another compiler which requires you to deal with program/data memory spaces, then here below are two solutions you may want to try. The C18 datasheet says that putsUSART prints a string from data memory to USART. The function putrsUSART will print a string from program memory. So you can simply use putrsUSART to print your string.
You may also want to try the following, which consists in copying your string from program memory to data memory (it may be a waste of memory if your application is tight on memory though) :
char pgmstring[] = "Hello";
char datstring[16];
strcpypgm2ram(datstring, pgmstring);
putsUSART(datstring);
In this example, the pointers pgmstring and datstring will be stored in data memory. The string "Hello" will be stored in program memory. So even if the pointer pgmstring itself is in data memory, it initially points to a memory address (the address of "Hello"). The only way to point to this same string in data memory is to create a copy of it in data memory. This is because a function accepting a string stored in data memory (such as putsUSART) can NOT be used directly with a string stored in program memory.
I hope this could help you understand a bit better how to work with Harvard microprocessors, where program and data memories are separated.

Getting raw bytes from packed struct

I've got a struct which looks like this:
#[repr(packed)]
struct Header {
some: u8,
thing: u8,
}
How can I get raw bytes from it, that I could use for either a C library or socket interaction?
I was hoping to use transmute to solve the problem, but unfortunately this doesn't work:
let header = Header {....}
let header_bytes: &[u8] = unsafe { mem::transmute(header) };
let result = self.socket.write(header_bytes);
This fails with
error: transmute called on types with different sizes: &Header (64 bits) to &[u8] (128 bits)
Edit: updated for Rust 1.x.
You can't transmute arbitrary thing to arbitrary thing (like Header to &[u8]) because transmute() is akin to reinterpret_cast in C++: it literally reinterprets the bytes which its argument consists of, and in order for this to be successful the source and the target type should have the same size. But even if Header and &[u8] had the same size, it wouldn't make sense to convert between them: Header is an actual value while &[u8] is a pointer with a size of data behind that pointer.
In order to interpret a piece of data as a slice of bytes you need to perform three steps: obtain a raw pointer to the data, convert it to a pointer to u8 and then convert that to a slice of u8. This means enhancing the raw pointer value with the length, which in this case is equal to the structure size. The last step can easily be done with std::slice::from_raw_parts():
use std::slice;
use std::mem;
let p: *const Header = &header; // the same operator is used as with references
let p: *const u8 = p as *const u8; // convert between pointer types
let s: &[u8] = unsafe {
slice::from_raw_parts(p, mem::size_of::<Header>())
};
However, doing this in most cases is not a good idea. Even though the struct is marked as packed, it still leaves the problem with the byte order, so at the very least the code which does this won't be portable (or rather, the data it serializes in such form may not be recoverable by the same program compiled for another architecture).
You can make any object into a byte slice with a function like this:
/// Safe to use with any wholly initialized memory `ptr`
unsafe fn raw_byte_repr<'a, T>(ptr: &'a T) -> &'a [u8]
{
std::mem::transmute(std::raw::Slice{
data: ptr as *const _ as *const u8,
len: std::mem::size_of::<T>(),
})
}
Run in Rust playpen.
I don't know the full safety analysis, but as long as you don't access any uninit values it should be fine.

Is there a way to wrap an ObjectiveC block into function pointer?

I have to provide a C-style callback for a specific C library in an iOS app. The callback has no void *userData or something similar. So I am not able to loop in a context. I'd like to avoid introducing a global context to solve this. An ideal solution would be an Objective-C block.
My question: Is there a way to 'cast' a block into a function pointer or to wrap/cloak it somehow?
Technically, you could get access to a function pointer for the block. But it's totally unsafe to do so, so I certainly don't recommend it. To see how, consider the following example:
#import <Foundation/Foundation.h>
struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
};
int main(int argc, char *argv[]) {
#autoreleasepool {
// Block that doesn't take or return anything
void(^block)() = ^{
NSLog(#"Howdy %i", argc);
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr = (struct Block_layout *)(__bridge void *)block;
// Now do same as `block()':
blockStr->invoke(blockStr);
// Block that takes an int and returns an int
int(^returnBlock)(int) = ^int(int a){
return a;
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr2 = (struct Block_layout *)(__bridge void *)returnBlock;
// Now do same as `returnBlock(argc)':
int ret = ((int(*)(void*, int a, ...))(blockStr2->invoke))(blockStr2, argc);
NSLog(#"ret = %i", ret);
}
}
Running that yields:
Howdy 1
ret = 1
Which is what we'd expect from purely executing those blocks directly with block(). So, you could use invoke as your function pointer.
But as I say, this is totally unsafe. Don't actually use this!
If you want to see a write-up of a way to do what you're asking, then check this out:
http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html
It's just a great write-up of what you would need to do to get this to work. Sadly, it's never going to work on iOS though (since you need to mark a page as executable which you're not allowed to do within your app's sandbox). But nevertheless, a great article.
If your block needs context information, and the callback does not offer any context, I'm afraid the answer is a clear no. Blocks have to store context information somewhere, so you will never be able to cast such a block into a no-arguments function pointer.
A carefully designed global variable approach is probably the best solution in this case.
MABlockClosure can do exactly this. But it may be overkill for whatever you need.
I know this has been solved but, for interested parties, I have another solution.
Remap the entire function to a new address space. The new resulting address can be used as a key to the required data.
#import <mach/mach_init.h>
#import <mach/vm_map.h>
void *remap_address(void* address, int page_count)
{
vm_address_t source_address = (vm_address_t) address;
vm_address_t source_page = source_address & ~PAGE_MASK;
vm_address_t destination_page = 0;
vm_prot_t cur_prot;
vm_prot_t max_prot;
kern_return_t status = vm_remap(mach_task_self(),
&destination_page,
PAGE_SIZE*(page_count ? page_count : 4),
0,
VM_FLAGS_ANYWHERE,
mach_task_self(),
source_page,
FALSE,
&cur_prot,
&max_prot,
VM_INHERIT_NONE);
if (status != KERN_SUCCESS)
{
return NULL;
}
vm_address_t destination_address = destination_page | (source_address & PAGE_MASK);
return (void*) destination_address;
}
Remember to handle pages that aren't required anymore and note that it takes a lot more memory per invocation than MABlockClosure.
(Tested on iOS)