INOS
Best Practices

Overview

This sections gives some tips and tricks for INOS hackers


64 bit support

This section describes some pitfalls, if one tries to port it's INOS application to a 64 bit system. The folowing systems are 64 bit based :

NrNameDescription
6120585xx GIN-PCIe5 PCIe add on card, quad core Cortex A72 CPU, 1.8GHz, 2.133GT/s DDR4 RAM
6122613xx IMP-MAS5 CPU card, quad core Cortex A72 CPU, 1.8GHz, 2.133GT/s DDR4 RAM
6121599xx GIN-SAM5 CPU card, 8/16 core Cortex A72 CPU, 2.2GHz, 2x3.2GT/s DDR4 RAM
6002025xx INOS Desktop INOS application development running on Linux/Windows

The main difference between a 32 bit and a 64 bit system is its address space and therefore the size [bytes] of a pointer :

32 bit :

sizeof(void*) == 4 // representable with a uint32

64 bit :

sizeof(void*) == 8 // representable with a uint64

INOS provides several different data types to simplify writing portable code :

Data types :

  • intnbr : an int32 on a 32 bit system and an int64 on a 64 bit system
  • uintnbr : an uint32 on a 32 bit system and an uint64 on a 64 bit system
  • uintptr : an unsigned integer which is able to represent a pointer value
  • uintid : an unsigned integer which is able to represent an id (e.g. a hook id)

Hooks

A Hook is identified by it's hook id. This id represents in fact the address of the hook descriptor. It's size is therefore 4 or 8 bytes depending on the system it runs on. To get portable code, one has to use the data type uintid to declare the id variable. The old (32 bit) hook id types uint32 have to be replaced with uintid :

portable :

uintid idHook = axis->RegisterHook(...);
// or
axis->RegisterHook(&idHook, ...);
Definition cinosmcmodule.h:1900

not portable :

uint32 uHook = axis->RegisterHook(...);
// or
axis->RegisterHook(&uHook, ...);

Pointer

Pointer arithmetic

Whenever a pointer is converted to an unsigned integer or vice versa (usually used in pointer arithmetics) one has to take care of the different pointer sizes. Instead of a fix conversion from pointer to uint32, one has to use the data type uintptr instead. Example :

portable :

void* myPtr;
// ...
uintptr uAddr = (uintptr) myPtr + 0x100;

not portable :

void* myPtr;
// ...
uint32 uAddr = (uint32) myPtr + 0x100;

The non portable version ends up in the following error if compiled on a 64 bit system : error: cast from 'void*' to 'uint32 {aka long unsigned int}' loses precision [-fpermissive].

Pointer argument

Passing a pointer as a CINOSTaskExParam (withour ownership handling) requires the following adjustment :

portable :

CMcResult CMyClass::Test(void* apParam, CINOSSync* apSync)
{
msg->AddParam((uintptr) apParam);
PutMsg(msg);
}
void CMyClass::iTest(CINOSTaskExMsg* apMsg)
{
void* pParam = apMsg->GetParam<uintptr>();
// ...
}
Definition inos_syn.h:67
Definition cinostaskex.h:396

not portable :

CMcResult CMyClass::Test(void* apParam, CINOSSync* apSync)
{
msg->AddParam((uint32) apParam);
PutMsg(msg);
}
void CMyClass::iTest(CINOSTaskExMsg* apMsg)
{
void* pParam = apMsg->GetParam<uint32>();
// ...
}

The non portable version ends up in the following error if compiled on a 64 bit system : error: invalid conversion from 'long unsigned int' to 'void*' [-fpermissive].


Printf/scanf format specifiers

Probably the most annoying issues during porting code from a 32 to a 64 bit system are all kind of printf/scanf format specifiers. Due to the fact, that e.g. a variable of type long is always 32 bits on a 32 bit system but 32 or 64 bits on a 64 bit system, we need to use different format specifiers. To simplify this, INOS provides format specifier macros, which behave always correct on all the different platforms (see also inos/os/inos/inc/inostype.h and search for 'format macros'). Example :

portable :

uint32 uCounter = 12;
// ...
INOS_MESSAGE("Counter = " PFU32 " in dec, or Counter = " PF0X32 " in hex, uCounter, uCounter);

not portable :

uint32 uCounter = 12;
// ...
INOS_MESSAGE("Counter = %ld in dec, or Counter = 0x%08lX in hex, uCounter, uCounter);

Hint: We strongly suggest to only work with the provided format macros and to enable the iDev feature 'Build options.Warnings as errors'.