----- Ursprüngliche Nachricht ----- Von: Matthias Ringwald Gesendet am: 17 Apr 2011 20:41:50
> sorry for highjacking this thread, but I'm also struggling to access data put > into the fartext segment. No hijack. (almost) Same topic, same thread :) >> static inline unsigned char FlashReadByte (unsigned long address){ >> unsigned char result; >> unsigned int sr, flash; >> __asm__ __volatile__ ("mov r2,%0":"=r"(sr):); >> // save SR before disabling IRQ >> _DINT(); >> __asm__ __volatile__ ("movx.a %1,%0":"=r"(flash):"m"(address)); >> __asm__ __volatile__ ("movx.b @%1, %0":"=r"(result):"r"(flash)); >> __asm__ __volatile__ ("mov %0,r2"::"r"(sr)); >> // restore previous SR and IRQ state >> return result; >> // aligned address -> low-byte contains result >> } > I'm using the mspgcc4-20110312 release (on mac ox), and the code above > doesn't work for me (yet). I use it with mspgcc 3.2.3 and it produces the following: 1713 000c 814F 0000 mov r15, @r1 //r15 contains a 16 bit result from a previous call to malloc, else the next would write R14 to 2(r1) or something similar 1714 0010 8143 0200 clr 2(r1) 1719 0014 0E42 mov r2,r14 // save status register (inlclufing GIE) to R14 1722 0016 32C2 dint 1728 0018 0018 6F41 movx.a @r1,r15 1731 001c 4018 6F4F movx.b @r15, r15 1734 0020 024E mov r14,r2 // restore status > Are there some extra compiler flags aside from the e.g. -mmcu=msp430x5438 > switch? CPFLAGS = -std=gnu99 -g -Os -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Winline -Wpointer-arith -Wredundant-decls -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch -Wunused - Wundef -Wunreachable-code -mmcu=$(MCU) -ffunction-sections LDFLAGS = -mmcu=$(MCU) -Wl,--gc-sections So there's nothing unusual. > I was trying to read data at 0x10000, but the function a) wasn't inlined, with optimization off (-o0), I get the same non-working code. And no inlining. > and b) did return the data from 0x00000. > I've single stepped this function and got irritated by generated assembly > code, which is much longer than the inline asm above. > I'm getting this: FlashReadByte: push r4 add #llo(-10), r1 // 10 bytes frame size? For what? R12..R15 and 4 bytes on stack should be enough mov r1, r4 // superfluous, maybe optimized away with optimization on. /* prologue ends here (frame size = 10) */ .L__FrameSize_FlashReadByte=0xa .L__FrameOffset_FlashReadByte=0xc mov r14, 6(r4) // store the address to memory That's okay. mov r15, 6+2(r4) /* #APP */ ; 147 "main.c" 1 mov r2,r15 // backup the status register. ; 0 "" 2 /* #NOAPP */ mov r15, 2(r4) // Using R12/R13 instead of R15 will make this superfluous. And where's the DINT? /* #APP */ ; 149 "main.c" 1 movx.a 6(r4),r15 // that's reading the address to R15. GIE must be OFF at this point (any ISR call will clear the upper 4 bit!) ; 0 "" 2 /* #NOAPP */ mov r15, @r4 // What an unnecessary nonsense! And you're right, here the upper 4 bits are chopped. mov @r4, r15 /* #APP */ ; 150 "main.c" 1 movx.b @r15, r15 // this is the actual read ; 0 "" 2 /* #NOAPP */ mov.b r15, 4(r4) // another unnecessary store - could be kept in R15 mov 2(r4), r15 // why reading to R15 and then moving to R2? A direct read to R2 will not clobber R15, so no need to clobber R15 here /* #APP */ ; 151 "main.c" 1 mov r15,r2 ; 0 "" 2 /* #NOAPP */ mov.b 4(r4), r15 // that's the restore from the unnecessary store two instructions earlier. /* epilogue: frame size = 10 */ add #10, r1 pop r4 ret > In the "movx.a 6(r4),r15", 0x10000 was stored in r15, but in the following > two lines (mov r15, @r4 , mov @r4, r15), > the upper bits get lost. I assume, if there wouldn't be that #NOAPP stuff, it > would be fine. What error do I make? None. Or rather I did something wrong - I put the instructions into separate ASM lines. The compiler is doing a lot of stupid stuff here. Which I allowed by using separate instructions. It looks like the compiler hesitates to use the already clobbered registers R12..R15 and tries to get away with only R15 used and much unnecessary stack saving. Try the following version instead: extern inline __attribute__((always_inline)) unsigned char FlashReadByte (unsigned long addr){ unsigned char result; unsigned int register sr, flash; __asm__ __volatile__ ("mov r2 , %1 \n" "bic %3 , r2 \n" "movx.a %4 , %2 \n" "movx.b @%2, %0 \n" "mov %1 , r2 \n" :"=X"(result),"=r"(sr),"=r"(flash) :"i"(GIE),"m"(addr)); return result; } It compiles well with or without optimization and is always inlined. It still lets the compiler decide where to put the result (memory, register, whatever) and without optimization generates still some unnecessary stuff, but less that the original version. And it works. With optimization, the result is identical to the original. > p.s. just starting with this toolchain and MSP430 in general. We all did once :) ------------------------------------------------------------------------------ Benefiting from Server Virtualization: Beyond Initial Workload Consolidation -- Increasing the use of server virtualization is a top priority.Virtualization can reduce costs, simplify management, and improve application availability and disaster protection. Learn more about boosting the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev _______________________________________________ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users