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

External RAM memory tester program

Hello,
I am trying to check if addresses bus and data bus are well configured in my external RAM memory.
I have done this algorithm

#include <XC164.h>

#define         low_adress   0x400000;
#define         high_adress   0x410000;
#define         high_data   0xFF;
#define         low_data   0x00;

void    main    (void)
{
        static double    idata  j,i,k;
        int xhuge       *DIR;

        DIR  = 0x400000;

        /*      DATA BUS TEST   */

        for (j = low_adress; j <= high_adress; j++)
        {
                *DIR = 0x55;                                    // I write 0101 0101
                if (*DIR != 0x55)       P3^3 = 1;       // If what I have read is diferent to what I have written, I switch on an alarm
                *DIR = 0xAA;                                    // I write 1010 1010
                if (*DIR != 0xAA)       P3^3 = 1;       // If what I have read is diferent to what I have written, I switch on an alarm
                DIR++;
        }

        /*      ADRESSES BUS TEST       */

        DIR  = 0x400000;
        for (i = low_adress; i < high_adress; i = i + 0xFF;)
        {
                for     (k = low_data; k < high_data ; k++)
                {
                        *DIR = k;
                        DIR++;
                }
        }


but the compiler throws errors. My RAM memory is mapped from 0x400000 to 0x410000 (64kB).
Why does the compiler throw this errors?

Build target 'Target 1'
assembling START_V2.A66...
compiling PruebaRA.c...
PRUEBARA.C(17): error C25: syntax error near '='
PRUEBARA.C(17): error C25: syntax error near ';'
PRUEBARA.C(17): error C25: syntax error near ')'
PRUEBARA.C(20): error C25: syntax error near 'if'
PRUEBARA.C(20): error C25: syntax error near 'P3'
PRUEBARA.C(20): error C25: syntax error near '='
PRUEBARA.C(22): error C25: syntax error near 'if'
PRUEBARA.C(22): error C25: syntax error near 'P3'
PRUEBARA.C(22): error C25: syntax error near '='
PRUEBARA.C(24): error C25: syntax error near '}'
PRUEBARA.C(29): error C25: syntax error near 'for'
PRUEBARA.C(29): error C7: compilation aborted
Target not created

Parents
  • The memtest function expects to receive an address. Not as an integer, but as a pointer to a memory cell.

    You don't send a pointer, since you use the * to pass the value the pointer points at. That will not get your memtest function to do what you think it does, or more specifically it won't test the memory cell you think it does.

    Another thing:

    volatile xhuge *pointer;
    

    You don't specify a type for the data the pointer should point at. The compiler will default it to be a pointer to int. Was that what you intended?

    Finally: You never assign your variable "pointer" a value, so it will be zero-initialized when the program starts. Whas that what you intended?

    I recommend that you get a good book on the C language, and take a closer look at pointers and pointer indirection. And until you are very comfortable with pointers - and everything else about the C language - you should consider all warnings as if they where errors. The probability will be very high that the compiler is correct, and that it has caught a real problem.

Reply
  • The memtest function expects to receive an address. Not as an integer, but as a pointer to a memory cell.

    You don't send a pointer, since you use the * to pass the value the pointer points at. That will not get your memtest function to do what you think it does, or more specifically it won't test the memory cell you think it does.

    Another thing:

    volatile xhuge *pointer;
    

    You don't specify a type for the data the pointer should point at. The compiler will default it to be a pointer to int. Was that what you intended?

    Finally: You never assign your variable "pointer" a value, so it will be zero-initialized when the program starts. Whas that what you intended?

    I recommend that you get a good book on the C language, and take a closer look at pointers and pointer indirection. And until you are very comfortable with pointers - and everything else about the C language - you should consider all warnings as if they where errors. The probability will be very high that the compiler is correct, and that it has caught a real problem.

Children
  • Thank you very much Per for your reply :)
    The truth is that it was a lapse of concentration. Those errors were my mistakes. I have fixed the code in this way.

    #include <XC164.h>
    
    typedef unsigned char U8;                       /* Set the data bus width to 8 bits. */
    U8      memTestDataBus(volatile U8 * address);
    
    U8 idata        j;
    volatile U8 xhuge  *pointer;
    
    void    main    (void)
    {
            pointer = 0;
            ASC0_CON       =  0x0011;      // load ASC0 control register
            ASC0_BG        =  0x0011;      // load ASC0 baud rate time reload register
            ALTSEL0P3 |= 0x0400;
            P3 |= 0x0400;
            DP3  |= 0x0400;    //set direction register
            ASC0_TXFCON = 0x0100;  /* transmit FIFO is disabled  */  ///
            ASC0_CON      |=  0x8000;      // enable baud rate generator
    
            j = memTestDataBus(pointer);
    
            ASC0_TBUF = j;          //Send me a  memTestDataBus function result through ASC0
    
            while (1);
    }
    
    

    It's now ok?

    Anyway the problem is still the same.

  • Are you sure you want to pass a null pointer to 'memTestDataBus'? Besides, what do you need the variable 'j' for?

  • How do you know that the pointer is null? The pointer points at 0x00000 adress. How to check it?

    What I want to do is to point, for example, at first adress of my external RAM, but I don't know how to do it.

    I simply use the variable "j"to store the value that 'memTestDataBus' function returns and afterwards to send it through ASC0.

  • ASC0_TBUF = memTestDataBus(pointer);
    


    Will send the result without the use of a variable.

    The datasheet (and possibly your external connections) should tell you where the memory is and how large it is - if your project doesn't know where the memory is, the compiler + linker will not be able to produce a project that makes use of the memory as expected.

    But I want you to once more think about one important issue: If you let the memtest function test a memory cell that is used for stack or for storing any of your variables, you will not get the expected result. The function call may not even return.

  • John,

    Don't try this stuff at home, or in your product! :-)

    ASC0_TBUF = memTestDataBus(&memTestDataBus);
    

  • Here is my Memory mapping:
    img160.imagevenue.com/img.php

    And here the indicated adresses y my project
    img133.imagevenue.com/img.php

  • John,

    How do you know that the pointer is null? The pointer points at 0x00000 adress. How to check it?

    In order to verify that a pointer does not point at a null address, such a test can be used:

    if (pointer)
    {
       // this code is executed if pointer is not null
    }
    else
    {
       // this code is executed if pointer is null
    }
    

    Note however that Per comments are very much in place: even if a pointer is not null, is does not mean that it points to an address on which you can run your test. running the test might destroy data/code, just like demonstrated in my previous post.

  • #include <XC164.h>
    #include <intrins.h>
    #define ASC0_TINT    0x2A
    
    typedef unsigned char U8;                       /* Set the data bus width to 8 bits. */
    U8      memTestDataBus(volatile U8 * address);
    
    
    volatile U8   *pointer;
    sbit    MY_OUT = P1L^0;
    
    void    main    (void)
    {
            DP1L           =  0x0001;      // load direction register
            pointer = 0x400000;                        // the pointer points at 0x400000 adress
    
            if (pointer)
            {
                    MY_OUT = 1;              // this code is executed if pointer is not null
            }
            while (1)
            {
                     ;
            }
    }
    

    Tamir, with this code, MY_OUT is to 5V, therefore,as you can see, the pointer isn't null

    What else can I do?
    Thanks ;-)

  • pointer = 0x400000;
    

    indeed points 'pointer' to a non-null address.

  • 
    pointer = 0x400000;   // the pointer points at 0x400000 adress
    
    if (memTestDataBus(pointer) == 0)       MY_OUT = 1; // if the result of the test is ok toggle MY_OUT to 5V
    
    

    Is it well done the instruction to check the databus test?

  • looks ok as long as no component of your program is mapped to 0x400000.

  • Tamir, "MY_OUT" has been set. => The data test its ok! :-D
    Now, I am going to do the adresses test.
    Thanks for your help.
    I write here the used program if someone need it:

    
    #include <XC164.h>
    #include <intrins.h>
    
    typedef unsigned char U8;               // Set the data bus width to 8 bits.
    U8      memTestDataBus(volatile U8 * address);
    
    volatile U8   *pointer;
    sbit    MY_OUT = P1L^0;
    
    void    main    (void)
    {
            DP1L           =  0x0001;  // load direction register
            pointer = 0x400000;                // the pointer points at 0x400000 adress
    
            if (memTestDataBus(pointer) == 0)       MY_OUT = 1; // if the result of the test is ok toggle MY_OUT to 5V
    
            while (1)
            {
                     ;
            }
    }
    ///////////////////////////////////////////////////////////////////////
    U8      memTestDataBus(volatile U8 * address)
    {
            U8 pattern;
    
            for (pattern = 1; pattern != 0; pattern <<= 1)
            {
                    //Write the test pattern.
                    *address = pattern;
    
                    //Read it back (immediately is okay for this test).
                    if (*address != pattern)
                    {
                            return (pattern);
                    }
            }
                    return (0);
    } /* memTestDataBus() */
    /////////////////////////////////////////////////////////////////////////
    
    

  • But are you aware that the memTestDataBus() only tests if there exists working memory at one specific little byte. It does not test all cells of the memory. An external loop is needed to step "pointer" to all RAM addresses and test them one-by-one. But once more: the test is destructive, so if it tests a RAM cell that contains critical data, your program will crash.

    Another interesting thing is that memory constructs that doesn't multiplex address and data can pass such a memory test since a write followed by a read may pick up the old signal states. Capacitances on the signals will make it possible to write out in the air, and then read back the same value. In such cases, it is good to write a test pattern to one address, and a dummy pattern to another address and then read back the test pattern from the original address. If reading air, you will get the dummy pattern instead of the test pattern.