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.

MEM_free() blocks Interrupts from being serviced?

Other Parts Discussed in Thread: TMS320C6414

Hi,

It seems that DSP_BIOS' MEM_Free() blocks interrupts from being serviced, sometimes for quite long time.

my environment:
- TMS320C6414, build tools V5.0, DSP BIOS V4.92
- A FPGA triggers an Interrupt (via DSP 'external pin 6') when a video datastream FIFO threshold overruns (once about every 60us)
- The DSP application (several TSK-functions) can call MEM_free() at any time (asynchronous to the video interrupts)
- Switching FPGA IOs allows debugging with an oscilloscope -> this way I discovered that this video interrupt is not executed (even though its triggered) while MEM_free is executed. For example (chan1: low when Video Interrupt is executed, chan 2: high when MEM_free is executed):

It seems that a part within the MEM_free call blocks the HWI (interrupt service function) from being executed for long time, sometimes >150us. It seems as if DSP_BIOS was not compiled with the -mi option (breaing rolled loopes after a certain interrupt threshold).

- Is there a workaround?
- Is a DSP_BIOS version available that was compiled with interrupt threshold, for example -mi10000?
- Is there a way to prevent MEM_free from blocking interrupts?

My project is quite old. It has spread over the world in a lot of different scenarios. The truth is that I dont want to update to a new compiler or DSP_BIOS version unless there is a good reason. Is there a solution with BIOS V4.92?

bye,

Thomas

  • I tried to use a V5 BIOS (V5.33.06) and discovered one big problem with that: my application uses csl broadly and there is no more csl in BIOS >= V5. So using BIOS >= V5 in my application would require porting it to CSLR or BIOS functions where possible. I consider this impossible in the environment of my application.

  • MEM calls a lock during the free (and alloc). This lock protects against multiple threads trying to access the internal linked list of free blocks. The MEM_free traverses this list, looking for the proper location to return the buffer. It also checks to see if it should coalesce any free memory before or after the block that is being freed. Since the length of free-list is non-deterministic, the duration that the lock is non-deterministic.

    The lock can be set by the application via the MEM_register_lock() function. Do you register a specific lock?

    Todd

  • Hi Todd,

    thanks for your answer. I did not know MEM_register_lock(), the function is not documented in the BIOS API doc (spru403). It is not there in the headers of the V 4.90 I use. It seems that it was introduced in V5. But I think that I cannot use V5 because of my application using CSL. So - no. I dont use a special locking.

    Meanwhile, I replaced the BIOS MEM- functions by malloc/free (which is also somehow a problem because I require cacheline size alignment...). The locking is still visible but lasts for a shorter time, maybe up to 90us instead of 130. I dont free/alloc in interrupts (HWI/ISR or how you call them) - since it is not possible. Its ok if a TSK blocks for whatever time, anyway BIOS doesn preempt a TSK unless it reaches a preemption point like TSK_yield.

    What I need is an interrupt being serviced within a certain time. The behaviour does not seem to come from a (semaphore kind) multithread lock, it seems to come from a rolled loop within MEM_free that is compiled without interrupt threshold (-mi1000) or something similar. The interrupt is not halted on a lock, it is not executed at all while MEM_free is being executed in a TSK.

    is there a way to get a -mi1000 compiled version of BIOS V4.90.270?

    bye,

    Thomas


  • Thomas,

    Just to confirm. Are you using 4.92 or 4.90.270?

    MEM_register_lock() should be in the mem.h file. It was an undocumented feature for awhile. Can you confirm which lock is being used. Look at the MEM_D_lockaddr variable. What function does this correspond to?

    We cannot provide a patch for this release. I can provide the code for you offline. You can rebuild the MEM_free.c file with your application. I'll send you a friend request.

    FYI: As part of the cdb conversion, CSL code can be generated. It's been awhile since I looked at this though.

    Todd

  • Hi Todd,

    In the header of mem.h the version indicated is 4.90.270:
    /* "@(#) DSP/BIOS 4.90.270 12-18-03 (barracuda-o04)" */

    you are right - MEM_D_lockaddr its there in mem.h.

    Looking for MEM_D_lockaddr in the watch after loading my application shows it being at 0x000cdf4c (MEM_D_unlockaddr at 0x000CDF50) - same is visible in map-file. It contains the value 0x000A8CC0 (MEM_D_unlockaddr contains 0x000A8CDC). According to 'view memory' there is no symbol directly at this location. According to the map file, tsk_stup_inst.o is linked to 0x000a8cc0.

    Could it be that this lock-function locks by disabling interrupts via the IER register or GIE? Would it be an option to define a function that uses SEM kind of locking since anyway I only alloc/free within TSK functions? What function signature is expected of the function registered by MEM_register_lock()?

    thanks for the offer with the code, maybe its an option. We already compiled rts.src using -mi10000, if the bios sources compile in a similar way, I will manage.

    bye,

    Thomas

  • Hi Todd,

    I tried MEM_register_lock/unlock - registered an empty Int test() function. The MEM_D_lockaddr points to my function, still the lockings appear in the same way. So from my point of view either this MEM_D_lockaddr is ignored in BIOS V4.90.270 or the problem comes from another side, like a too high interrupt threshold.

    bye,

    Thomas

  • Thomas,

    tsk_stup_inst.o contains the locks that are using in the system. They are semaphore based. This is the default.

    I was looking at MEM_free's assembly for that release. There might be a case where the branch delay slots in a tight loop are keeping interrupts disabled too long. We generally build our libraries with -mi1 or -mi10. However, I cannot confirm this for the c64 libraries. I'll sent you the mem_free.c and _mem.h files from the release. You should be able to include them in your application. Another option is to use BUF module for your memory manager. This memory manager is fixed size and there are no traversal of linked lists.

    Todd

  • Hi Todd,

    thanks a lot. I compiled your file along with my project and the effect is gone. Now it looks like that (chan1 low: videoISR execution, chan 2 high: MEM_free execution):

    the MEM_free problem seems to be solved now, I cannot trigger interrupts being lost at the moment. I cannot verify that it is ok since I dont know all the scenarios in which my application is used.

    To be sure that there are no other similar loops inside BIOS it would be great to have the complete code built in the same way. I think you will not be able to send me the sources in a .src archive like the rts. But: would it be possible for you to compile this old BIOS version with build tools V5.0.0.0 andcl6x -c -eo.o -ml2 -k -o3 -ms0 -pm -mi10000 -mv6400 -dCHIP_6414?

    The reason why I want this is that missing such a video interrupt is a big problem since this can result in a defect in the grabbed image, for example the image being shifted partly. I know now that rolled loops inside BIOS function can cause this effect. I want to be sure that it does not happen again...

    bye,

    Thomas

  • Hi Thomas --

    Rebuilding that old version of BIOS is possible, but I think it'd be better to move to BIOS 5.x.

    BIOS 5.33 and 5.41 will work with CSL.  The big change between 4.9 and 5.x was that we no longer support CSL configuration.   CSL will still work with BIOS, but it is not configurable with the configuration tool.

    We have a conversion utility called cdb2tcf that can be used to translate a .cdb file to a .tcf file.  If the cdb file has CSL in it, then the conversion utility will generate a separate .c file that can be added to your BIOS 5.x application.

    I think it'd be best to migrate to newer BIOS 5.x.  Can you .zip up your .cdb file and attach it to this forum?  I'll review the .cdb file to see how big of a problem it will be to migrate to BIOS 5.x.


    Thanks,
    -Karl-

  • Hi Karl,

    I thought that the main problem for me is the need to replace the CSL library functions and defines? I use functions like CSL_init, CACHE_enableCaching, EDMA_intAlloc, EDMA_configArgs, IRQ_globalDisable, etc. or macros like CACHE_L2_LINESIZE, IRQ_EVT_EXTINT5.

    The use of this functions and macros is spread all over my project - its not just replacing a few lines. Especially with DMA and Cache we had troubles stabilizing the project (the truth is that working on memory that is manipulated by DMA and DSP "behind" and "in front" of the cache (along with Interrupts reading cachelines that a TSK DMA just fills...) on the DSP is quite a headache...).  I think that it would be quite a risk for me to replace the EDMA-csl functions by something different - this means again weeks of testing and then still releasing a software that will show sometimes strange problems somewhere on a machine somewhere on the other end of the world.

    I ported part of the code using CSL for a new project (but this is not usable in the old environment). I replaced CSL by CSLR, basically manipulating in registers instead of having an API call. I thought of having to do that again (for different code) to switch to BIOS V5. The old CSL was part of the V4 BIOS as far as I know, so using V5 with CSL would mean using parts of V4 BIOS along with V5...

    Maybe I am wrong? Is there a way of using BIOS V5 along with code that calls CSL functions?

    If there is a way I really would like to upgrade to V5 BIOS and V6.1 build tools to be on a more 'modern' base... bye and thanks to you and Todd for your support,

    Thomas

  • Hi Thomas --

    You can continue to use CSL with BIOS 5.41.   The main change is that we do not support the configuration of CSL modules within BIOS configuration tool.  And we do not ship CSL .h and .lib files as was done back in the 4.9x days.   You should be able to use the old CSL .c and .h files and libraries with BIOS 5.41.  You just need to call CSL_init() in your main() function prior to using any CSL APIs. 

    If you are using CSL in your configuration file, then cdb2tcf will generate a separate csl.c file to save all this configuration data.  And you'll need to add this to your project.

    See appendix A of this manual for more info on converting your .cdb file to a .tcf file as needed by BIOS 5.41.

    http://www.ti.com/lit/ug/spru007i/spru007i.pdf

    Regards,
    -Karl-