Consider this code:
int procmon_state = 0;
static struct ctl_table_header *procmon_table_header;
static ctl_table state_table[] = {
{
.procname = "state", .mode = 0666,
.proc_handler = &proc_dointvec_minmax,
.data = &procmon_state, .maxlen = sizeof(int),
.extra1 = "\x00\x00\x00\x00" /*0*/, .extra2 = "\x01\x00\x00\x00" /*1*/
},
{ 0 }
};
static ctl_table procmon_table[] = {
{
.procname = "procmon", .mode = 0555,
.child = state_table
},
{ 0 }
};
procmon_table_header = register_sysctl_table(procmon_table);
This will create an entry in /proc/sys (so I could then just sysctl procmon.state=1).
My question is: Once that entry is created, how can I add more entries?
EDIT: More entries inside procmon, that is. For example, procmon.another_state
There are no functions for changing sysctl tables in sysctl.h.
You have to list all entries that you might need before calling register_sysctl_table.
If you really need to change the table afterwards, you have to call unregister_sysctl_table before doing your modifications, and then register it again.
Yes, you can, just look into the linux kernel's drivers directory for many examples. Essentially, you just need to call register_sysctl_table() multiple times, for for each call you make, you will be creating a branch off an existing branch.
The details are covered here:
https://tthtlc.wordpress.com/2016/05/26/how-to-add-new-entries-to-sysctl-with-the-same-root/
Related
I'm reading some freeRTOS code, and I'm not understanding how a function callbacks work. Take this example. The following function is defined -
static void prov_event_handler(void *user_data,
wifi_prov_cb_event_t event, void *event_data)
{
switch (event) {
case WIFI_PROV_CRED_RECV: {
wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data;
...
}
This is the callback function that we want to call from this code:
/* Configuration for the provisioning manager */
wifi_prov_mgr_config_t config = {
.scheme = wifi_prov_scheme_ble,
.scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM,
.app_event_handler = {
.event_cb = prov_event_handler,
.user_data = NULL
}
};
ESP_ERROR_CHECK(wifi_prov_mgr_init(config));
So far, so good. Where I am confused is where the heck do the parameters come from? When prov_event_handler is run, it has values for event_data. How does this generally work?
Thanks.
As I was studying the code of the mxs-auart.c driver I noticed the following declaration:
enum mxs_auart_type {
IMX23_AUART,
IMX28_AUART,
ASM9260_AUART,
};
and then later on:
static const struct platform_device_id mxs_auart_devtype[] = {
{ .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
{ .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
{ .name = "as-auart-asm9260", .driver_data = ASM9260_AUART },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
static const struct of_device_id mxs_auart_dt_ids[] = {
{
.compatible = "fsl,imx28-auart",
.data = &mxs_auart_devtype[IMX28_AUART]
}, {
.compatible = "fsl,imx23-auart",
.data = &mxs_auart_devtype[IMX23_AUART]
}, {
.compatible = "alphascale,asm9260-auart",
.data = &mxs_auart_devtype[ASM9260_AUART]
}, { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
The thing I don't understand about this is how can IMX28_AUART, for example, be used like .data = &mxs_auart_devtype[IMX28_AUART]. Don't we have to instanciate a variable beforehand to use the enum values by doing as an example enum mxs_auart_type value = IMX28_AUART?
I am aware that in enumerations in C, values are equal to integer starting by default at 0 but I can't help but feel confused about this.
Can anyone help me understand this a bit better?
Thanks
Don't we have to instanciate a variable beforehand to use the enum values by doing as an example enum mxs_auart_type value = IMX28_AUART?
Not at all.
After doing this:
enum MyEnum {A, B, C};
You will have three globally available names: A, B, and C, with fixed integer values of 0, 1, and 2 accordingly.
Take a look at this useful post to know more: "static const" vs "#define" vs "enum".
An enum allows you to give names to constant values. For all intents and purposes, you can treat the enum name as an integer literal.
In this case:
.data = &mxs_auart_devtype[IMX28_AUART]
The name IMX28_AUART is treated like 1, so the code is the same as:
.data = &mxs_auart_devtype[1]
I have two files in Node.js where one requires the other one.
variable_test.js:
TEST = require('./variable_test_external.js');
TEST.get(function(myVariable) {
var changeMeVariable;
console.log(myVariable);
changeMeVariable = myVariable.epicVariable;
changeMeVariable.evenEpicerVariable = "test3";
TEST.get(function(myVariable2) {
console.log(myVariable2);
});
});
variable_test_external.js:
var testVariable = new Array({epicVariable: {evenEpicerVariable: "test1"}}, {epicVariable: {evenEpicerVariable: "test2"}});
exports.get = function(callback) {
callback(testVariable[1]); // I know that the return is unnecessary in this example but in my real application I have return there for compactness.
}
This is the output when run in Node.js with node variable_test.js:
{ epicVariable: { evenEpicerVariable: 'test2' } }
{ epicVariable: { evenEpicerVariable: 'test3' } }
The console.log(myVariable) changes in the two TEST.get's. Why does this happen?
This is a reference copy, not a value copy. You got the object from the array, NOT a copy of them.
changeMeVariable = myVariable.epicVariable;
This would have to fix yout problem
// PSEUDO CODE, i don't know the correct syntax
changeMeVariable = {
epicVariable = myVariable.epicVariable
};
The answer in my case is the following based on the links at the bottom:
changeMeVariable = JSON.parse(JSON.stringify(myVariable.epicVariable));
But, it's much better to manually copy it like the bottom most link like this:
changeMeVariable = {
evenEpicerVariable: myVariable.epicVariable.evenEpicerVariable
}
n0m's answer is similar but if the epicVariable.evenEpicerVariable contained an object that object's reference would still be linked! (I tested it)
References:
What is the most efficient way to deep clone an object in JavaScript?
http://jsperf.com/cloning-an-object/3
I am working on the Keil uv4 IDE with an ARM Cortex-M3 in a bare metal C application. I have a GUI that I created that is currently in English, but I would like to give the user the ability to go between other languages like you can on a cell phone.
I have created a structure with all the words that are used called string_table_t.
struct string_table_t
{
char *word1;
char *word2;
char *word3;
};
My thought process was to have plain text files for the different languages and the list of words used contained in each one. Then I would do a load function that would link the pointers of the string table with the actual word.
Now, my initial menu is created statically by defining it like so. It is based off of Altium software platform.
// Test structure
struct string_table_t string_table = {"Main Menu","test1","test2"};
form_t mainmenu_form =
{
.obj.x = 0,
.obj.y = 0,
.obj.width = 240,
.obj.height = 320,
.obj.draw = form_draw,
.obj.handler = mainmenu_form_handler,
.obj.parent = NULL,
.obj.agui_index = 0,
.obj.visible = __TRUE,
.obj.enabled = __TRUE,
.caption.x = 0,
.caption.y = 0,
.caption.text = "Main Menu",
.caption.font = &helveticaneueltstdltext18_2BPP,
.caption.color = RGB(230,230,230),
.caption_line_color = RGB(241,101,33),
.caption.fontstyle = FS_NONE,
.caption.align = ALIGN_CENTRE,
.captionbarcolor = RGB(88,89,91),
.children = mainmenu_children,
.n_children = 4,
.relief = RELIEF_NONE,
.color = RGB(65,64,66),
};
What I want to do is replace the "Main Menu" of the caption.text with string_table.word1. Therefore, if I load a different language set, the menu will automatically be pointing to the correct char array. Doing this currently results in a error expression must have a constant value.
Now, I can get this to work by leaving the text null in the menu component and adding:
Link_pointer_to_menu() {
mainmenu_form.caption.text = string_table.Main_menu_text;
}
This will compile and work, but I would rather not have to have 100 or so of these statements. Is there a more optimal way of doing this?
I would recommend something like that:
enum MyWords
{
msgHello,
msgOpen,
msgClose,
msgMainMenu,
num_Messages,
};
char *string_table_t[num_Messages];
You should write code that loads your language file and assigns pointers in this array. After that in your code:
.caption.text = string_table_t[msgMainMenu];
The idea is that you give each string a symbolic name that is an offset in the table of strings. After that you use this offset as an index into the table.
I'm looking at the source code in one of the FFMPEG files and found a construct that looks really strange to me. Can sb please explain what is happening here?
init and query_formats are actually functions that have been declared before in the file.
AVFilter avfilter_vf_fade = {
.name = "fade",
.description = NULL_IF_CONFIG_SMALL("Fade in/out input video"),
.init = init,
.priv_size = sizeof(FadeContext),
.query_formats = query_formats,
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_props,
.get_video_buffer = avfilter_null_get_video_buffer,
.start_frame = avfilter_null_start_frame,
.draw_slice = draw_slice,
.end_frame = end_frame,
.min_perms = AV_PERM_READ | AV_PERM_WRITE,
.rej_perms = AV_PERM_PRESERVE, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
};
What are the "." doing in there. How would you access all these points. What would be saved in the compartments of the array (pointer addresses?!)?
I'm a bit confused..
Also, how do you learn about how the code of a third party programmer works, if there are almost no comments around? Documentation doesn't exist either..
PS: This is what the init function looks like:
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
...
}
This is C99.
It allows to initialize structures by name.
For example the structure:
struct foo {
int x,y;
char *name;
};
Can be initialized as:
struct foo f = {
.name = "Point",
.x=10,
.y=20
};
This requires up-to-date compiler that supports the latest
standards: C99.
It's called a designated initializer, and is part of the C99 standard. Have a look here to learn more.