This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Break-Point Expressions

Hi guys. Its been a while since I've posted, yet I still browse the forums daily.

I'm working on an STM320F103E project which interfaces with an FPGA via memory mapping.

The code is functional, but 'for some reason' the processor is accessing memory at 0x68008000 and at 0x6800A000 as observed in ChipScope within the Xilinx FPGA.

As you know by now, I really hate not knowing everything that my code is doing, so this really upsets me.

Although the interface to the FPGA is in BANK3 at 0x68018000 & 0x68018002, the code is accessing memory that I don't know about or remember yet.

All of this code works. (No problems here)
I just wanted to share the basic access performed:
I don't read/write externally anywhere else (that I know)

typedef volatile unsigned int    vu16;
typedef volatile unsigned long   vu32;
typedef          unsigned long    u32;

#define BANK3_PSRAM             ( (vu32)0x68000000 )          // 0x6800.0000-0x68FF.FFFF
#define FPGA_BASE_ADDRESS       ( BANK3_PSRAM + 0x00000000 )  // FPGA mapped base

#define FPGA_ROTARY_DIRECT_DATA_LSW *( (vu32 *) (u32) ( FPGA_BASE_ADDRESS + 0x00018000 ) )
#define FPGA_ROTARY_DIRECT_DATA_MSW *( (vu32 *) (u32) ( FPGA_BASE_ADDRESS + 0x00018002 ) )

vu32 The_Encoder_Value; // 'global' for testing

void FPGA_Test_RW( void ) // redacted routine for this post
{
    vu16 rotary_encoder_lsw; // 16-bit external access to FPGA (least significant word)
    vu16 rotary_encoder_msw; // 16-bit external access to FPGA (most significant word)

    rotary_encoder_lsw = FPGA_ROTARY_DIRECT_DATA_LSW;
    rotary_encoder_msw = FPGA_ROTARY_DIRECT_DATA_MSW;

    The_Encoder_Value  =  ( ((u32) rotary_encoder_msw)<<16 ) | rotary_encoder_lsw;
}

I'd like to set a break point on writing or reading to/from 0x68008000 & 0x6800A000, but the Expression Help doesn't explain the syntax well enough.

Yes, I did a 'little' research first, but decided to ask the forum how to do this, or better yet, provide a link that explains the Expression syntax better.

--Cpt. Vince Foster
2nd Cannon Place
Fort Marcy Park, VA

Parents Reply Children
  • I prefer to use uint8_t, uint16_t, uint32_t, ... when I need variables of fixed size. If the platform don't have a stdint.h file, then I declare my own "layer 0" data types.

  • Linq,

    Yes. I did.

    Thanks to you, I had to run it down in the libraries. As a result, I found that Keil's "rt_Typedef.h" defines it this way:

    FILE: C:\IDEs\Keil\ARM\RL\RXT\SRC\ARM\rt_Typedef.h
    /* Types */
    typedef char               S8;
    typedef unsigned char      U8;
    typedef short              S16;
    typedef unsigned short     U16;
    typedef int                S32; // defined as 32-bits
    typedef unsigned int       U32; // defined as 32-bits
    typedef long long          S64;
    typedef unsigned long long U64;
    typedef unsigned char      BIT;
    typedef unsigned int       BOOL;
    typedef void               (*FUNCP)(void);
    typedef void               (*FUNCPP)(void *);
    
    


    So, I've been doing it wrong since, well, forever. This is embarrassing. Thanks for ruining my day. I shan't forget this John Linq. You have made my list. ;-)

    In my defense, I never declare an 'int', I declare a s16 or u16 for a 16-bit value. Same goes for the other types such as 'char' and 'long' etc: I work with bit-widths.

    But I can see that this misinterpretation could get me in trouble when interfacing with STM/Keil library routines: a thing I avoid. Thus far, no errors have resulted. I shall be very mindful of this.

    It is not a 'stupid question' at all. I think you meant to say "I've got a question, stupid..."

    Per,
    I prefer to use this form using lower-case letters:

    typedef  unsigned char    u8;
    typedef    signed char    s8;
    typedef   unsigned int   u16;
    typedef     signed int   s16;
    typedef  unsigned long   u32;
    typedef    signed long   s32;
    
    

    But this is kind of besides the OP point.

    How do I set a breakpoint on a memory access to 0x68008000 and 0x6800A0000 ?
    The expression looks like what? http://i.imgur.com/7vd9U.jpg

    (I would also like to see a document that explains the expression parameters better than the Help File on breakpoints)

    Thanks for your help on this.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • This should do the trick - in the debugger command window, enter:

    bs readwrite *((int *) 0x68008000)
    bs readwrite *((int *) 0x6800A000)
    bl   // list the current breakpoints
    

    With the cast around the address constant, the access size is specified
    (4 in this case). You might change this to 'short *' or 'char *' to
    specify the access size to be 2 or 1.
    You might also open the breakpoint dialog and look how the above breakpoints
    are translated and shown - just as a reference...

  • Thanks Gp F !

    It worked.
    You nailed it.

    I had to enter it via command-line, and not the Breakpoints Dialog box. (It shows up in the dialog box after the command-line command is entered).

    Yup, it turns out that some "temporary" diagnostic code was still burried in one of my isr routines when I first started interfacing with the FPGA at 0x68008000 / 0x6800A000.

    Problem solved. Thanks again.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA