We need to test stack depth at various locations and would like to use a processor expert to do this. I looked in the PEx for kinetis user manual and did not find anything. If not possible to use PE what options do I have?
Hi
Why not write a routine? It only takes two lines:
extern void *fnCheckStackDepth(void)
{
volatile unsigned long dummy; // put a variable on the stack
return (void *)&dummy; // return its address - therefore the (approx.) present SP value
}
Regards
Mark
That will make Lint and other safety standards explode, returning the address of a local variable. :-)
Also shows the fallacy of such standards of not accounting for really wanting to do something like this.
Here is how to read the Stack Pointer, PC etc
in GCC:
static __inline__ void *pc_get(void)
{
void *pc;
__asm__ __volatile__ ("mov %0, pc" : "=r"(pc));
return( pc );
}
static __inline__ void *sp_get(void)
{
void *sp;
__asm__ __volatile__ ("mrs %0, msp" : "=r"(sp));
return( sp );
}
static __inline__ void psp_set( void *setval)
{ __asm__ volatile ("msr psp, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):);
__asm__ volatile ("" ::: "memory");
}
static __inline__ void lr_set(uint32_t setval)
{ __asm__ volatile ("mov lr, %[value]\n\t"::[value]"r"(setval):);
__asm__ volatile ("" ::: "memory");
}
Thanks for your input. I had tried some of the above in KDS 2.0 and had compile issues. After upgrading to 3.0 the above work. I will be doing some wok with monitoring the stack. Does anyone have a good beginning reference for the ARM assembler? I have a background in assembly in some 8bit processors but need to get started in ARM.
Bob
In this case I would disable the lint checking of this single routine because I feel it is generally better practice to use the C-code solution rather than assembler for code bases that are designed to be compiler and processor independent. [For a single specific project that is "known for sure" to be a one-off and needs no future-proofing the assembler is of course possible].
The reason is that I have experienced this:
1. When porting (that is moving a project base to another environment) the assembler failed (not compatible, not valid for the new processor etc.)
2. The engineer involved commented it out so that the project would build and link (eg. by returning a zero) due to the fact that it involved some study of how to do the same thing (which was not his field of expertise as C code would have been) - to be sorted out later when there is time because at the moment pressure was on to get the basic functionality up.
3. This was forgotten and so the checking code was, unknown to the users, not operational - based on the fact that the projet base was simply moved to another environment and so all such features must still be intact.
4. At some point the system failed because the monitoring security features were bypassed so couldn't react - and lint would have been entirely happy with it...
Although not as serious, it does call to mind the $7 Billion software failure in the Arian 5 rocket in 1996 (cause by a single line of code that was assumed to be OK since it was inherited from the previous version) although I understand lint would have detected it, if it weren't in assembler.... Arian 5 explosion: https://www.youtube.com/watch?v=PK_yguLapgA
My preference would be to get the project lead (or any human with real-world common sense) to check that the lint checking deactivation would be a better method to future-proof the code and add his/her decision and permission as a comment in the code. The alternative would be to knowingly open the code base (and possibly the companies future reputation and in the worst case survival) to potential failure in the future in order to keep a single lint check happy.
Regards
Mark
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wcast-qual"
#pragma GCC diagnostic error "-Wdiscarded-qualifiers"
#pragma GCC diagnostic error "-Wreturn-local-addr"
void *stack_depth_check( void )
{
volatile uint32_t dummy; // Put a variable on the stack
return( (void *) &dummy ); // Return its address - therefore the (approx.) present SP value
}
#pragma GCC diagnostic pop
In the project I'm currently working on this is what my GCC setup, with all warnings and all diagnostics on as they always shall be for any project, produces:
WatchDog/stackchk.c: In function 'stack_depth_check':
WatchDog/stackchk.c:19:11: error: cast discards 'volatile' qualifier from pointer target type [-Werror=cast-qual]
return( (void *) &dummy ); // Return its address - therefore the (approx.) present SP value
^
WatchDog/stackchk.c:19:9: error: function returns address of local variable [-Werror=return-local-addr]
return( (void *) &dummy ); // Return its address - therefore the (approx.) present SP value
As these are actual errors and not diagnostic messages not even GCC's
mechanism will let this code compile.
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
It could still be done by selectively compiling with its own error options in the Make build system. However if someone is working on (safety related?) code doesn't understand C there is even less of a chance an error in the build system is going to be uncovered. Such exceptions are always best to avoid.
Software Safety: Do you just ignore Compiler Warnings?
I agree code reuse can be a problem. There we can get into obscure things like pointers being different sizes than integers or one I struggle with using tables of function pointers, where sizes have changed from when the code was first created.
/*
* You may not even convert a void * to a function
* pointer by explicit casting (6.3.2.3|1).
*
* C's abstract machine does not assume that code and
* data are addressed the same way, so as far as C is
* concerned function pointers and data pointers have
* nothing to do with each other (they could have
* different widths).
*/
"2. The engineer involved commented it out so that the project would build and link (eg. by returning a zero) due to the fact that it involved some study of how to do the same thing (which was not his field of expertise as C code would have been) - to be sorted out later when there is time because at the moment pressure was on to get the basic functionality up".
Which is a Management problem.
Firmware Inspections should have found the code problem.
The Ariane 5 code was in ADA and the *process* failure was the reused code problem not being caught in Validation.
http://iansommerville.com/software-engineering-book/case-studies/ariane5/
Bob
It goes to show that there is more involved in reliable software than just lint-type code checking - validation and management being just two of probably a whole string of risks (I wonder whether relying on PE to generate your code for you falls in to this class or not??? ;-)
Regards
Mark
PE generated code is impossible to do a Code Inspection on due to the abstractions of abstractions of abstractions in headers. In KDS 3.2 and KSDK 2.0 the generated code has become a lot less obtuse to follow. Still I'm not going to use it in a safety related project.
Only thing I use such tools for is to see the initialization code they create then write my own based on it and the data sheet, when working on safety related stuff.
I have no problem with such tools for non-safety, non-financial impact (if the generated code causes problems someday in the field will lawyers show up?) projects.