Providing assignments to variables from makefiles/kconfig - c

I have an unsigned long which needs to get a platform specific variable.
I do not wish to use boot parameters as this driver will go into products and vendors are reluctant to change boot parameters.
I would like to know if this variable can be initialized from Makefile or from Kconfig.
I remember that the serial port address for early printk is provided in the Kconfig when I used the menuconfig long back to set it. But I never understood how that worked.

You can pass that value from Kconfig file in that directory of the program file,
You can set the Kconfig to value of the variable which is needed.
Like for example, in the Kconfig, add below configuration for the variable
config MY_VALUE_LONG // config keyword
hex "MY VALUE IS" //What you see in the menuconfig
default 0xAB123 //unsigned long value in hex
In the above Kconfig, MY_VALUE_LONG will hold you long value in the hex format, MY VALUE IS is what that will be displayed when $ make menuconfig is called, and the default value set using the default variable will be passed to the program.
In Program (where the variable value is required), use the config variable CONFIG_MY_VALUE_LONG to obtain the value in hexadecimal
Like for example,
unsigned long value = CONFIG_MY_VALUE_LONG

Find the C file and Makefile implementation in below to meet your requirements
foo.c
main ()
{
int a = MAKE_DEFINE;
printf ("MAKE_DEFINE value:%d\n", a);
}
Makefile
all:
gcc -DMAKE_DEFINE=11 foo.c
MAKE_DEFINE is a define, which is enabled through Makefile

Related

how to use address defined in linkerscript in C source file?

In a C application, I want to place a big buffer at an address after the variables, stack and dma address ranges. Of course I can define a section in the wanted location in the linker script and declare a big array in C and give a section attribute to the array. But I want to do it without actually declaring the big array because it makes the executable too big. I want to use the array address to do the same.
I'm using gcc and try to use an address I define in the linker script inside the C source file.
Here is how I tried it.
in the linker script file (which is ldabtsm.lds.S in my case),
...
. = ALIGN(16777216);
.vimbuffs : {
*(.vimbuffs)
}
vimbuffs = .;
...
I tried using vimbuffs in the C source file.
So I did (if I can print, I can use it anyway..)
extern unsigned int vimbuffs; // from linker script
printf("vimbuffs = %x\n", vimbuffs);
From the map file, I can see the vimbufs is assigned to 0x3b3f6000 which is just right, I want it to be aligned. But when run the program and print the value, I see
vimbuffs = a07f233d
What is wrong?

Strange definition in C with # sign

I have come across following definition in an embedded C source file:
const preamble_t OAD_Preamble # ".preamble" =
{
HAL_OAD_RC_MAX, // Default program length of max if not using post-processing tool.
OAD_MANUFACTURER_ID, // Manufacturer ID
OAD_TYPE_ID, // Image Type
0x00000001 // Image Version
};
I have no idea about the # part, can you please help me with this?
Edit:
This is in IAR compiler, used with TI SoCs.
This is the way you can specify a memory address or a section in which you would like to place your variable.
".preamble" is the name of a section,
OAD_Preamble is the variable to be placed there.
You can also specify physical address after the at # sign:
const unsigned char port_bit # 0x1800 = BIT0;
More information is in this document.
Note: this is a non-portable compiler extension, not a part of the standard C syntax.

C - LuaJit Assign custom module name to a compiled string

I have a small C program that has a string which must represent a Lua module and it looks like this:
const char *lua_str = " local mymodule = {} \
function mymodule.foo() \
print(\"Hello World!\") \
end
return mymodule";
Or maybe using the old way (if required):
const char *lua_str = "module(\"mymodule\", package.seeall \
function foo() \
print(\"Hello World!\") \
end";
And let's assume that this is my small host application:
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(int argc, char** argv)
{
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dostring(L, lua_str);
luaL_dofile(L, "test.lua");
return 0;
}
Now in test.lua to be able to use that module with a static name that isn't decided by the file name:
local mymodule = require "mymodule"
mymodule.foo()
Basically, I need to execute that string and give it a custom name which represents the actual module name. Currently the name is decided by the file name and I don't want that.
If you look at the documentation for require:
Loads the given module. The function starts by looking into the
package.loaded table to determine whether modname is already loaded.
If it is, then require returns the value stored at
package.loaded[modname]. Otherwise, it tries to find a loader for the
module.
To find a loader, require is guided by the package.loaders array. By
changing this array, we can change how require looks for a module. The
following explanation is based on the default configuration for
package.loaders.
First require queries package.preload[modname]. If it has a value,
this value (which should be a function) is the loader. Otherwise
require searches for a Lua loader using the path stored in
package.path. If that also fails, it searches for a C loader using the
path stored in package.cpath. If that also fails, it tries an
all-in-one loader (see package.loaders).
Once a loader is found, require calls the loader with a single
argument, modname. If the loader returns any value, require assigns
the returned value to package.loaded[modname]. If the loader returns
no value and has not assigned any value to package.loaded[modname],
then require assigns true to this entry. In any case, require returns
the final value of package.loaded[modname].
If there is any error loading or running the module, or if it cannot
find any loader for the module, then require signals an error.
You will see that it explains, in some detail, what methods require uses to find the code for the given module name. Implicit in that explanation is an indication as to how you can assign arbitrary chunks of loaded (or loadable) code to any given name you would like.
Specifically, if you set a value in package.loaded[modname] that value will be returned immediately. Failing that, package.preload[modname] is used as a loader (which is a function that takes the module name).

Undefined reference to extern int stm32

I'm using Atrollic Studio(problem also exists in Eclipse).
.h file
extern int i2cInitIO(uint channel, uint hz);
extern int i2cIO(uint device, byte *put, uint putlen, byte *get, uint getlen);
.c file
#include "tollosI2C.h"
int i2cGetReg(uint device, byte reg, byte *get) {
// write one byte address then read 1 byte data
return i2cIO(device, &reg, 1, get, 1);
} // i2cGetReg
I have a problem: undefined reference to `i2cIO'.This project is need to be compiled by ARM tool chain.
StM32F103VET6 - high density devices.I'm use ST-Link.
UPD: my .h file - http://pastebin.com/52ftBxR9
and c. file - http://pastebin.com/CcjpVZUP
Compiler invocation command - "gcc" without braces.
Compiler invocation arguments - "-E -P -v -dD ${plugin_state_location}/specs.c" without braces.
OK, your environment is called Atollic (spelling mistake), but from the name of the header file I conclude you are using the Tollos supervisor from Mike Cowlishaw.
Secondly, your compilation options may not be correct, since the -E option for GCC results in only preprocessed output being generated, the error you report is a linker error, however.
Without more information, I would assume you're missing a library containing the i2cIO implementation, probably a missing option for the linker command line.
Since you seem to be using a processor variant not directly supported by Tollos, I suppose you want to port Tollos for your processor. Check your makefile cq. Atollic project setup to include the correct libraries. And if appropriate, replace the -E option with -c.

Environment variabile in Macro path

I need to define some path to files with macros. How can I use the $HOME environment variable?
I can't find it on the GNU manual, and this doesn't work:
#define LOGMMBOXMAN "$HOME/mmbox/LOGmmboxman"
No it shouldn't and you probably don't want constant-defined settings like that in any case. If you did that and it worked as you're intending to use it, your home directory would be built in as whatever $HOME is for whoever's doing the building. The executable then depends on that specific home directory existing. If that's OK, just #define your own home. I suspect it isn't though, so you need to deduce it at runtime.
For run-time deduction what you want is this, such that:
const char* home_dir = getenv("HOME");
If there is no $HOME defined, you get NULL returned so be sure to test for this.
You can then build your string based on that. You'll need #include <stdlib.h>.
Sounds like you are really asking "how can I set some cpp macro from my environment?"
If sothen you should just be able to add it to CPPFLAGS.
export CPPFLAGS="$CPPFLAGS -D LOGMMBOXMAN=$HOME/mmbox/LOGmmboxman"
Then in your code
#ifndef LOGBOXMAN
#error LOGBOXMAN not defined
#endif
Then make sure your source is built using the CPPFLAGS in the command line to gcc:
$ gcc -c file.c $CPPFLAGS
You can't. You need to use your build system to define a macro with the $HOME value (or equivalent on a non-unix system), i.e. something like this:
gcc -DHOME="/home/username" file.c
Or "/Users/username" for Mac OS X, or "C:\Users\username" (or something) for Windows. Basically, GCC provides the -D flag to define a macro on the command line. You can set up a script (or your build system) to take care of this macro definition for you, or perhaps make a system-dependent include file to define the HOME macro properly.
Then, in your C header, you can do:
#define LOGMMBOXMAN HOME "/mmbox/LOGmmboxman"
Note that, in C, consecutive string literals are concatenated. So this macro expands to:
"/home/username" "/mmbox/LOGmmboxman"
Which C interprets as
"/home/username/mmbox/LOGmmboxman"
EDIT: All that thinking, and I didn't think! D'oh!
As others have pointed out, you probably don't want to do this. This will hard-code your program to work for one specific user's home directory. This will likely cause problems if you want each user to use your program, but for each to keep his (or her) own separate files.
Ninefingers' answer is what you're most likely looking for. In the event that you ever find yourself in need of the above technique (i.e. storing application files in a system-specific place) I will leave my answer unchanged, but I expect it won't help you here.

Resources