How to boot OBDS via USB

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to boot OBDS via USB

4,831 Views
lategoodbye
Senior Contributor I

Hi,

i've modified i.MX28 On-Board Diagnostics Suite (OBDS) 1.0 to run on a custom hardware (still i.MX28 + USB but without SD card slot).

After that i generated the mx28-obds.sb file with tools/linux/build_mx28.sh and modified the XML of the Mfgtool:

<UCL>

  <CFG>

    <STATE name="Recovery" dev="IMX28"/>

    <STATE name="Updater" dev="Updater" />

    <DEV name="IMX28" vid="15A2" pid="004F"/>

    <DEV name="Updater" vid="066F" pid="37FF" />

  </CFG>

  <LIST name="Custom img" desc="Start OBDS">

    <CMD type="boot" body="Recovery" file="mx28-obds.sb" >Start OBDS</CMD>

  </LIST>

</UCL>

If i run the MfgTool, the custom hardware only prints

HTLLCL


But if i try the original updater_ivt.sb with MfgTool, everything is fine. So i think the mx28-obds.sb has the wrong format.

Here is the content of the bd file:

options {

        driveTag = 0x00;

        flags = 0x01;

}

constants {

        IVT_ADDR = 0x70;

        LOAD_ADDR  = 0x100;

        ENTRY_ADDR = 0x40800000;

}

sources {

        ipl = "../../output/mx28/bin/ipl";

        obds = "../../output/mx28/bin/diag-obds-mx28evk.bin";

}

section (0) {

    load ipl > LOAD_ADDR;

    load ivt (entry=LOAD_ADDR) > IVT_ADDR;

    hab call IVT_ADDR;

    load obds > ENTRY_ADDR;

    load ivt (entry=ENTRY_ADDR) > IVT_ADDR;

    hab jump IVT_ADDR;

}

How can i generate a sb file which works like a bare metal application in internal i.MX28 RAM?

Do i need to change the bd file?

Labels (1)
Tags (3)
17 Replies

2,561 Views
fernandolopes
Contributor III

Stefan,

since you want to make a memory test, take a look on the mem_test that Yuri posted on my thread i.MX28 DDR stress test.

The .sb file on the mem_test loaded on my board, but the processor freezes after power initialization.

I changed the power initialization code to (kind of) match the power_prep bootlet with NO_DCDC_BATT_SOURCE defined (my board is running from an external power supply with no battery). Now the code runs on my board and catches some errors if I increase the EMI frequency.

You can apply the patch attached to the mem_test code that Yuri posted and try it if you want.

You will need windows with the arm-none-eabi-gcc from CodeSourcery (Mentor) and make to compile the code. I use Windows XP 32 bits on VirtualBox to do it.

It should be as simple as that:

>make

>usb_load.bat

You may change the DDR2 memory parameters on the main file to match the PN you're using.

0 Kudos

2,561 Views
fear_nada
Contributor II

Hello Fernando!

Please, can you give DDR memory test, with modification (mem_test+power_init.patch) like .sb file? I do not have a compiler to build .sb file.

Thank you!

0 Kudos

2,561 Views
lategoodbye
Senior Contributor I

Hello Fernando,

thank you very much. I'll try it, if i've got more time.

BR Stefan

0 Kudos

2,561 Views
igorpadykov
NXP Employee
NXP Employee

Please look at attached example, hope this helps.

0 Kudos

2,561 Views
GraceH
Senior Contributor II

Hi Stefan,

Both the link file mx28.ld and bd file show the diag-obds-mx28evk.bin is loaded to address 0x40800000 which is SDRAM.

If you want to load to IRAM, you need modify mx28.ld and bd.


Grace

2,561 Views
lategoodbye
Senior Contributor I

Hi Grace,

you are right. I thought the obds runs completly in OCRAM, but that's impossible because the binary is too big.

First i reduced the size of the binary to 67 kb by removing all unnecessary drivers. After that i tried many settings ( ENTRY_ADDR = 0, 0x200, 0x4000 or 0x8000) but the results are worse. I got the message "Pref" or "Undefined Ins" without any errorcode.

0 Kudos

2,561 Views
Yuri
NXP Employee
NXP Employee

You may look at very simple enclosed (led) example.
sb-loader is used to load and run the led example via i.MX28 USB in recovery mode.

The MFG uses the same approach.

2,561 Views
Ramtry
Contributor III

Hi Yuri,

I tried your standalone LED program to test the board is working or not using internal SRAM. When using the sb_loader to send the test.sb file to board there is error during download but in board, i can see the blinking of LED and print message in Hyperterminal. The log information for your reference.

D:\sharelinux\LED>sb_loader.exe -f test.sb

Downloading test.sb to device.

  .. CStHidDevice::Download()  Error(258) during read.

Quitting.

  Error(258) during download.

Quitting.

Can you give me an idea to test the SDRAM. I modified your code and cross compiled to test the SDRAM but it ends with error as follows

pause

DDR2 Test Starting

Writing

Bank Selection done

Writing 0

0x8020a014

Test program to test DDR

!

#include "stdio.h"

#include "hardware.h"           /* note, this is where the SoC specific header file is included */

#define TXFE 0x0080

#define R32   volatile unsigned long *

#define R16   volatile unsigned short *

#define R8     volatile unsigned char *

#define PARAM_DDR_TEST_DENSITY      (128 * 1024 * 1024)

#define PARAM_DDR_TEST_CS_NR        1

#define HW_UARTDBG_FR     (*(R32)(0x80074018))  // UART Flag Register    

#define HW_UARTDBG_DR     (*(R32)(0x80074000)) // UART Data Register

#define HW_PWM_CTRL        (*(R32)(0x80064000))

#define HW_PWM_ACTIVE0   (*(R32)(HW_PWM_CTRL + 0x10))

#define HW_PWM_PERIOD0   (*(R32)(HW_PWM_CTRL + 0x20))

#define HW_PWM_ACTIVE1   (*(R32)(HW_PWM_CTRL + 0x30))

#define HW_PWM_PERIOD1   (*(R32)(HW_PWM_CTRL + 0x40))

#define PINCTRL_MUXSEL6   (*(R32)(0x80018160))

#define PINCTRL_MUXSEL7   (*(R32)(0x80018170))

#define PINCTRL_MUXSEL7_SET   (*(R32)(0x80018174))

#define PINCTRL_DOE3   (*(R32)(0x80018B30))

#define PINCTRL_DOUT3   (*(R32)(0x80018730))

void pwm1_init(U32 bright)

{

    HW_PWM_CTRL = 0 ;       //disable pwm 1

    HW_PWM_ACTIVE1 = (bright<<16) & 0x01FF0000 ; // set pwm 1  0<bright<0x200

    HW_PWM_PERIOD1 = 0x5B0200; // set pwm 1

    HW_PWM_CTRL = 0x2 ; //enable pwm 1

}

void pause(int time)

{

    volatile int i ;

  while (time--) i = time ;

}

void outbyte(int c)

{

   while( !(HW_UARTDBG_FR & TXFE)  );

    HW_UARTDBG_DR = c ;

}

int ddr_test(u32 density, u32 number_of_cs)

{

    unsigned int failCount = 0;

    unsigned int i;

    unsigned int mem_src;

    unsigned int *ps;

    int bank_size = density / 8;

    /* Data bus, walking ones test */

    /* Looking for shorts on the board, so no need to test both chip selects */

  printf("\n\rWriting \n\r");

    /* First, write walking ones to DDR memory */

    ps = (unsigned int *)(CSD0_BASE_ADDR + bank_size * 4);

  printf("\n\r Bank Selection done \n\r");

    for (i = 0; i <= 31; i++) {

  printf("\n\r Writing %d \n\r",i);

        *ps = 0x1 << i;

        ps++;

    }

  printf("\n\r Reading \n\r");

    /* Now, read-verify the memory */

    ps = (unsigned int *)(CSD0_BASE_ADDR + bank_size * 4);

    for (i = 0; i <= 31; i++) {

        if (*ps != (0x1 << i)) {

            failCount++;

        }

        ps++;

    }

    /* BANK ADDRESS test */

    /* CS0 bank address test - note since code is stored in first part of DDR in CSD0

       do not write data to the first bank to avoid overwriting code.

       Hence variable "i" starts at 1 not 0 */

    /* First, write data to each bank */

    for (i = 1; i <= 7; i++) {

        ps = (unsigned int *)(CSD0_BASE_ADDR + bank_size * i);

        *ps = 0x11111111 * i;

    }

    /* Second, read back data from each bank to verify */

    for (i = 1; i <= 7; i++) {

        ps = (unsigned int *)(CSD0_BASE_ADDR + bank_size * i);

        if (*ps != 0x11111111 * i) {

            failCount++;

        }

    }

    if (number_of_cs == 2) {

        /* CS1 bank address test */

        /* First, write data to each bank */

        for (i = 0; i <= 7; i++) {

            ps = (unsigned int *)(CSD1_BASE_ADDR + bank_size * i);

            *ps = 0x88888888 + 0x11111111 * i;

        }

        /* Second, read back data from each bank to verify */

        for (i = 0; i <= 7; i++) {

            ps = (unsigned int *)(CSD1_BASE_ADDR + bank_size * i);

            if (*ps != (0x88888888 + 0x11111111 * i)) {

                failCount++;

            }

        }

    }

    /* DDR ADDRESS test, test the last two banks for each chip select */

    /* CS0 */

    /* First, write data to each row */

    mem_src = CSD0_BASE_ADDR + bank_size * 6;

    for (i = 0; i < bank_size * 2; i = i + 512) {

        ps = (unsigned int *)(mem_src + i);

        *ps = 0x12345678 + 0x11111111 * i;

    }

    /* Second, read back data from each row to verify */

    mem_src = CSD0_BASE_ADDR + bank_size * 6;

    for (i = 0; i < bank_size * 2; i = i + 512) {

        ps = (unsigned int *)(mem_src + i);

        if (*ps != (0x12345678 + 0x11111111 * i)) {

            failCount++;

        }

    }

    if (number_of_cs == 2) {

        /* CS1 */

        /* First, write data to each row */

        mem_src = CSD1_BASE_ADDR + bank_size * 6;

        for (i = 0; i < bank_size * 2; i = i + 512) {

            ps = (unsigned int *)(mem_src + i);

            *ps = 0x87654321 + 0x11111111 * i;

        }

        /* Second, read back data from each row to verify */

        mem_src = CSD1_BASE_ADDR + bank_size * 6;

        for (i = 0; i < bank_size * 2; i = i + 512) {

            ps = (unsigned int *)(mem_src + i);

            if (*ps != (0x87654321 + 0x11111111 * i)) {

                failCount++;

            }

        }

    }

    if (failCount == 0) {

        printf(" DDR test passed \n");

        return 1;

    } else {

        printf(" DDR test failed \n");

        return 0;

    }

}

int main ()

{

  printf("pause \n\r");

  pause (100);

  printf("DDR2 Test Starting\n\r");

  pause (100);

  ddr_test(PARAM_DDR_TEST_DENSITY, PARAM_DDR_TEST_CS_NR);

  printf("DDR Test Finished\n\r");

  PINCTRL_DOE3 = 0x30 ;

  while (1)

  {

  pause(2000000);

  PINCTRL_DOUT3 = 0x10 ;

  printf("RAM 1\n\r");

  pause(2000000);

  PINCTRL_DOUT3 = 0 ;

  printf("test 0\n\r");

  PINCTRL_DOUT3 = 0x20 ;

  printf("test 1\n\r");

  pause(2000000);

  PINCTRL_DOUT3 = 0 ;

  printf("test 0\n\r");

   }

}

!

Thanks,

RAM

0 Kudos

2,561 Views
lategoodbye
Senior Contributor I

Hi Ram,

i see you need the same program :smileygrin:

Do you also copied the startup code (Assembler in plat_startup.h) from obds into your project? Without the SDRAM isn't initialized and accessable.

Which toolchain and version do you use?

0 Kudos

2,561 Views
Ramtry
Contributor III

Hi Stefan,

I haven't included the SDRAM init code from plat_startup.h. Basically what am doing is just modifying the OBDS project to test only DDR. My main aim is to test the DDR using standalone program using internal RAM.

Steps followed :

1)  untar "imx_28_obds_release_v1_0.tar.gz"

2) cd \imx_28_obds_release_v1_0\201040_mx28_evk_release\src\mx28

3) vi mx28.ld

4) changed this line

-->

RAM (rwx) : ORIGIN = 0x0, LENGTH = 120K

-->

  .vectors :

    {

        __vectors_start = .;

        *o(.vectors)

        __vectors_end = .;

    }>RAM

5) save and exit

6) vi mx28evk_mmcsd.bd

7) changed this line

       IVT_ADDR = 0x8000;

       LOAD_ADDR  = 0x100;

       ENTRY_ADDR = 0x0;

8) save and exit

9) cd \imx_28_obds_release_v1_0\201040_mx28_evk_release\src\drivers

10) vi makefile

11) To decrease the size of SB file, modify this line "SUB_DIRS := ddr timer uart dma"

12) Delete the sub folder except ddr, timer, uart, dma

13) cd \imx_28_obds_release_v1_0\201040_mx28_evk_release

14) ./tools/linux/build_mx28.sh

15) flash the \imx_28_obds_release_v1_0\201040_mx28_evk_release\output\mx28\bin\mx28-obds.sb file using sb_loader through USB.

16) But flashing it showing an error of

LCLLJ

LLCLLJ

UndefiîHTLLCLLJ

Undefin HTLLCLLJ

Undefin HTLLCLLJ

UndefineHTLLCLLJ

HTLLCLLJ

HTLLCLLJ

I don't know the what am missing here, please suggest me to fix this issue or give some other idea to test DDR.

Thanks,

RAM

0 Kudos

2,561 Views
lategoodbye
Senior Contributor I

Hi Ram,

okay if you modify obds and not led example you don't need plat_startup.h.

My changes on obds are very close to yours, except:

- i removed the C file for the application uart

- i removed the static structures for test cases

- i placed the call for run_ddr_test() direct into platform_init()

But finally i get the same results as you (see reply to GraceSi). So i decided to implement the DDR test in the led example. But than comes the problem with the collision.

Here are my assumptions why it won't work with obds:

- the binary of obds is still too big and there are not enough memory for variables and stack

- the settings in mx28.ld are wrong (try to reduce LENGTH to a smaller value than 120k)

- the settings in mx28evk_mmcsd.bd are wrong (may be the ipl image overlaps obds)

Best regards

Stefan

0 Kudos

2,561 Views
Ramtry
Contributor III

Hi Stefan,

I am using GCC 4.3.2 from Mentor graphics.

0 Kudos

2,561 Views
lategoodbye
Senior Contributor I

Hi Yuri,

thanks for the application. If i compile the example with my toolchain (gcc version 4.8.3 20131129, newlib), i get some strange messages, but it seems to work:

      Heap and stack collision
                              Heap and stack collision
                                                      pause
start

What toolchain should i use for the example?

0 Kudos

2,561 Views
Yuri
NXP Employee
NXP Employee

The message is from syscall.c (C-function _sbrk) .

Perhaps memory layout is not correct (to get enough amount of memory for heap) 

0 Kudos

2,561 Views
lategoodbye
Senior Contributor I

Hi Yuri,

i changed many settings in the crt.s and MX28_ocram.ld, but i always get "Heap and stack collision" also with original LED example. Because i didn't get this message with the precompiled binary test.sb from the ZIP file, i thought the problem has something to do with my toolchain.

Do you know for which toolchain the LED example was designed for?

0 Kudos

2,560 Views
fernandolopes
Contributor III

Hi Stefan,

I got the same error as you when I compile the LED example in my linux toolchain (https://launchpad.net/gcc-arm-embedded/+download).

If I compile with the windows version of the arm-none-eabi-gcc from CodeSourcery (Mentor) I don't get this error using these flags:


CXXFLAGS =-Os -Wall -mcpu=arm926ej-s -march=armv5te -mfloat-abi=soft

The -s flag don't let the code run on my board and I only get an error code on the UART: 0x8050100f.

0 Kudos

2,560 Views
Yuri
NXP Employee
NXP Employee

arm-none-eabi-gcc is from CodeSourcery (Mentor).

Sourcery CodeBench Lite Edition including ARM GCC IDE - Mentor Graphics

0 Kudos