How to create FMU source code for Linux 64 in windows with LONG_MAX set to 64 bit

58 visualizzazioni (ultimi 30 giorni)
Creating an FMU with Hardware Implementation 'Device Vendor' set to either 'AMD' or 'Intel' and 'Device Type' to be 'x86-64 (Linux 64)' generates C code with a compile check for 32 bit "long" data type.
#if ( ULONG_MAX != (0xFFFFFFFFU) ) || ( LONG_MAX != 0x7FFFFFFF) )
Even tried with different toolchains for embedded Linux 64 bit.
Is it not possible via FMU to create C code for Linux 64 bits where "long" is 64 bits?

Risposte (1)

Andy Bartlett
Andy Bartlett il 17 Ott 2022
Modificato: Andy Bartlett il 18 Ott 2022
Simpler need
If you're goal is just to have the size of long defined as 32-bits in the generated code, then you can change the settings on the Hardware Implementation pane of your Configuration Parameters dialog of your Simulink model (or similar dialog in MATLAB Coder projects). Click the toggle "Device Details" to see what size is being used for long in the generated production code.
Linux 64-bit is an LP64 architecture and will always define long as 64-bits. To get long to be 32-bits you want a different architecture such as 64-bit Windows which is LLP64, or you can choose custom on the Hardware Implementation pane and explicitly set the individual word lengths for the five integer types.
Note: I suspect you'll want to check the box on the Hardware Implementation pane "Support long long" so that you will have a 64-bit integer type available.
More complex need, portability
If you are seeking to get generated code that can be recompiled for both Linux 64 and Windows 64 without re-generating the code that is harder.
The C and C++ languages are not designed to be portable with regard to the size of integers. MathWorks Coders take care to make sure that integer and fixed-point code have bit-true agreement with simulation behavior. Coders also seek to make the generated bit-true code as performant as possible for the target for which code is being generated. Compiling that code on a target with different sizes for any of the 5 integer types could lead to incorrect behavior.
The preprocessor checks of integer max values are designed to make sure that code does not silently give incorrect answers due to compiling code intended for a "target A" on a "different size target B".
The Portable word sizes feature is intended to provide code that supports two slightly different targets. One target is the Production Target as defined on the Hardware Implementation pane. The other target is the current MATLAB Host. This feature may solve your problem. If you configure the production target to be an LP64 and generate code on an LLP64 MATLAB host or visa versa with "support long long" on, you can expect Portable word sizes feature to modify the code to avoid depending on the size of long which would vary between 32 bits and 64 bits.
There is also a "remove the safety rails options." As described on this doc page,
set_param(gcs, 'TLCOptions', ...
'-aRemoveFixptWordSizeChecks=1')
This will remove the preprocessor check, but there could be silent disagreements with simulation depending on what the code contains. For example, a literal constant like 34LU may be treated as 32 bits on one platform and 64 bits on another. This could lead to silent changes due to C and C++ usual binary type promotion rules and overflow behaviors.
  2 Commenti
R
R il 2 Nov 2023
My company has been using MATLAB for many years on the same project. Our target includes all the following: Pentium X86 32 bit CPU, a PPC 32 bit CPU, PPC-SPE 32 bit CPU and now the AARCH 64 bit CPU (little endian). There are about 50 models running on each of these machines. The generated model code contains the same check as indicated above: #if ( ULONG_MAX != (0xFFFFFFFFU) ) || ( LONG_MAX != 0x7FFFFFFF) ). To compile on the 64 bit machine, I am currently hacking this check from the auto-generated code.
What is the safest, most efficient way to generate code that will execute on all these targets? Is this the recommended approach:
set_param(gcs, 'TLCOptions', ... '-aRemoveFixptWordSizeChecks=1')
and/or
should we be setting the Portable Word Sizes option? This latter options seems more geared towards development workstation vs target but is it also applicable to portable code for multiple word sized targets such as we have?
Andy Bartlett
Andy Bartlett il 2 Nov 2023
Modificato: Andy Bartlett il 2 Nov 2023
Glad to hear you've been successful at generating code that can port to many targets.
One of the biggest source of integer portability issues is C's usual unary and binary type promotion rules. The rule of promoting anything smaller than an int up to int before performing an operation can have dramatic impacts.
Sounds like your targets have mostly common sizes
char = 8 bits, short = 16 bits, int = 32 bits, and long long = 64 bits
with int always being 32 bits making portability much easier.
Only the size of long varies by target. Two main things you need to avoid due to long variability are.
  • Make sure 64-bit constants are marked with 'LL' rather than 'L'
  • Make sure 32-bit constants are NOT marked with 'L'
  • Use portable typedefs such as int8_T, ... uint64_T
  • make sure typedef for int64_T in rtwtypes.h maps to long long (NOT long)
Setting your hardware implemenation production target to have long set to 32 bits and using coder typedefs should take care of those needs. But since you've had this working for years, you shouldn't need to change anything.
Removing integer size checks
The integer sizes preprocessor check covers all the C types. You're current process for modifying the checks is just removing the check for long.
Using the option
set_param(gcs, 'TLCOptions', ... '-aRemoveFixptWordSizeChecks=1')
will remove all the checks not just the check for long. If you're not concerned about feeding the code to a target with incompatibile sizes, then using the option is probably easier than modify the code after generation.
Portable Word Sizes feature
The portable word sizes feature is design to allow the code to work correctly on one embedded target and the MATLAB host on which the code was generated.
As mentioned above, I recommend your model's hardware implemenation production target to have long set to 32 bits.
If the MATLAB host you will use to generated code will always have long of 64 bits, such as 64-bit linux, then the portable word sizes feature may modify the generated code in ways beneficial to portability.
But if the MATLAB host you will use to generated code has long of 32 bits, such as Windows, then the MATLAB host and hardware implemenation production target will have the same attributes, so I would not expect Portable Word Sizes to do anything.
Since you reported successfully generating code portable for your needs for many years, it seems unlikely you need Portable Word Sizes.

Accedi per commentare.

Tag

Prodotti


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by