This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

omap l138 boot error



Our DSP application sometimes gets stuck booting after a code change. The DSP will run through c_int00, call main, and during TSK_create, a br instruction jumps to an invalid address and the DSP resets. I have noticed that in some cases adding or removing one line of code in the main application can cause or cure the issue. The line of code never has a chance to run before the error happens, but does change the link map a bit. In particular I have notice that several .cinit destination addresses change, all of which are related to DSP/BIOS.

Any ideas on what could cause this?

#include "platform.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <std.h>
#include <gbl.h>
#include <clk.h>
#include <tsk.h>

#define LOAD_WINDOW_IN_MS (500)

#pragma DATA_SECTION(__main_args__,".args");
uint8_t __main_args__[1024];


static uint32_t minIdleFxnTime = 0xFFFFFFFF;
static uint32_t loadWindowTime = 0;
static int32_t  currLoad = 0;

int32_t GetLoad( void )
{
  return currLoad;
}

void UpdateDspToArmTick();
unsigned int GetUsTime();

void IdleFunction( void )
{
  static uint32_t idleCount = 0;
  static uint32_t totalTime = 0;
  static uint32_t t0 = 0;
  uint32_t        t1 = 0;
  uint32_t        delta;

  // Keep track of times through this function
  GetUsTime();
  UpdateDspToArmTick();
  idleCount++;

  // Compute the time difference since the last call this function
  t1 = CLK_gethtime();
  delta = t1 - t0;
  t0 = t1;

  // Accumulate totalIdleTime
  totalTime += delta;

  /*
   * 'minloop' keeps track of the shortest time thru the IDL loop.
   * Note that we check to make sure delta is not zero (delta
   * will be zero during IDL loop calibration)
   */
  if (delta != 0 && delta < minIdleFxnTime)
  {
    minIdleFxnTime = delta;
  }

  // Compute the CPU load as 100 - "percent time idle"
  // "percent time idle" = 100 * (idleCount * minIdleFxnTime)/totalTime
  if (totalTime > loadWindowTime)
  {
    currLoad = (int32_t) (100 - ( (100 * idleCount * minIdleFxnTime) / totalTime));
    idleCount = 0;
    totalTime = 0;
  }
}

// Replacement clock function to use in place of RTS lib version
_CODE_ACCESS clock_t clock(void)
{
  clock_t result;

  // Calculate absolute time in microseconds
  result = (clock_t) ((CLK_gethtime() *  CLK_cpuCyclesPerHtime() * 1000) / GBL_getFrequency());

  return result;
}

void Initialize( );

extern void exit(), _auto_init();
extern void IDL_loop();
extern void BIOS_start();
extern far void BCACHE_bootInit();
extern far void auto_init(const void *cinit, const unsigned int dp);
/*---------------------------------------------------------------------------*/
/* ALLOCATE THE MEMORY FOR THE SYSTEM STACK.  THIS SECTION WILL BE SIZED     */
/* BY THE LINKER.                                                            */
/*---------------------------------------------------------------------------*/
asm(" .global __STACK_SIZE");
asm(" .global __stack");

/*
 * Define special symbol to guarantee that this boot file gets linked
 * instead of boot file from rts.lib (SDSsq24217). The GBL_config macro
 * will reference this symbol forcing a linker error if non-bios boot.obj
 * has been linked with application.
 */
asm(" .def GBL_boot");
asm("GBL_boot .set 1");

asm("__stack: .usect   .stack, 0, 8");


/*
 * Put c_int00 in the .sysinit section.
 */
asm(" .sect \".sysinit\"");

#pragma CODE_SECTION(c_int00,".sysinit")
extern void interrupt c_int00()
{
//    volatile int debugDummy = 0;
//
//    while(debugDummy == 0);
    /*
    * Clear IER register.  This is necessary to prohibit left-over
    * interrupts from being serviced.  This is not necessary if users
    * reset the part before reload or restart but ...
    */
    asm("        zero b0");
    asm("        mvc b0,ier");

    /*------------------------------------------------------------------------*/
    /* SET UP THE STACK POINTER IN B15.                                       */
    /* THE STACK POINTER POINTS 1 WORD PAST THE TOP OF THE STACK, SO SUBTRACT */
    /* 1 WORD FROM THE SIZE.                                                  */
    /*------------------------------------------------------------------------*/
    asm("      mvkl __stack,SP");
    asm("      mvkh __stack,SP");
    asm("      mvkl __STACK_SIZE - 4,B0");
    asm("      mvkh __STACK_SIZE - 4,B0");
    asm("      add  B0,SP,SP");

    /*------------------------------------------------------------------------*/
    /* THE SP MUST BE ALIGNED ON AN 8-BYTE BOUNDARY.                          */
    /*------------------------------------------------------------------------*/
    asm("      and  ~7,SP,SP");

    /*------------------------------------------------------------------------*/
    /* SET UP THE GLOBAL PAGE POINTER IN B14.                                 */
    /*------------------------------------------------------------------------*/
    asm("      .global $bss");
    asm("      mvkl $bss,DP");
    asm("      mvkh $bss,DP");

    /*------------------------------------------------------------------------*/
    /* SET UP FLOATING POINT REGISTERS FOR C67 ONLY                           */
    /*------------------------------------------------------------------------*/
  #ifdef _TMS320C6700
    asm("      mvk   0,B3");     /* round to nearest */
    asm("      mvc   B3,FADCR");
    asm("      mvc   B3,FMCR");
  #endif

    /*------------------------------------------------------------------------*/
    /* INITIALIZE CONTROL REGISTERS (FOR BIOS ONLY)                           */
    /*------------------------------------------------------------------------*/
    asm("      mvk     0,B3");
    asm("      mvc     B3,AMR");          /* addressing mode register */
    asm("      mvc     B3,CSR");          /* control status register */

    /*------------------------------------------------------------------------*/
    /* CALL BCACHE_bootInit function.  This function is determined by config  */
    /* and bound in the generated linker command file.                        */
    /*------------------------------------------------------------------------*/
    BCACHE_bootInit();

    /*------------------------------------------------------------------------*/
    /* GET THE POINTER TO THE AUTOINITIALIZATION TABLES INTO THE FIRST        */
    /* ARGUMENT REGISTER (A4)                                                 */
    /*------------------------------------------------------------------------*/
    asm("      .global cinit");
    asm("      mvkl cinit,A4");
    asm("      mvkh cinit,A4");

    /*------------------------------------------------------------------------*/
    /* PASS THE CURRENT DP TO THE AUTOINITIALIZATION ROUTINE.                 */
    /*------------------------------------------------------------------------*/
    asm("      mv   DP,B4");

    /*------------------------------------------------------------------------*/
    /* CALL THE AUTOINITIALIZATION ROUTINE.                                   */
    /*------------------------------------------------------------------------*/
    asm("      .global __auto_init");
    asm("      mvkl __auto_init, B0");
    asm("      mvkh __auto_init, B0");
    asm("      mvkl boot_ret, B3");
    asm("      mvkh boot_ret, B3");
    asm("      b    B0");
    asm("      nop  5");
    asm("boot_ret:");

    asm("      .global ___main_args__");
   asm("      mvkl ___main_args__,A0");
   asm("      mvkh ___main_args__,A0");
   asm("      ldw *+A0[2],A6");          /* envp */
   asm("      ldw *+A0[1],B4");          /* argv */
   asm("      ldw *+A0[0],A4");          /* argc */

    /*------------------------------------------------------------------------*/
    /* CALL THE USER'S PROGRAM.                                               */
    /*------------------------------------------------------------------------*/
    //   main();                 /* main(A4, B4, A6); */
    asm("      .global _main");
    asm("      mvkl _main, B0");
    asm("      mvkh _main, B0");
    asm("      b    B0");
    asm("      mvkl main_ret, B3");
    asm("      mvkh main_ret, B3");
    asm("      nop  3");
    asm("main_ret:");

    /*------------------------------------------------------------------------*/
    /* START RUNTIME FOR BIOS.                                                */
    /* The call to BIOS_start does not return if the Task Manager is enabled  */
    /*------------------------------------------------------------------------*/
    BIOS_start();

    /*------------------------------------------------------------------------*/
    /* FALL INTO THE BIOS IDLE LOOP, NEVER RETURN.                            */
    /*------------------------------------------------------------------------*/
    IDL_loop();
}

TSK_Handle g_InitializeTask;

void main( void )
{
    TSK_Attrs  attrs = TSK_ATTRS;

    volatile int debugDummy = 0;

    if(g_pSharedMemory->dspInitParams.debugLevel & DSP_CODE_COMPOSER_CONNECT)
        while(debugDummy == 0);

    // Start Control task
    attrs.stacksize = 4 * 1024;
    attrs.priority  = TSK_MAXPRI;
    attrs.name = "Initialize";

    g_InitializeTask = TSK_create( (Fxn)Initialize, &attrs );

    return;
}


/************************************************************
* Local Function Definitions                                *
************************************************************/


/***********************************************************
* End file                                                 *
***********************************************************/