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.

volib c6p 1.0.1.2 tduOpen() exception

Other Parts Discussed in Thread: TMS320C6748, SYSBIOS

Hi,

I've run into an exception in tduOpen() when running the code on the evaluation board for TMS320C6748. I've traced through the steps of tduGetSizes(), tduNew(), and when in calling tduOpen() the exception occurs. Can anyone provide feedback as to what might be happening?  I see that the internal tduDetContexts affects the tduBufs sizes. When tduDetContexts is same as from example code, then most of the time tduOpen() is okay. I say most of the time because once the exception still occurred. I had thought that any detector that's not needed, don't have to be included in tduDetContexts. When I remove a few, the tduBufs's sizes decrease, and tduOpen() fails. I've run the code on the simulator and it works fine. Below is the tduDetContexts from the example code, and the tduBufs sizes.

/* TDU Internal Contexts */
const tduDetContext_t *tduDetContexts[] = {
/*** Put all th SFDF detectors together, one after another ***/
  &tduIncV23BW_MARKS_F,
  &tduIncV21LOW_MARKS_F,
  &tduIncTT1khz_F,
  &tduIncCNG_F,
  &tduIncV21LOW_SPACES_F,
  &tduIncB202_MARKS_F,
  &tduIncBELLTX2_F,
  &tduIncV23FW_MARKS_F,
  &tduIncV18A_F,
  &tduIncV21UPPER_MARKS_F,
  &tduIncSS7COR_F,
  &tduIncV18A_S_F,
  &tduIncSS7COT_F,
  &tduIncV25_F,
  &tduIncB202_SPACES_F,
  &tduIncBELLTX1_F,
  &tduIncSF_F,    
  &tduIncSIA_F,
  &tduIncSIA_S_F,
/*** Put all the SFDT detectors together, one after another ***/ 
  &tduIncV23FW_MARKS_T,
  &tduIncSS7COT_T,
  &tduIncV25_T_RX,
  &tduIncBELLRX1_T,
  &tduIncBELLRX2_T,
//  NULL,/* tdu_SFDT_DET_V18A_RX */
//  NULL,/* tdu_SFDT_DET_V18A_S_RX */
//  NULL,/* tdu_SFDT_DET_V21LOW_MARKS_RX */
//  NULL,/* tdu_SFDT_DET_V21LOW_S_RX */
//  NULL,/* tdu_SFDT_DET_CIDCAS_RX,tdu_SFDT_DET_CASH_RX  */
//  NULL, /* tdu_SFDT_DET_CASH_RX */
  &tduIncSIA_T_RX,
  &tduIncSIA_S_T_RX,
  &tduIncSFDT_DUMMY1_T,
  &tduIncSFDT_DUMMY2_T,
  &tduIncSFDT_DUMMY3_T,
/*** Put all th MF detectors together, one after another ***/ 
  &tduIncDTMF,
  &tduIncR1,
  &tduIncR2FW,
  &tduIncR2BW,
  &tduIncV8BIS_FS_F,
  &tduIncCOIN_TONES,
/*** ... the rest ***/   
  &tduIncV21,
  &tduIncCPT,
  NULL
};

 

 

[0] = {...}
    mclass = 0
    log2align = 1
    size = 100
    volat = 0
    base = 0xC0016488
[1] = {...}
    mclass = 0
    log2align = 10
    size = 1024
    volat = 1
    base = 0xC0016800
[2] = {...}
    mclass = 0
    log2align = 1
    size = 440
    volat = 0
    base = 0xC00164F8
[3] = {...}
    mclass = 0
    log2align = 0
    size = 362
    volat = 0
    base = 0xC0016C08
[4] = {...}
    mclass = 0
    log2align = 0
    size = 106
    volat = 0
    base = 0xC00166B8

  • Kevin,

    Are you running a SYSBIOS application?  If so what version? Also are you using CCS? which version of CCS?

    BIOS does have an Exception handler which can give you additional information.

    Judah

  • Hi Judahvang,

    Bios 6.30.03.46, ccs v4, and I've enabled print for the exception handler. What should I be looking for? (The problem's gone away. But for future reference.)

    Kevin

  • Kevin,

    In the BIOS version that you are using you have to enable print like you mentioned.  Later versions of BIOS has this enabled by default.

    The main things that you want to look for is what the values of NRP and B3 are at the time of the Exception.  These are printed out as part of the default Exception handler.  The NRP tells you approximately where the exception happened.  B3, of course, is the function return pointer so it can also be used to back trace where the Exception happened.  Typically, using these two points, if an Exception always occurs at the same point, you can trace back to determine how the exception happened.

    The exception also prints out what kind of exception occured...internal or external.  If internal it can further break it down to whether its an "instruction fetch" or "opcode", etc..

    Judah

  • This problem is happening frequently -- it comes and goes. Sometimes after a rebuild it works. Then for some unkown reason it stops working. I'm certain that I'm not modifying any of the tdu contexts, or tdu bufs. Can anyone provide an explanation? Here is the printout of the exception. It happens in tduOpen().

    Exception_handler: EFR=0x2, NRP=0x0, mode=supervisor
    Internal exception: IERR=0x1
    Instruction fetch exception
    A0 =  00000000, A1 =  00000004
    A2 =  00000000, A3 =  0000fdff
    A4 =  0000fdff, A5 =  00000000
    A6 =  00000001, A7 =  00000000
    A8 =  00000000, A9 =  00000000
    A10 = ffbfff7f, A11 = c0024fa4
    A12 = 00000000, A13 = 00000000
    A14 = 00000000, A15 = 00000000
    A16 = c0025034, A17 = 00000000
    A18 = c002502c, A19 = 00000000
    A20 = c0022678, A21 = 0000006c
    A22 = 0000004c, A23 = 5c072c0b
    A24 = c73300ca, A25 = ec4260ed
    A26 = e05b27f8, A27 = b8e65801
    A28 = 00000001, A29 = 00000020
    A30 = c002267d, A31 = 0000000c
    B0 =  00000000, B1 =  00000001
    B2 =  c0024f44, B3 =  c0029da8
    B4 =  00000002, B5 =  00000001
    B6 =  00000000, B7 =  00000004
    B8 =  c001ff8d, B9 =  68000000
    B10 = 00000000, B11 = 00000000
    B12 = 00000000, B13 = 00000000
    B14 = c002e524, B15 = c0024f60
    B16 = 00000000, B17 = c0020ed0
    B18 = 00000000, B19 = 00000078
    B20 = 00000069, B21 = 00000000
    B22 = 0000040f, B23 = 00000000
    B24 = 00000003, B25 = 00000000
    B26 = 00000000, B27 = 14858d24
    B28 = c0016ea0, B29 = 00000002
    B30 = ffffffff, B31 = 0000007f
    NTSR = 0001000f
    ITSR = 00000000
    IRP  = 00000000
    SSR  = 00000000
    AMR  = 00000000
    RILC = 00000000
    ILC  = 00000000
    Exception abort

  • Kevin,

    Exception_handler: EFR=0x2, NRP=0x0, mode=supervisor
    Internal exception: IERR=0x1
    Instruction fetch exception
    B3 =  c0029da8

    From the output, I can see that your code is jumping to address 0 which is causing the exception. [This is what the NRP is saying].

    B3 is the return pointer (Where the code was expecting to return).  What I typically do when I encounter an exception is I put the B3 in the disassembly window.  Then I scroll up to determine what function caused the exception.  If this is a function this isn't called that often you could put a breakpoint here then re-run the program and hope that you encounter the exception condition.

    Judah

  • Hi,

    Can someone explain about the memory allocation involved in using the TDU? And what should the various tdu contexts be set to? I require Call-Progress-Tone detection and Test-tone detection. Currently I'm using the same values for the tdu context as found in the example tdusim.c . This setup worked for a while, but is no longer working now, and there wasn't any change to the code. tduOpen() fails, and if it doesn't fail, the tdu isn't recognizing any signals, even though the signals haven't changed and were detected previously.

     

    Much thanks,

    Kevin Trieu

     

     

  • Hi Kevin,

    This problem has been redirected to me -- I will be able to help provided this is a TDU issue. 

    I've reviewed this thread and it sounds as though you had the TDU "working" for a while as long as you didn't change the detector context structure.  Now though, with the original TDU detector context (from the simulation) your example no longer works. 

    First off -- is this correct?  If not what have I missed?

    To get started I have a quick question.  Are you checking the return codes from tduGetSizes() and tduNew()?  If so, what are they?

    Regards,
    Charlie

  • Hi Charlie,

    Yes, that's correct. The TDU was working at first for a while, then stopped working. Now with some adjustments it looks like it's working again.

    BEFORE and AFTER: tduGetSizes() returns tdu_NOERR.

    BEFORE: tduNew() returns 1, which is an error.

    AFTER: I thought the cause might be the tduInst pointer wasn't initialized, so I set it to NULL, and afterwards tduNew() returns 0. Why does this seem to work? I've only called tduNew() once during a run. Is it that the uninitialized tduInst pointer had a value from a previous run, and the call to tduNew() detected a tduInst already in use and returned error?

    AFTER: Also, I've memset the tduCfgCtl to 0 before each call to tduControl. Now it looks like the TDU is working.

    Question about memory: I would like to avoid dynamic memory allocation for the tduBufs. Can you provide example for how to do that? I had thought to hard-code the required memory for tduBufs in a static array, and found that tduNew() fails if tduGetSizes wasn't called before.

     

    Thanks,

    Kevin Trieu

  • Hi Kevin,

    Good catch.  The call to tduNew() checks the instance pointer (pointed to by **tduinst) and skips all buffer assignment if it is not NULL.  This is done to ensure the TDU is using an "available" instance pointer (tduDelete() sets the instance pointer back to NULL).  I would guess that, since the code wasn't explicitly setting the instance pointer to NULL, you would get NULL somewhat randomly sometimes due to uninitialized memory.  Anyways, I suspect you will find more deterministic performance now.

    You can easily use static buffer allocation for the TDU -- or any other component that follows the ECO API.  Just declare static buffers and assign them one-by-one rather than in a for loop:

    /* Dynamic */
    for (i=0; i<tduNbufs; i++) {
      tduBufs[i]           = bufs[i];
      tduBufs[i].mclass    = ecomem_CLASS_EXTERNAL;
      tduBufs[i].log2align = bufs[i].log2align;
      tduBufs[i].volat     = bufs[i].volat;
      tduBufs[i].base      = (bufs[i].size) ? ALIGNED_ALLOCATION_ROUTINE() : NULL;
    }
    /* Static */
      tduBufs[0]           = bufs[0];
      tduBufs[0].mclass    = ecomem_CLASS_EXTERNAL;  
      tduBufs[0].log2align = bufs[0].log2align;      
      tduBufs[0].volat     = bufs[0].volat;
      tduBufs[0].base      = &tdu_buffer_0[0];

      tduBufs[1]           = bufs[1];
      tduBufs[1].mclass    = ecomem_CLASS_EXTERNAL;  
      tduBufs[1].log2align = bufs[1].log2align;      
      tduBufs[1].volat     = bufs[1].volat;
      tduBufs[1].base      = &tdu_buffer_1[0];
      ...

    The buffers tdu_buffer_0, tdu_buffer_1, etc. are declared statically.  You will need to ensure that the alignment is met for each buffer (PRAGMA).

    You should also be sure to avoid Global Memory Pool (GMP) allocation unless your system has a scheme that supports this (and is similar to what the TDU expects).  You can avoid GMP allocation by ensuring pointers 4 through 9 of the TDU Context are NULL.

    tduContext_t tduContext = {
      pointer,
      pointer,
      pointer,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      pointer,
      ...

      ...
    }


    Good luck.

    Regards,
    Charlie

  • Hi Charlie,

    I developed a DSP sw for a VOIP PBX and I would like to use VoLIB TDU in replacemente of Goertzel DTMF dect  I already implemented.

    I have to allocate static buffers, but how can I decide at compile time the size of  tduBufs[??], the size of tdu_buffer_1[??] and the alignment to be used in pragma

    I am using CCS v3.1 platinum small memory model. Is it compatible with VoLIB ? I should use large memory model?

    Thank you very much,

    best regads,

    Sebastiano

  • Hi Sebastiano,

    Sebastiano Pastorino said:
    I have to allocate static buffers, but how can I decide at compile time the size of  tduBufs[??], the size of tdu_buffer_1[??] and the alignment to be used in pragma

    If you know your configuration (i.e., enabled detectors)  beforehand, you can run the simulation configured as the solution will be and observe buffer alignment and size specifications.  It generally doesn't hurt to over-allocate and definitely doesn't hurt to over-align -- depending on how much wiggle room you have with memory.

    Sebastiano Pastorino said:
    I am using CCS v3.1 platinum small memory model. Is it compatible with VoLIB ? I should use large memory model?

    If you are using VoLIB release 1.0.1, the CCS projects provided have been created for CCS version 4.x.  I haven't tried them on CCS 3.x, but I would suspect that they are backward-compatible.  Please let me know if they aren't.

    Yes, you should use the large memory model.

    Best Regards,
    Charlie