Framework Components FAQ
From Texas Instruments Wiki
What is Framework Components?
Framework Components is comprised of XDAIS algorithm resource managers and functional interfaces.
- DSKT2 - used for creating and interacting with XDAIS algorithms.
- RMAN - General purpose resource manager (introduced in FC 2.00)
- ECPY - DMA-based memory copy functional library built to work with the RMAN resource manager
- DMAN3 - used for sharing QDMA channels from an EDMA3 device with XDAIS algorithms. (Deprecated as of FC 3.23)
- ACPY3 - DMA-based memory copy functional library. (Deprecated as of FC 3.23)
The FC API Reference Guide provides details on the APIs.
TI's marketing team also has a description of the Framework Components product.
Where can I download Framework Components?
Where's the DSKT2 User's Guide?
The FC 2.x API Reference Guide also includes DSKT2 API documentation.
What exactly is "scratch memory" and when can my algorithm use it ?
Scratch memory is a scheme for sharing memory between XDAIS algorithms. DSKT2 implements this scheme by distributing available memory (usually internal memory) into scratch groups and allowing algorithms to be associated with a particular scratch group. The distribution of different memory segments within various scratch groups is done via DSKT2's configuration.
All algorithms in a particular scratch group potentially share their scratch memory, hence they do not truly 'own' this memory at the time the algorithm is created or granted its memory (by DSKT2). Only after the algorithm is 'activated' (i.e, the framework calls the
IALG_Fxns.algActivate() on the algorithm's IALG_Handle), does it become the sole owner of it's scratch memory. The algorithm continues to own the memory till the point the framework 'deactivates' the algorithm (by calling
One of the most common reasons for inconsistent codec behavior when integrating multiple algorithms in a framework, is improperly written
algDeactivate() functions. Often algorithm writers make the mistake of clearing out scratch memory as soon as it is assigned (i.e. during
IALG_Fxns.algInit()). However, at this time, the algorithm does NOT own the scratch memory (it is the owner of only the persistent memory granted to it); and another algorithm in the system might be using this scratch memory. Algorithms should only access this scratch memory between the
algDeactivate() calls by the framework.
Another common mistake is not backing up scratch memory to persistent memory. After an algorithm is deactivated, its scratch memory contents may be overwritten by some other algorithm in the same scratch group. Hence, any memory contents that need to 'persist' have to be copied from the scratch memory to persistent memory in the
Scratch memory concepts are further explained in DSKT2 User's Guide.
Which heap does alg-requested
IALG_EXTERNAL memory come from?
The same heap configured for
In general, DSKT2 does its best to follow this mapping:
- IALG_DARAM0: DSKT2.DARAM0
- IALG_DARAM1: DSKT2.DARAM1
- IALG_DARAM2: DSKT2.DARAM2
- IALG_SARAM0: DSKT2.SARAM0
- IALG_SARAM1: DSKT2.SARAM1
- IALG_SARAM2: DSKT2_SARAM2
- IALG_IPROG: DSKT2.IPROG
- IALG_EPROG: DSKT2.EPROG
- IALG_ESDATA: DSKT2.ESDATA
- All other (including IALG_EXTERNAL): DSKT2.ESDATA
DSKT2_freeAlg() call my alg's
DSKT2 doesn't invoke the alg's
algFree() method in today's
DSKT2_freealg() implementation because it remembers the resources the alg requested during its
algInit(). As a result, it can free the algorithms memory without invoking the algorithm's
This optimization has a side effect in that it "works around" a common algorithm defect of not returning the same
memTab table that was returned during initialization. In order to return the right
memTab, the alg often must retain the create params provided to it during init. A common alg defect was to not retain these create params, and as a result, return an incorrect
memTab. While this is still a defect, and the alg should be fixed, these defects are not seen when using DSKT2.
Note that this optimization is done in today's DSKT2 implementation, but may not be done in future implementations, and other frameworks that XDAIS algs can plug into may not make this optimization. As a result, algs should not use this internal, DSKT2-specific implementation detail; algs should continue to implement
What is the lazy deactivation feature?
Per the XDAIS spec, applications must call
DSKT2_deactivateAlg() before and after invoking an algorithm's processing methods.
DSKT2 employs a lazy deactivate feature where calls to
DSKT2_deactivateAlg() simply place the algorithm instance on a list of deactivated algs. The deactivated algorithm's
IALG_Fxns->algDeactivate() method will not be immediately invoked. The deactivated algorithm's
IALG_Fxns->algDeactivate() method is really called when another algorithm instance in the same scratch group is activated.
If no other algorithm instances in the same scratch group is activated before the lazily deactivated instance, the preparatory
DSKT2_activateAlg() will simply take the alg off the deactivated list.
This removes any unnecessary, back-to-back,
algActivate() calls as a performance optimization.
Why does DSKT2 provide external memory when my alg asked for internal?
DSKT2, by default, employs a best effort, "create the alg if at all possible" approach. Per the XDAIS spec, the memory requested by the algorithm is a request, not a requirement. As a result, while DSKT2 will first try to satisfy the exact memory request, if that can't be met, it will try external memory as a backup. The thinking is that while the algorithm may run slower, at least it can be created and run.
Some algorithms require internal memory as they may be using hardware accelerators which can only access internal memory. In these cases, DSKT2's granting of external memory can create issues. To provide system integrators with additional configuration tooling, DSKT2 provides a configuration parameter:
config Bool ALLOW_EXTERNAL_SCRATCH = true;
to enable/disable this best effort approach. The default is set to true. However, configuration scripts can override the default by setting:
DSKT2 = xdc.useModule('ti.sdo.fc.dskt2.DSKT2'); DSKT2.ALLOW_EXTERNAL_SCRATCH = false;
which results in error being returned when there isn't available internal memory.
Additionally, the algorithm's themselves can (and should!) check in their
IALG_Fxns.algInit() whether the "assigned" memory is internal or not and fail when the algorithm knows it must have internal memory. This test can be done by checking the assigned
IALG_MemAttrs via the IALG supplied macro
IALG_isOffChip(s), and returning failure when appropriate.
Unfortunately many algorithms don't perform these checks, as it is not mandated, and the conservative
DSKT2.ALLOW_EXTERNAL_SCRATCH configuration approach is an option.
Why does my alg hang in
One of most common issues seen when using ACPY3 is a "hang" in the call to
ACPY3_wait() call simply polls on the IPR bit corresponding to the last transfer (in the series of configured linked transfers). A hang here indicates that the actual transfer never went through or completed. The following are a list of common reasons for getting stuck in
- If you are running on the simulator, you might be hitting a known simulator bug, that causes any transfer with
ACNT > 16to hang. CCS version 3.3.56 has fixed the issue.
- If running on hardware, the hang most likely occurs when DMAN3's internal memory has not been configured correctly. Make sure DMAN3's configuration parameter
DMAN3.heapInternalis actually configured to point to an Internal memory heap. Below are some details on this issue:
- ACPY3 internally uses the C64x+ GEM's IDMA hardware to initiate QDMA transfers.
- It shadows the PaRam settings (in some internal memory) and then uses the IDMA to copy them (or DMA them) to the actual EDMA3 PaRam config space and triggers the actual EDMA3 transfer.
- IDMA requires the source of the IDMA transfer to always be "internal memory". In ACPY3, the IDMA destination address is EDMA3's PaRam configuration space and the source is the shadow PaRam setting (in the form of some ACPY3 internal data structures).
- Usually DMAN3 is used to provide memory requested by ACPY3. If DMAN3's configuration parameter
DMAN3.heapInternalis set incorrectly (to external memory), then the IDMA transfer will not succeed, hence the actual EDMA transfer never starts and this leads to a hang when
ACPY3_wait()is called by the application.
- Another slightly obscure reason for an
ACPY3_wait()hang is the wrong usage of the
waitId's are to be used as follows:
waitIdof -1 can be passed in the
ACPY3_Paramsto indicate that no intermediate waits will be made on this linked transfer. Use this in your
ACPY3_Paramsfor intermediate transfers that you don't intend to wait on.
0 <= waitId < (numWaits - 1), where
numWaitsis the parameters you supplied in
IDMA3_ChannelRecwhen creating the IDMA3 handle, can be passed to
ACPY3_Paramsto indicate that this intermediate transfer can be "waited" on by an
- For a single transfer configured (using
ACPY3_configure()) or for the last transfer in a series of linked transfers, internally a
(numWaits -1)is automatically used. Any supplied
waitIdwill be ignored. Do not use this
waitIdfor any intermediate transfers.
- Please refer to the DMAN3/ACPY3 User's Guide for more details.
Does ACPY3 support 3D transfers?
No, ACPY3 does not support 3D transfers, since it uses QDMA channels only.
If you want to do a 3D transfer, you can use a DMA channel, and chain it to itself (set the TCC bits of the PaRam opts to the DMA channel number). Set the synchronization type to ABSYNC, the STATIC bit to 0, and set ITCHEN to 1 in the PaRam opts.
Where's the RMAN User's Guide?
The FC API Reference Guide also includes RMAN API documentation.
How do I configure the EDMA3 resource manager with specific resources (channels, params, tccs) so that the algorithms can request them?
Use the ti.sdo.fc.edma3.Settings module to designate the EDMA3 resources to be used by the RMAN module. This article describes the available configuration settings.
One key field is the 'regionConfig' field, which can be used to designate the exact EDMA3 channels to be used. A good example of how to use this field is provided in the Framework Components example scratchEdma3 located in $(FC_INSTALL_DIR)/examples/ti/sdo/fc/rman/examples/scratchEdma3 of your FC installation.