error: storage class may not be specified here when using __align() in MDK ARM uVision v5 ARM Compiler 5 - alignment

I am migrating a project from CubeIDE (GCC) to the most comprehensive software development solution for Arm®-based microcontrollers uVision (ARM Compiler 5) and have a difficulty using __align keyword.
CubeIDE code which compiles fine in CubeIDE:
#include <stdalign.h>
typedef struct {
volatile alignas(uint32_t) uint16_t imageDark[320];
} test_results;
First issue is that uVision cannot locate <stdalign.h> which is part of standard library of the C programming language:
..\Src\device_tests.c(3): error: #5: cannot open source input file "stdalign.h": No such file or directory
So I removed <stdalign.h> and based on these KEIL documentation rewrote my code to
typedef struct {
volatile __align(__ALIGNOF__(uint32_t)) uint16_t imageDark[320];
} test_results;
Now I am receiving the following error:
..\Src\device_tests.c(46): error: #80: a storage class may not be specified here
volatile __align(__ALIGNOF__(uint32_t)) uint16_t imageDark[320];
..\Src\device_tests.c(46): error: #328: invalid storage class for a class member
volatile __align(__ALIGNOF__(uint32_t)) uint16_t imageDark[320];
Any help on how to make alignment work in uVision would be greatly appreciated.

I found out that the problem was that I was trying to align inside a struct. The above-mentioned syntax works for variables outside a struct. However to make it work inside struct I used the following syntax:
typedef struct {
volatile uint16_t imageDark[320] __attribute__((aligned (4)));
} test_results;

Related

Trouble getting started with Metal shader compilation

I'm having trouble getting started with Metal's shader compilation.
How to make a MTLLibrary that can link to a MTLDynamicLibrary (or MTLLinkedFunctions), in particular a library that declares extern functions that are to be resolved at runtime when providing preloadedLibraries (or linkedFunctions) in the compute pipeline descriptor? For example, I can compile the following to air using xcrun metal (with option -c), but then invoking xcrun metallib (even with option --split-module-without-linking) gives the error LLVM ERROR: Undefined symbol: _Z3addjj. In other words, how do I make a 'partially bound' metal library?
// shader.h
extern uint add(uint a, uint b);
/// shader.metal
#include "shader.h"
kernel void kernel_func(uint gid [[ thread_position_in_grid ]]) { add(gid,2); }
WWDC2021 mentions this extern technique, but the Dynamic Library Code Sample from the previous year doesn't use extern (or the installName), so I don't make sense of it.
When creating an executable library that uses a dynamic library, there are two points where you must include the dynamic library (I thought there was only one).
The process is different depending on whether the executable source is compiled at build or runtime. I'll describe for the case of runtime, because I haven't yet figured out the case for the executable library created from a metallib file.
The first point is when you compile the executable, where you must include the dynamic library in the libraries field of the CompileOptions. The library is there at this point just as a dummy, to check that you have a dynamic library that defines the declarations allowing for proper linkage, though that linkage doesn't occur at this stage, just the checking.
The second point is when you create the pipeline state, where you must include the dynamic library in the preloadedLibraries field of the pipeline descriptor. This time, the dynamic library is not a dummy but the real library you plan to use, as it will be linked with the executable during pipeline creation.

Using splint for static code analysis on windowms with MPLAB how to avoid system file parse errors

I'm using MPLAB X (3.26) with a PIC32 on windows (XC32 v1.40 compiler). I'm trying to use splint to do static code analysis on someones code as part of a review. I've got most of the compiler defines and search paths sorted, but are a bit stumped when it comes to avoiding the parse errors in the PIC32 std include files.
The command I am using to run splint is
splint ^
-D"__32MX370F512L__" ^
-D"__PIC32_FEATURE_SET__"=370 ^
-D"__LANGUAGE_C__" ^
+I"C:/Program Files (x86)/Microchip/xc32/v1.40/pic32mx/include/" ^
main.c
The output then gives
< Location unknown >: Field name reused:
Code cannot be parsed. For help on parse errors, see splint -help
parseerrors. (Use -syntax to inhibit warning)
< Location unknown >: Previous use of
< Location unknown >: Previous use of
.... approx 100 times then...
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(4,18):
Datatype ptrdiff_t declared with inconsistent type: long int
A function, variable or constant is redefined with a different type. (Use
-incondefs to inhibit warning)
load file standard.lcd: Specification of ptrdiff_t: arbitrary integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(5,27):
Datatype size_t declared with inconsistent type: unsigned long int
load file standard.lcd: Specification of size_t:
arbitrary unsigned integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stddef.h(6,13):
Datatype wchar_t declared with inconsistent type: int
load file standard.lcd: Specification of wchar_t: arbitrary integral type
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stdarg.h(75,36):
No type before declaration name (implicit int type): __builtin_va_list :
int
A variable declaration has no explicit type. The type is implicitly int.
(Use -imptype to inhibit warning)
C:\Program Files (x86)\Microchip\xc32\v1.40\pic32mx\include\\stdarg.h(75,36):
Parse Error: Suspect missing struct or union keyword: __builtin_va_list :
int. (For help on parse errors, see splint -help parseerrors.)
*** Cannot continue.
The last one causes things to stop. I've tried things like -skip-iso-headers with no luck. It seems it is seeing issues with its standard.lcd file and the xc32 std files
Can anyone tell me
What the < Location unknown >: Field name reused: means or possibly is referring to?
A way to resolve the parse error due to the std header files?
So far only way to solve the header file issue is to define the types, e.g.
-D"__builtin_va_list"=int ^
I think your code (or some code that you #include) is using anonymous bitfields or/and structs. Anonymous structs and anonymous unions are provided by a GNU extension for versions of C earlier than C11. Since Splint doesn't know about C11 (I only found mentions of C99 in the manual, and google agrees) and only partial support for the GNU extensions (search for gnu-extensions), it has a hard time parsing them.
I had a similar problem with some code written for a PIC18f46k22, though I was using sdcc instead of XC8.
The issue was with pic18f46k22.h, which had anonymous structs (bitfields, specifically) inside a typedef union.
This code...
typedef union
{
struct
{
unsigned name0 : 1;
unsigned name1 : 1;
unsigned name2 : 1;
unsigned name3 : 1;
unsigned name4 : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
};
struct
{
unsigned name : 6;
unsigned : 2;
};
} __NAMEbits_t;
...would produce these errors...
< Location unknown >: Field name reused:
Code cannot be parsed. For help on parse errors, see splint -help
parseerrors. (Use -syntax to inhibit warning)
< Location unknown >: Previous use of
...but this code wouldn't.
struct indv
{
unsigned name0 : 1;
unsigned name1 : 1;
unsigned name2 : 1;
unsigned name3 : 1;
unsigned name4 : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
};
struct all
{
unsigned name : 6;
unsigned : 2;
};
typedef union
{
struct indv individualbits;
struct all allbits;
} __NAMEbits_t;
I am working with a different processor, compiler, and static analysis tool (PRQA / Helix QAC), but I think we are facing the same problem regarding the parse issue of the standard header files. It took me some time to figure out what is going on.
For one thing, I can say that your workaround is good enough and apparently you should not worry about it too much. I used a slightly different workaround described here:
Pycparser not working on preprocessed code
-D __builtin_va_list = struct __builtin_va_list {}
I guess another way would be to use stub standard headers instead of the real ones. My tool manual claims, for example, that there should be such header files supplied with the tool, although I haven't found/obtained them yet.

implicit declaration of function when compiling kernel module

I am new to working in kernel space, so I hope someone can help me with the issue I am having.
I have seen a lot of questions related to implicit declaration of function for userspace c/c++ programs, but I think the issue I am having may be approached differently in kernel space.
The code I am working on is to test out signaling a user application from the driver, which I have working, but the issue was I could not use the function send_sig_info declared in linux/signal.h until I had declared it in the header of my own driver source. I figured if I had included to correct header to access the function call declared there, it should work.
So without the declaration of send_sig_info in my own header:
error: implicit declaration of function ‘send_sig_info’
And then adding to my header file:
static int send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
would allow my code to compile just fine.
Does anyone have an idea why this is?
Thanks.

Lua - "multiple vms detected" while trying to add extension for statically linked Lua

I have application that contain statically linked lua 5.2 inteperpreter (and haven't access to code).
When I trying to write extension with next code:
#define LUA_LIB
#define LUA_BUILD_AS_DLL
#include "lua.hpp"
extern "C"
{
static int test(lua_State* state)
{
return 1;
}
static const struct luaL_Reg functions[] = {
{"test", test},
{NULL, NULL},
};
int __declspec(dllexport) luaopen_test(lua_State* state)
{
luaL_newlibtable(state, functions);
luaL_setfuncs(state, functions, 0);
return 0;
}
}
And compile it with statically linked lua52.lib .
I get "multiple vms detected" error when I trying to require it fromn lua code.
What I can do in this situation?
You can't compile it with statically linked lua52.lib as the main application loads its own version of lua52.lib and when this module is "required", it loads its own copy, which leads to "multiple VMs detected" message.
With statically compiled VM you have two options (on Windows): (1) include all your modules statically, or (2) compile your modules against Lua52.dll, but instead of the actual DLL include a "proxy" DLL that will forward Lua API calls to the methods in the statically compiled executable (the API methods also need to be exported in the executable).
See this thread for the discussion on how the executable needs to be compiled and LuaProxyDllFour page for the proxy DLL.
On Linux you don't need to have a proxy library, but you still need to avoid linking Lua interpreter into the library and export symbols from the executable by using -Wl,-E linker option; see lhf's answer for details.

How does CLR match the exported names during P/Invoke?

I work on a project that requires .Net interoperability with unmanaged code. I started to work with .Net a couple of weeks ago, though I have a lot of experience with C/C++, and I am surprised how CLR deals with P/Invoke. Here are the details. My colleague wrote this function
__declspec(dllexport) int __stdcall ReadIPWSensor(unsigned int deviceClassId, void *buffer) {...}
and I had to call it from C# module. I imported the function as
[DllImport("ipw", CallingConvention = CallingConvention.StdCall)]
extern static int ReadIPWSensor(uint deviceClassId, IntPtr buffer);
just to find out an exception (System.EntryPointNotFoundException, Unable to find an entry point named 'ReadIPWSensor' in DLL 'ipw'). I used DependencyWalker tool and found that the function was exported as ?ReadIPWSensor##YGHIPAX#Z (my colleague forgot to export it in the DEF file). Just for the quick test (the unmanaged DLL compiles very slowly) I changed my import definition to:
[DllImport("ipw", EntryPoint = "#22", CallingConvention = CallingConvention.StdCall)]
extern static int ReadIPWSensor(uint deviceClassId, IntPtr buffer);
as the ordinal was 22. The test passed successfully with the new import definition.
My first question is: What are the good practices when dealing the mangled function exports? Is it a good practice to use the export ordinals?
In my case I had access to the C++ source code and the DEF file so I added the export and changed back the import definition to
[DllImport("ipw", CallingConvention = CallingConvention.StdCall)]
extern static int ReadIPWSensor(uint deviceClassId, IntPtr buffer);
I knew there is another function we already use in our project and wanted to compare my code with the existing one. The function is defined as
extern "C" __declspec(dllexport) int __stdcall LoadIPWData(void
*buffer)
and is imported as
[DllImport("ipw", CallingConvention = CallingConvention.StdCall)]
extern static int LoadIPWData(IntPtr buffer);
To my surprise DependencyWalker tool shows that the function is exported as _LoadIPWData#4 (my coworker forgot to export it in the DEF file again). However with this function there is no System.EntryPointNotFoundException error. Obviously, the CLR somehow managed to resolve the right name. It seems there is some sort of fallback mechanism that allows CLR to find the right function. I can easily imagine the it sums the sizes of the parameters and is looking for "function_name#the_sum_of_all_parameter_sizes" though it seems quite simplistic.
My second question is: How does CLR match the exported function names during P/Invoke?
In this scenario I think CLR is so clever that it actually hides a bug - LoadIPWData function should be accessible by its name from other unmanaged modules. Maybe I am a bit of paranoid but I prefer to know how actually CLR works. Unfortunately all my google searches on that topic were fruitless.
The pinvoke marshaller has built-in knowledge of a few common DLL export naming schemes. It knows that __cdecl functions often have a leading underscore and that __stdcall in 32-bit mode is commonly decorated with a leading underscore and a trailing #x where x is the size in bytes of the arguments passed on the stack. It also knows that winapi functions are exported with a trailing extra A or W, a naming scheme to distinguish functions that accept strings and for which there's both an ansi and a Unicode version. The corresponding [DllImport] property is CharSet. It just tries them all until it finds a match.
It doesn't know anything about C++ compiler name decoration rules (aka mangling) so that's why you have to use extern "C" to suppress that by hand.

Resources