summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaniel <danieruru@gmail.com>2013-04-24 17:17:29 +0900
committerdaniel <danieruru@gmail.com>2013-04-24 17:17:29 +0900
commit888a4d89fcfa32f371ad07d89a2980eb94b4d335 (patch)
treec978bc33fda946224f67df868d688d1453cf7c3f
parent5aa4d0580cbee44c83dac541509692121b7c19e1 (diff)
Add a work around for the unaligned access and add some notes on what was happening
-rw-r--r--parser.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/parser.c b/parser.c
index 6d3ae2e..5b4779a 100644
--- a/parser.c
+++ b/parser.c
@@ -1274,8 +1274,25 @@ static int Go_Float_eprom51(gchar** response, int channel, char *loc_string,char
return OK;
break;
- case query_param:
- return query_float(response, *(float *)(&globals.Flash.flash_start + eprom_loc));
+ case query_param:{
+ // The basic issue here is that this pointer isn't aligned. Which
+ // should actually be a problem as ARMv7 has unaligned access support
+ // and it's hardcoded to be on.. the issue is that not all instructions
+ // can do unaliged accesses and the previous code generated one of those
+ // instructions. The kernel traps the access and kills the process.
+ // You should see something like this in dmesg:
+ // [494223.471575] Alignment trap: not handling instruction edd37a00 at [<00011d12>]
+ // [494223.479380] Unhandled fault: alignment exception (0x001) at 0x00050d66
+ //
+ // I use memcpy here to copy the variable out into a temp
+ // variable on the stack which is aligned.
+ // There are probably other bits of code that will trigger this because of
+ // the use of offsets into the struct.. It might be an idea to write some macros
+ // for pushing and pulling bits from the struct.
+ float temp;
+ memcpy(&temp, (float *)(&globals.Flash.flash_start + eprom_loc),sizeof(float));
+ return query_float(response, temp);
+ }
break;
default: