hi i created a hardware that calculates the square root of (a^2+b^2 )
i sent the inputs (a and b) with assembly and that was fine however when i tried to send them using c code the hardware take them as inputs calculates a^2 + b^2 but never do the square root
i am really clueless here i couldn't locate the problem
heeeeeeeeeeeeeeelp
So, if I understand correctly :
AGAIN LDR R1, =0x59000000 LDR R0, =0x00000022 STR R0, [R1] LDR R1, =0x59000000 LDR R0, =0x00002200 STR R0, [R1] B AGAIN ENDP
0x59000000 is the address where the input should be sent. I'll call it input_address here.
Then the first input value (a in your algebraic formulae) is retrieved from address 0x22 and stored at input_address.
Same thing for second input value (b), which address seems to be 0x2200.
Then, I guess, once two values provided the hardware do the whole calculation automatically ?
In that case, do this code work in your case :
test.c
int calculate(int a, int b) { volatile int *input_address = (int*)0x59000000; while(1) { *input_address = a; *input_address = b; } }
Compiling it with gcc like this :
armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -shared -o test.o test.c
Generates this machine code :
armv7a-hardfloat-linux-gnueabi-objdump -d test.o
00000218 <calculate>: 218: e3a03459 mov r3, #1493172224 ; 0x59000000 21c: e5830000 str r0, [r3] 220: e5831000 str r1, [r3] 224: eafffffc b 21c <calculate+0x4>
Which is roughly the same.
In any case, in your provided code, did you try this instead :
int main() { the_old_days: xd[0]=0; yd[0]=0; int i; for(i=0;i<9;i++){ /* with i < 10, when i = 9, xd[i+1] will be equal to xd[10] which is out of bounds */ xd[i+1]= xd[i]+1; yd[i+1]= yd[i]+1; regdistance = xd[i]; regdistance = yd[i]; } goto the_old_days; }
as i told M
Peter Harris
I don't why my keil can't allocate a memory address with a pointer however i think that the problem is within the def of the "attribute" which allocate a fixed address that can't be reused by another
i tried to differentiate the output of yd and xd and when i compiled my code i observed that regdistance take only the value of xd so i defined another address memory to put the yd and when i simulate my hardware behavior i found that now it calculates the a^2+b^2 but not the square root
if anyone has a suggestion or any idea how can i resolve this prob please help
Well, can you use objdump -d on the bugged binary file and paste the output here.
I do not think that the variable definition is the problem here. However, one way to be sure is to try defining regdistance within main like this :
volatile int *regdistance = (int*)0x59000000;
And see if it works.
Note that you might want to replace
for (i = 0; i < 10; i++)
by
for (i = 0; i < 9; i++)
else you will write into places you did not define (xd[9+1] is not defined).
However, the "at" behaviour can also be emulated doing something like :
volatile int input_address __attribute__ ((section ("regdistance"))); int calculate(int a, int b) { while(1) { input_address = a; input_address = b; } }
Using a linker script like this :
test.ld
ENTRY(calculate)SECTIONS{ . = 0x10000; .text : { *(.text*) } . = 0x59000000; .regdistance : { *(regdistance*) }}
ENTRY(calculate)
SECTIONS
{
. = 0x10000;
.text : { *(.text*) }
. = 0x59000000;
.regdistance : { *(regdistance*) }
}
And then compile like this :
armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -mthumb -T test.ld -o test test.c
Code produced :
LANG=C armv7a-hardfloat-linux-gnueabi-objdump -d testtest: file format elf32-littlearmDisassembly of section .text:
LANG=C armv7a-hardfloat-linux-gnueabi-objdump -d test
test: file format elf32-littlearm
Disassembly of section .text:
00010000 <calculate>: 10000: f240 0300 movw r3, #0 10004: f6c5 1300 movt r3, #22784 ; 0x5900 10008: 6018 str r0, [r3, #0] 1000a: 6019 str r1, [r3, #0] 1000c: e7fc b.n 10008 <calculate+0x8> 1000e: bf00 nop