EngineerZone
All Places
Processors and DSP
Blackfin Processors
Discussions
Hi,
Could somebody give me some clue about how to resolve this error:
At runtime my program crash on bare metal coreb:
.....
| COREB: test mdct36 | |
| COREB: execption 24 addr 3c0746c | |
| COREB: coreb dump stack | |
| COREB: found fp: ff700c1c | |
| COREB: call frame 0 -12 feb05676 | |
| COREB: call frame 0 -11 00000000 | |
| COREB: call frame 0 -9 00000000 | |
| COREB: call frame 0 -8 ff700bec |
.....
when debugging, this assembler line of code is in cause.
A1 = A0 = 0 || R3 = [P5++] || [I0--] = R1;
is there is something wrong with it?
I attach the whole assembler file, the above code is at line 211
Looks like a misaligned exception. I believe you are calling this from C. Insert a break at the start of this function and look at R0/R1/R2 contents conforming to the calling prototype -
void _mdct12( fract16 *input, fract16 *output, fract16 *twid_coef);
Check values in P5/I0 when you hit exception / just before hitting. If it is alignment problem, it can be fixed by (say 32 bit alignment for example) : char a __attribute__((aligned(4))); in C or .align 4; in ASM. Also be aware of the ABI of GCC when looking at function arguments of extracted assembly library codes (especially if tested with VDSP) .
Blackfin alignment requirements --
Thanks PrasanthR,
here is the debug I've got with gdb:
just before:
| p5 | 0x3c0b792 0x3c0b792 |
| r3 | 0x8006a830 -2147047376 |
| i0 | 0xff700c98 -9433960 |
| r1 | 0xd73f1a2 225702306 |
| sp | 0xff700ca0 0xff700ca0 |
| fp | 0xff700cf4 0xff700cf4 |
| a0x | 0xffffffff -1 |
| a0w | 0xf1a24400 -241024000 |
| a1x | 0x0 0 |
| a1w | 0xd735c00 225664000 |
after exception:
| r0 | *value not available* |
for all registers value
using .align 4 as suggested it crash the same way. the register values are:
before crash:
| p5 | 0x3c0b78e 0x3c0b78e |
| r3 | 0x10b57ee7 280329959 |
| i0 | 0xff700c98 -9433960 |
| sp | 0xff700ca0 0xff700ca0 |
| fp | 0xff700cf4 0xff700cf4 |
| a0x | 0xffffffff -1 |
| a0w | 0xefb55880 -273328000 |
| a1x | 0x0 0 |
| a1w | 0xeed8880 250448000 |
after crash:
same as before:
(gdb) break +1
Breakpoint 3 at 0x3c0722c: file signal_processing/mdct36.asm, line 213.
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0xff600000 in ?? ()
(gdb) bt
#0 0xff600000 in ?? ()
(gdb) info registers
r0 *value not available*
r1 *value not available*
r2 *value not available*
r3 *value not available*
Thanks,
William
As Prasanth indicated, the instruction that you are indicating to throw the exception is doing two 32-bit data moves, one via P5 and another via I0. While I0 looks OK in all of the above, P5 is not 32-bit aligned in any of the dumps you provided. In the assembly code, P5 appears to be loaded from R2, which is the 3rd argument in the call (the coefficient array). If you force the coefficient array to align on a 32-bit boundary, then P5 should not get a 16-bit boundary value.
Hi Thanks for the help,
I'm not really sure how to force R3 to be align on a 32 bit boundary, could you give me an example?
here is what I think in the code can be related:
.section .text
.global __mdct36;
.align 8; (This tell that everything is align 32 bit is that the way to force it? it was .align 4 before. but I still have the same runtime error)
(start of the function)
......
A1 = A0 = 0 || R3 = [P5++] || [I0--] = R1; (line where the error is triggered)
how do I force the R3 coef to align? do I left shift it ( R3 << 16)?
Thanks,
William
This is built into the compiler for you, you do not need to do anything at the assembly level to align anything. These pointers are being passed in R0, R1, and R2 at the point of the function call. The function prototype is:
void _mdct12( fract16 *input, fract16 *output, fract16 *twid_coef);
So, the pointer in R2 at the point of entry for this function is to the twid_coef array, which must be quad-aligned. Wherever you declare this buffer, you need to ensure it is quad-aligned. The "align 4" in assembly is the correct means of forcing quad-alignment if you are doing this in assembly.
Hi thanks,
I've try to change twid_coef from short to int so it has 32 bit words but this jus put the error line 168 of the mdc36.asm file:
R0 = [I0 ++ M0] || I1 -= M1;
how do I quad align in C?
here are the way the function is called:
f1 = _mdct36;
coreb_msg("test mdct36\n");
// Test Case 1 :Input is a DC signal
in_MDCT = get_free_buffer((sm_uint32_t)(36*sizeof(short)));
if(in_MDCT == NULL){
coreb_msg("error in pointer is null\n");
}
out_MDCT = get_free_buffer((sm_uint32_t)(36*sizeof(short)));
if(out_MDCT == NULL){
coreb_msg("error in pointer is null\n");
}
for(i=0;i<36;i++)
in_MDCT[i] = dc_signal1;
cycle_count[0] = Compute_Cycle_Count(in_MDCT, out_MDCT, twid_coef);
the initial code had short for all of it so I kept short. the variables are define as such:
| //segment("mydata1") short twid_coef[162] = { |
short twid_coef[162] = {
0x5A81,
0x0FB7,
......
| //segment("mydata1") short in[36]; | |
| //segment("mydata1") short out[36]; |
int *in_MDCT;
int *out_MDCT;
commented was the VDSP compiler implementation way.
Thanks,
William
I wouldn't convert the data to type int if I were you. According to what you posted previously, the data types expected by the function are type fract16, which wouldn't be correct in memory if declared as type int (32-bit data). The correct means of forcing specific alignment in C source is to use the pragma:
#pragma align 4
fract16 in[NUM_SAM], out[NUM_SAM], twiddle[NUM_SAM];
As for your new error, I cannot comment without more details, but the same concept would apply as in the previous failure. The I0 DAG register location is being accessed as a 32-bit entity in the instruction you provided. If this is pointing to a location that is not quad-aligned, you will generate the same exception.
Looks like it is closed, but just to add:
#pragma align 4 in VDSP
char a __attribute__((aligned(4))); in GCC
These links have comparisons between two cases:
http://docs.blackfin.uclinux.org/doku.php?id=visualdsp:port_assembly_code&s[]=align
http://docs.blackfin.uclinux.org/doku.php?id=visualdsp:port_c_code&s[]=align
Regards
Prasanth