Is it possible to print a variable's address in Specman e, as it can be done in c:
printf(" variable address = %d \n", &some_variable);
Thank you for your help
There is no way to do this.
In e, there is no concept of pointers and addresses.
Also, if this is a variable that persists across a garbage collection (for example, if it is a field or a TCM local variable), its physical address in memory can change, so in fact it is meaningless.
You can use this:
int a = 10;
printf("%p\n", (void *) &a);
Related
I'm trying to program FLASH using HAL_FLASH_Program() function. Precisely speaking, I've written a function which is expected to write two measurements
to flash at a set time interval (e.g. 3 seconds). However, when called, the function manages to write only the first one while ignoring the second one. Can't HAL_FLASH_Program be used twice? What am I doing wrong? I just want to mention that I'm utterly new to STM32 programming, so any helpful suggestions would be much appreciated. Here is the code:
void writeFlash(void){
mem = returnPointerToFirstEmptyAddressInSector();
Address = (uint32_t)mem;
var1.f = Temperature;
var2.f = SD;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGPERR);
HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, var1.i );
Address++;
HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, var2.i);
HAL_FLASH_Lock();
}
The address is not properly aligned
The declaration of Address is not shown, but from the line
Address = (uint32_t)mem;
I'd guess it's an unsigned long. Later, you are incrementing Address after the first write with
Address++;
and use this value to program the second value. But since Address is presumably an integer, not a pointer type, it would be incremented by one instead of the word size (4), and pointing to an address that is partially overlapping the previously written value, and not aligned for word-sized writes. The second write operation would inevitably fail. As #JMA suggests in the comments, check the return value of HAL_FLASH_Program(), and the error code
uint32_t ret = HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, var2.i);
switch(ret) {
case HAL_OK:
break;
case HAL_TIMEOUT:
printf("HAL_FLASH_Program() timeout!\n");
break;
case HAL_ERROR:
printf("HAL_FLASH_Program() error 0x%08x, see *hal_flash.h for bit definitions\n", HAL_FLASH_GetError());
break;
default:
printf("HAL_FLASH_Program() returned unknown status %lu\n", ret);
}
Write a double word at once
The HAL library supports writing 64 bit values at once, so you can write two 32 bit integers in one operation.
HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, Address, ((uint64_t)var2.i << 32) | var1.i);
Just ensure that Address is aligned to a doubleword boundary, i.e. divisible by 8.
I have trouble understanding what happens when calling &*pointer
int j=8;
int* p = &j;
When I print in my compiler I get the following
j = 8 , &j = 00EBFEAC p = 00EBFEAC , *p = 8 , &p = 00EBFEA0
&*p= 00EBFEAC
cout << &*p gives &*p = 00EBFEAC which is p itself
& and * have same operator precedence.I thought &*p would translate to &(*p)--> &(8) and expected compiler error.
How does compiler deduce this result?
You are stumbling over something interesting: Variables, strictly spoken, are not values, but refer to values. 8 is an integer value. After int i=8, i refers to an integer value. The difference is that it could refer to a different value.
In order to obtain the value, i must be dereferenced, i.e. the value stored in the memory location which i stands for must be obtained. This dereferencing is performed implicitly in C whenever a value of the type which the variable references is requested: i=8; printf("%d", i) results in the same output as printf("%d", 8). That is funny because variables are essentially aliases for addresses, while numeric literals are aliases for immediate values. In C these very different things are syntactically treated identically. A variable can stand in for a literal in an expression and will be automatically dereferenced. The resulting machine code makes that very clear. Consider the two functions below. Both have the same return type, int. But f has a variable in the return statement which must be dereferenced so that its value can be returned (in this case, it is returned in a register):
int i = 1;
int g(){ return 1; } // literal
int f(){ return i; } // variable
If we ignore the housekeeping code, the functions each translate into a sigle machine instruction. The corresponding assembler (from icc) is for g:
movl $1, %eax #5.17
That's pretty starightforward: Put 1 in the register eax.
By contrast, f translates to
movl i(%rip), %eax #4.17
This puts the value at the address in register rip plus offset i in the register eax. It's refreshing to see how a variable name is just an address (offset) alias to the compiler.
The necessary dereferencing should now be obvious. It would be more logical to write return *i in order to return 1, and write return i only for functions which return references — or pointers.
In your example it is indeed illogical to a degree that
int j=8;
int* p = &j;
printf("%d\n", *p);
prints 8 (i.e, p is actually dereferenced twice); but that &(*p) yields the address of the object pointed to by p (which is the address value stored in p), and is not interpreted as &(8). The reason is that in the context of the address operator a variable (or, in this case, the L-value obtained by dereferencing p) is not implicitly dereferenced the way it is in other contexts.
When the attempt was made to create a logical, orthogonal language — Algol68 —, int i=8 indeed declared an alias for 8. In order to declare a variable the long form would have been refint m = loc int := 3. Consequently what we call a pointer or reference would have had the type ref ref int because actually two dereferences are needed to obtain an integer value.
j is an int with value 8 and is stored in memory at address 00EBFEAC.
&j gives the memory address of variable j (00EBFEAC).
int* p = &j Here you define a variable p which you define being of type int *, namely a value of an address in memory where it can find an int. You assign it &j, namely an address of an int -> which makes sense.
*p gives you the value associated with the address stored in p.
The address stored in p points to an int, so *p gives you the value of that int, namely 8.
& p is the address of where the variable p itself is stored
&*p gives you the address of the value the memory address stored in p points to, which is indeed p again. &(*p) -> &(j) -> 00EBFEAC
Think about &j itself (or even &(j)). According to your logic, shouldn't j evaluate to 8 and result in &8, as well? Dereferencing a pointer or evaluating a variable results in an lvalue, which is a value that you can assign to or take the address of.
The L in "lvalue" refers to the left in "left hand side of the assignment", such as j = 10 or *p = 12. There are also rvalues, such as j + 10, or 8, which obviously cannot be assigned to.
That's just a basic explanation. In C++ there's a lot more to it, with various classes of values (but that thread might be too advanced for your current needs).
I make a stack trace at some point in my program. Once with libc's backtrace_symbols() function and once with unw_get_proc_name() from libunwind.
backtrace_symbols() output:
/home/jj/test/mylib.so(+0x97004)[0x7f6b47ce9004]
unw_get_proc_name() output:
ip: 0x7f6b47ce9004, offset: 0x458e4
Here you see that the instruction pointer address (0x7f6b47ce9004) is the same and correct. The function offset 0x97004 from backtrace_symbols() is also correct but not the one I get from unw_get_proc_name() (0x458e4).
Does somebody have a clue what's going on here and what might cause this difference in offsets?
Both methods use a similar code like the following examples:
backtrace():
void *array[10];
size_t size;
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);
libunwind:
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
char fname[64];
unw_get_reg(&cursor, UNW_REG_IP, &pc);
fname[0] = '\0';
(void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
printf ("%p : (%s+0x%x) [%p]\n", pc, fname, offset, pc);
}
I think unw_get_proc_name compute offset from an unnamed internal frame.
For example:
void f() {
int i;
while (...) {
int j;
}
}
Notice there is a variable declaration inside loop block. In this case (and depending of level of optimization), compiler may create a frame (and related unwind information) for the loop. Consequently, unw_get_proc_name compute offset from this loop instead of begin of function.
This is explained in unw_get_proc_name man page:
Note that on some platforms there is no reliable way to distinguish
between procedure names and ordinary labels. Furthermore, if symbol
information has been stripped from a program, procedure names may be
completely unavailable or may be limited to those exported via a
dynamic symbol table. In such cases, unw_get_proc_name() may return
the name of a label or a preceeding (nearby) procedure.
You may try to test again but without stripping your binary (Since unw_get_proc_name is not able to find name of function, I think your binary is stripped).
How do I detect whether a variable is float, double, int, etc.?
Thanks.
Objective-C is not like PHP or other interpreted languages where the 'type' of a variable can change according to how you use it. All variables are set to a fixed type when they are declared and this cannot be changed. Since the type is defined at compile time, there is no need to query the type of a variable at run-time.
For example:
float var1; // var1 is a float and can't be any other type
int var2; // var2 is an int and can't be any other type
NSString* var3; // var3 is a pointer to a NSString object and can't be any other type
The type is specified before the variable name, also in functions:
- (void)initWithValue:(float)param1 andName:(NSString*)param2
{
// param1 is a float
// param2 is a pointer to a NSString object
}
So as you can see, the type is fixed when the variable is declared (also you will notice that all variables must be declared, i.e. you cannot just suddenly start using a new variable name unless you've declared it first).
In a compiled C based language (outside of debug mode with symbols), you can't actually "detect" any variable unless you know the type, or maybe guess a type and get lucky.
So normally, you know and declare the type before any variable reference.
Without type information, the best you can do might be to dereference a pointer to random unknown bits/bytes in memory, and hopefully not crash on an illegal memory reference.
Added comment:
If you know the type is a legal Objective C object, then you might be able to query the runtime for additional information about the class, etc. But not for ints, doubles, etc.
Use sizeof. For double it will be 8. It is 4 for float.
double x = 3.1415;
float y = 3.1415f;
printf("size of x is %d\n", sizeof(x));
printf("size of y is %d\n", sizeof(y));
What does the & symbol mean in Objective-C? I am currently looking at data constucts and am getting really confused by it.
I have looked around the web for it but have not found an answer at all. I know this is possibly a basic Objective-C concept, but I just can't get my head around it.
For example:
int *pIntData = (int *)&incomingPacket[0];
What is the code doing with incoming packet here?
& is the C address-of unary operator. It returns the memory address of its operand.
In your example, it will return the address of the first element of the incomingPacket array, which is then cast to an int* (pointer to int)
Same thing it means in C.
int *pIntData = (int *)&incomingPacket[0];
Basically this says that the address of the beginning of incomingPacket (&incomingPacket[0]) is a pointer to an int (int *). The local variable pIntData is defined as a pointer to an int, and is set to that value.
Thus:
*pIntData will equal to the first int at the beginning of incomingPacket.
pIntData[0] is the same thing.
pIntData[5] will be the 6th int into the incomingPacket.
Why do this? If you know the data you are being streamed is an array of ints, then this makes it easier to iterate through the ints.
This statement, If I am not mistaken, could also have been written as:
int *pIntData = (int *) incomingPacket;