I am using a structs for storing different configurations and I would like to force the initialization of all members. I mean not let the compiler do it (to zero), but the progammer explizitly.
A compiler error would be best but a warning would be fine as well. I am using Segger clang for arm.
Any tips about how to achieve this?
Since I would like to use designated initializers, -Wmissing-field-initializers does not work in this case. See: Docs
typedef struct{
int option_1,
int option_2,
....
} config_t;
// this is fine
const config_t config_1 = {
.option_1 = 10,
.option_2 = 20,
};
// this should generate a warning
const config_t config_1 = {
.option_2 = 20,
};
There's no particularly elegant way to do this programmatically. Best bet is to use a static initializer tool. (There's for example a MISRA-C:2012 rule that can be checked for, requiring that all elements of a struct must be initialized explicitly.)
With pure standard C, well...
Since this struct won't have any padding, I suppose you could cook up something fairly ugly like this:
#define CONFIG_INIT_LIST1 10, 20
#define CONFIG_INIT_LIST2 10
_Static_assert(sizeof (int[]){CONFIG_INIT_LIST1} == sizeof (config_t),
"CONFIG_INIT_LIST1 wrong number of initializers.");
_Static_assert(sizeof (int[]){CONFIG_INIT_LIST2} == sizeof (config_t),
"CONFIG_INIT_LIST2 wrong number of initializers.");
// this is fine
const config_t config_1 = {
CONFIG_INIT_LIST1
};
const config_t config_2 = {
CONFIG_INIT_LIST2
};
This gives the compiler error
error: static assertion failed: "CONFIG_INIT_LIST2 wrong number of initializers."
Related
I am trying to initialize properly this struct:
typedef struct
{
TU_ApplicationData uApplicationData;
TS_SHA_Padding sSHA_Padding;
TU_ApplicationNonVolatileData uApplicationNonVoltatileData;
TS_SHA_Digest sSHA_Digest;
}TS_ApplicationFooter;
As you can see, it is composed with other structure:
typedef struct
{
uint32_t u32ApplicationVersion_Major;
uint32_t u32ApplicationVersion_Minor;
fpJumpHandler fpApplicationJumpHandler;
uint32_t u32BootApplicationStartAddress;
uint32_t u32BootApplicationAllocationSize;
uint32_t u32UserApplicationStartAddress;
uint32_t u32UserApplicationAllocationSize;
}TS_ApplicationData;
typedef union
{
uint32_t au32ApplicationData[32];
TS_ApplicationData sApplicationData;
}TU_ApplicationData;
typedef struct
{
uint32_t u32SHA_1PaddingBytes[16];
}TS_SHA_Padding;
typedef struct
{
uint8_t u8ApplicationNonVoltatileData[256];
}TU_ApplicationNonVolatileData;
typedef struct
{
uint32_t au32ApplicationHashTag[16];
}TS_SHA_Digest;
I cannot find the proper way to initialize the TS_ApplicationFooter structure. The best way that I have is the following, but it returns me the warning: "missing braces around initializer [-Wmissing-braces]".
const TS_ApplicationFooter sUserApplicationFooter =
{ /* Warning point here */
.uApplicationData=
{
.au32ApplicationData={0},
.sApplicationData=
{
.u32ApplicationVersion_Major=U32_USB_CDC_USER_APP_SW_RELEASE_MAJOR_VERSION,
.u32ApplicationVersion_Minor=U32_USB_CDC_USER_APP_SW_RELEASE_MINOR_VERSION,
.fpApplicationJumpHandler=NULL,
.u32BootApplicationStartAddress=U32_BOOT_LOADER_APPLICATION_START_ADDRESS,
.u32BootApplicationAllocationSize=U32_BOOT_LOADER_APPLICATION_ALLOCATED_SIZE,
.u32UserApplicationStartAddress=U32_USER_APPLICATION_START_ADDRESS,
.u32UserApplicationAllocationSize=U32_USER_APPLICATION_ALLOCATED_SIZE
}
},
.sSHA_Padding={0},
.uApplicationNonVoltatileData={0},
.sSHA_Digest={0}
};
Do you have any idea on how I could initialize this structure without having any warning of this kind ?
You should add extra braces around the last three members to appease GCC:
...
.sSHA_Padding={{0}},
.uApplicationNonVoltatileData={{0}},
.sSHA_Digest={{0}}
};
This might be a bug in GCC. Clang does not show this warning, even if compiled with -Wall -W -Wmissing-braces -pedantic.
Alternatively, since as soon as you initialize one member member of a struct, all other members that are not explicitly initialized are initialized to zero, you can just omit them.
Furthermore, you should only initialize exactly one member of a union! I recommend you rewrite the whole initialization like so:
const TS_ApplicationFooter sUserApplicationFooter =
{
.uApplicationData =
{
.sApplicationData =
{
.u32ApplicationVersion_Major = U32_USB_CDC_USER_APP_SW_RELEASE_MAJOR_VERSION,
.u32ApplicationVersion_Minor = U32_USB_CDC_USER_APP_SW_RELEASE_MINOR_VERSION,
.u32BootApplicationStartAddress = U32_BOOT_LOADER_APPLICATION_START_ADDRESS,
.u32BootApplicationAllocationSize = U32_BOOT_LOADER_APPLICATION_ALLOCATED_SIZE,
.u32UserApplicationStartAddress = U32_USER_APPLICATION_START_ADDRESS,
.u32UserApplicationAllocationSize = U32_USER_APPLICATION_ALLOCATED_SIZE
}
},
};
Hi I am following the book Linux device driver development to write a driver in Linux. In an example code as below:
struct my_gpios {
int reset_gpio;
int led_gpio;
};
static struct my_gpiosneeded_gpios = {
.reset_gpio = 47;
.led_gpio = 41;
};
static struct resource needed_resources[] = {
[0] = { /* The first memory region */
.start = JZ4740_UDC_BASE_ADDR,
.end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
.flags = IORESOURCE_MEM,
.name = "mem1",
},
[1] = {
.start = JZ4740_UDC_BASE_ADDR2,Platform Device Drivers
[ 126 ]
.end = JZ4740_UDC_BASE_ADDR2 + 0x10000 -1,
.flags = IORESOURCE_MEM,
.name = "mem2",
},
};
static struct platform_devicemy_device = {
.name = "my-platform-device",
.id = 0,
.dev = {
.platform_data = &needed_gpios,
},
.resource = needed_resources,
.num_resources = ARRY_SIZE(needed_resources),
};
platform_device_register(&my_device);
I do not understand the syntax static struct_gpiosneeded_gpios = {} meaning and why have a dot in .reset_gpio. And what is the meaning of the syntax static struct [] = {[0]={}, [1]={}}?
Could you please give me a reference link or keyword or example about static struct {.a = VALUE, .b = VALUE,};?
static struct something x = {
.field_one = 123,
.field_two = 456
};
This is a struct initialization syntax, standard from C99 (see here). This example creates a variable of type struct something named x, with fields field_one and field_two initialized to the specified values, and any other field initialized to 0. The static keyword is a storage duration specifier (see here).
static struct something x[] = {[0]={ ... }, [1]={ ... }};
This is a mix of both struct initialization and array initialization syntax, again standard from C99 (see here). This example creates an array x of variables of type struct something, the one at index 0 is initialized with the contents of the {...} initializer, and the same goes for the one at index 1. Since the greatest specified index is 1, the array size is 2.
I do not understand why they named the type is u32 or what is the purpose of __raw.
The u32 type is just a short alias for uint32_t.
I am not sure exactly where you saw __raw, since I don't seem to find anything like it in the kernel source. In any case, the Linux kernel as a series of compile-time annotations used for variables that have different purposes (__user, __rcu, etc). Those are not part of the C standard and frequently not even GCC extensions. They are mostly hints to be used by Sparse, the Linux kernel semantic checker.
Is there any standard or rule for naming the variable, macro, type,... in kernel?
Refer to the Linux kernel coding style documentation page for more information. I would suggest you to read it all before trying to do any kind of kernel programming. The more documentation pages you read, the better.
And what C standard i have to compliance when writing code in linux driver?
Use anything that is C99 or older and you will be fine. The Linux kernel code does not adhere to a single C standard, and various parts of the code aren't even standard compliant, but use GCC extensions. See here for more information.
You don't usually choose the standard when compiling, the kernel Makefile does this for you, and it should default to C90.
In any case, those are a lot of questions. If you have a specific question I would suggest you to ask it separately so that people are able to give you a focused and more extensive answer, since it's off topic to ask too broad or too many questions.
I'm writing my own enums-based backtrace. Basically each function call will append it's error to a pre-defined stack which will eventually include all errors across all function calls.
I want to create an efficient way to parse it. In the end I got int backtrace[] with enum values from all over my codebase, and I'd like to relate each enum value to it's name.
This should of course be done post-failure (not at runtime), so what I'm missing is a way, maybe as a part of the compilation step, to dump all my enums and there values to a file. Then i can write a script that parse the errors.
Is there an easy (cross-platform) static tool that does that?
Not sure how you log the errors, but how about:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
} error_t;
typedef struct
{
error_t code;
char * error_name;
} backtrace_entry_t;
backtrace_entry_t backtrace[..];
#define FUNC_EXIT(error_code__) \
do { \
backtrace[func_id].code = (error_code__); \
backtrace[func_id].error_name = #error_code__; \
} while (0)
Then, when you call FUNC_EXIT(E_SUCCESS);, you'll get for the backtrace for the function to be: {.code = 0, .error_name = "E_SUCCESS"}
The problem is, you can't get the right name if you call FUNC_EXIT(var);, where var is some local variable.
Another option, although still not an automagical one:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
NOF_ERROR_CODES
} error_t;
#define MAP_E_CODE_TO_NAME(error_code__) [error_code__] = #error_code__
const char * error_to_name_mapping[NOF_ERROR_CODES] = {
MAP_E_CODE_TO_NAME(E_SUCCESS),
MAP_E_CODE_TO_NAME(E_FAIL),
...
};
Will give a const char * array with {"E_SUCCESS", "E_FAIL", ...}, which you can use like this:
printf("The name of error code %d is '%s'", error, error_to_name_mapping[error]);
The problem here is that you have to have positive value to errors with increasing values.
I'm having trouble passing a struct into a function and I am running into an error:
'PWM_PINS' undeclared (first use in this function)
I am typically able to do this in a C++ compiler without any trouble. I would appreciate some advice as to what I might be doing wrong here.
I have included the relevant parts from the header and c file below.
pwm.h file:
typedef struct PWM_tag{
int PWM_1;
int PWM_2;
int PWM_3;
int PWM_4;
int PWM_5;
int PWM_6;
} PWM;
void PWM_Set( uint32_t channelNum, uint32_t cycle, PWM PWN_PINS );
pwm.c file:
#include "pwm.h"
void PWM_Set( uint32_t ChannelNum, uint32_t cycle, PWM PWN_PINS)
{
if ( ChannelNum == 1 )
{
LPC_PWM1->MR0 = cycle;
LPC_PWM1->MR1 = PWM_PINS.PWM_1;
LPC_PWM1->MR2 = PWM_PINS.PWM_2;
LPC_PWM1->MR3 = PWN_PINS.PWM_3;
LPC_PWM1->MR4 = PWM_PINS.PWM_4;
LPC_PWM1->MR5 = PWM_PINS.PWM_5;
LPC_PWM1->MR6 = PWM_PINS.PWM_6;
}
return;
}
You declared a parameter called PWN_PINS (with an N), but you are referring to PWM_PINS (with an M).
Fixing this typo will address this particular error. There may be more errors, though - it's hard to tell, because the snippet does not show essential parts, such as the declaration of LPC_PWM1 variable.
Is there misspelling in the code?
The function parameter is PWN_PINS.But the code have 5 PWM_PINS, and one PWN_PINS.
I think what you should do is to change all PWN_PINS to PWM_PINS.
I am working on an embedded application where the device is controlled through a command interface. I mocked the command dispatcher in VC and had it working to my satisfaction; but when I then moved the code over to the embedded environment, I found out that the compiler has a broken implementation of pointer-to-func's.
Here's how I originally implemented the code (in VC):
/* Relevant parts of header file */
typedef struct command {
const char *code;
void *set_dispatcher;
void *get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, &set_##dispatcher, &get_##dispatcher, (const char*)description}
/* Dispatcher data structure in the C file */
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)"),
COMMAND_ENTRY("IP", Ip, "IP Address (192.168.1.205)"),
COMMAND_ENTRY("SM", Subnet, "Subunet Mask (255.255.255.0)"),
COMMAND_ENTRY("DR", DefaultRoute, "Default router (192.168.1.1)"),
COMMAND_ENTRY("UN", Username, "Web username"),
COMMAND_ENTRY("PW", Password, "Web password"),
...
}
/* After matching the received command string to the command "label", the command is dispatched */
if (pc->isGetter)
return ((get_fn_t)(commands[i].get_dispatcher))(pc);
else
return ((set_fn_t)(commands[i].set_dispatcher))(pc);
}
Without the use of function pointers, it seems like my only hope is to use switch()/case statements to call functions. But I'd like to avoid having to manually maintain a large switch() statement.
What I was thinking of doing is moving all the COMMAND_ENTRY lines into a separate include file. Then wraps that include file with varying #define and #undefines. Something like:
/* Create enum's labels */
#define COMMAND_ENTRY(label,dispatcher,description) SET_##dispatcher, GET_##dispatcher
typedef enum command_labels = {
#include "entries.cinc"
DUMMY_ENUM_ENTRY} command_labels_t;
#undefine COMMAND_ENTRY
/* Create command mapping table */
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, SET_##dispatcher, GET_##dispatcher, (const char*)description}
const command_t commands[] = {
#include "entries.cinc"
NULL /* dummy */ };
#undefine COMMAND_ENTRY
/*...*/
int command_dispatcher(command_labels_t dispatcher_id) {
/* Create dispatcher switch statement */
#define COMMAND_ENTRY(label,dispatcher,description) case SET_##dispatcher: return set_##dispatcher(pc); case GET_##dispatcher: return get_##dispatcher(pc);
switch(dispatcher_id) {
#include "entries.cinc"
default:
return NOT_FOUND;
}
#undefine COMMAND_ENTRY
}
Does anyone see a better way to handle this situation? Sadly, 'get another compiler' is not a viable option. :(
--- Edit to add:
Just to clarify, the particular embedded environment is broken in that the compiler is supposed to create a "function-pointer table" which is then used by the compiler to resolve calls to functions through a pointer. Unfortunately, the compiler is broken and doesn't generate a correct function-table.
So I don't have an easy way to extract the func address to invoke it.
--- Edit #2:
Ah, yes, the use of void *(set|get)_dispatcher was my attempt to see if the problem was with the typedefine of the func pointers. Originally, I had
typedef int (*set_fn_t)(cmdContext_t *pCmdCtx);
typedef int (*get_fn_t)(cmdContext_t *pCmdCtx);
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
You should try changing your struct command so the function pointers have the actual type:
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
Unfortunately, function pointers are not guaranteed to be able to convert to/from void pointers (that applies only to pointers to objects).
What's the embedded environment?
Given the information posted in the updates to the question, I see that it's really a bugged compiler.
I think that your proposed solution seems pretty reasonable - it's probably similar to what I would have come up with.
A function pointer isn't actually required to fit in a void*. You could check to make sure that the value you're calling is actually the address of the function. If not, use a function pointer type in the struct: either get_fn_t, or IIRC void(*)(void) is guaranteed to be compatible with any function pointer type.
Edit: OK, assuming that calling by value can't be made to work, I can't think of a neater way to do what you need than auto-generating the switch statement. You could maybe use an off-the-shelf ASP-style preprocessor mode for ruby/python/perl/php/whatever prior to the C preprocessor. Something like this:
switch(dispatcher_id) {
<% for c in commands %>
case SET_<% c.dispatcher %>: return set_<% c.dispatcher %>(pc);
case GET_<% c.dispatcher %>: return get_<% c.dispatcher %>(pc);
<% end %>
default:
return NOT_FOUND;
}
might be a bit more readable than the macro/include trick, but introducing a new tool and setting up the makefiles is probably not worth it for such a small amount of code. And the line numbers in the debug info won't relate to the file you think of as the source file unless you do extra work in your preprocessor to specify them.
Can you get the vendor to fix the compiler?
To what extent is the pointer-to-function broken?
If the compiler allows you to get the address of a function (I'm from C++, but &getenv is what I mean), you could wrap the calling convention stuff into assembler.
As said, I'm a C++ssie, but something in the way of
; function call
push [arg1]
push [arg2]
call [command+8] ; at the 4th location, the setter is stored
ret
If even that is broken, you could define an array of extern void* pointers which you define, again, in assembly.
try this syntax:
return (*((get_fn_t)commands[i].get_dispatcher))(pc);
It's been awhile since I've done C & function pointers, but I believe the original C syntax required the * when dereferencing function pointers but most compilers would let you get away without it.
Do you have access to the link map?
If so, maybe you can hack your way around the wonky function-pointer table:
unsigned long addr_get_dhcp = 0x1111111;
unsigned long addr_set_dhcp = 0x2222222; //make these unique numbers.
/* Relevant parts of header file */
typedef struct command {
const char *code;
unsigned long set_dispatcher;
unsigned long get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label,
addr_set_##dispatcher, addr_get_##dispatcher, (const char*)description}
Now compile, grab the relevant addresses from the link map, replace the constants, and recompile. Nothing should move, so the map ought to stay the same. (Making the original constants unique should prevent the compiler from collapsing identical values into one storage location. You may need a long long, depending on the architecture)
If the concept works, you could probably add a post-link step running a script to do the replacement automagically. Of course, this is just a theory, it may fail miserably.
Maybe, you need to look into the structure again:
typedef struct command {
const char *code;
void *set_dispatcher; //IMO, it does not look like a function pointer...
void *get_dispatcher; //more like a pointer to void
const char *_description;
} command_t;
Let say your dispatchers have the following similar function definition:
//a function pointer type definition
typedef int (*genericDispatcher)(int data);
Assume that the dispatchers are like below:
int set_DhcpDispatcher(int data) { return data; }
int get_DhcpDispatcher(int data) { return 2*data; }
So, the revised structure will be:
typedef struct command {
const char *code;
genericDispatcher set_dispatcher;
genericDispatcher get_dispatcher;
const char *_description;
} command_t;
Your macro will be:
#define COMMAND_ENTRY(label,dispatcher,description) \
{ (const char*)label, \
set_##dispatcher##Dispatcher, \
get_##dispatcher##Dispatcher, \
(const char*)description }
Then, you can set your array as usual:
int main(int argc, char **argv)
{
int value1 = 0, value2 = 0;
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)")
};
value1 = commands[0].set_dispatcher(1);
value2 = commands[0].get_dispatcher(2);
printf("value1 = %d, value2 = %d", value1, value2);
return 0;
}
Correct me, if I am wrong somewhere... ;)