NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

DSP/BIOS on Multi-Core singleimage

From Texas Instruments Wiki
Jump to: navigation, search

Single Application on Multiple Cores

The singleImage example shows how a single application can run on all the device cores. The cores run the same application independently of each other.

Figure 1. Single Application on Each Core of C6472 Device
Figure 1. Single Application on Each Core of C6472 Device

Singleimage Example Application

The example for this scenario is in the singleimage project folder. The example uses a QUE (queue) and SEM (DSP/BIOS semaphore) to send messages and synchronize between multiple writer() tasks to a single reader() task. The reader task, the three writer tasks, and the semaphore are statically created in the DSP/BIOS configuration file.

Each of three identical writer tasks will load and send a message through the DSP/BIOS QUE mechanism, then will post a SEM to tell the reader task that a message is ready. The reader task will respond to the SEM by pulling a message off the QUE object and reporting the results using a LOG_printf message.

You will be able to observe the results of the execution by each core by using the RTA->Printf Logs window.

The application should be built using DSP/BIOS 5.41.07 or greater and CCS4.2.0.09 or greater. Earlier releases will not support the Printf Logs as well or at all.

The DSP/BIOS memory configuration for the C6472 for this application allows the single application image to be loaded and executed on all cores by placing all program and data in the local L2 SRAM.

Code and Data Placement

This example is based on a C6472 device (6 independent cores w/ both local and shared memory). See Figure 1 for details.

One way to build and run a single application is to place all program and data in local L2 (LL2RAM) so that each core is completely independent of the other cores and each core accesses its own complete copy of the application image.

Since there are portions of the application that are common between all the core, such as the user-developed program code and the DSP/BIOS program code, this LL2RAM-only scenario may seem inefficient because it duplicates these portions that could be shared. The [[#Problems with Alternative Methods for a Single Image|Problems with Alternative Methods for a Single Image] section below examines other methods and some of the problems with those alternative methods. The third scenario of this app note, sharedImage, discusses ways to share portions of the DSP/BIOS library.

The singleImage application uses the exact same program image for all six cores of the C6472, so none of the cores will physically share any of their program and data memory with the other cores. This technique allows you to load and run the exact same application on all cores while running each core completely independent from the other cores.

The singleImage method is very easy to implement. All program and data will be mapped to LL2RAM. This works because the address for Local L2 is 0x00800000 for each of the cores. When Core0 accesses the address 0x00800000 it accesses the Core0 L2 memory which is mirrored at 0x10800000; when Core1 accesses the address 0x00800000 it accesses the Core1 L2 memory which is mirrored at 0x11800000 and is a physically different memory than Core0's L2 memory. The default DSP/BIOS configuration platform file for the C6472 is setup with all of the initialized sections (program code and constant data) in the Shared L2 space and all of the uninitialized and unique (data and interrupt vectors) sections in the Local L2 space. So some of the sections need to be relocated to LL2RAM.

Code Placement

Since all cores on the C6472 have access to a private Local L2 memory region (Local L2 or LL2RAM) that can be addressed by the same Local L2 address starting at 0x00800000, all code can be placed in LL2 from a single application image. In a DSP/BIOS-based application, the .text and .bios sections contain most of the code needed for the application.

The following program and read-only memory sections will be defined in the tcf file to be placed in the Local LL2RAM memory:

  • BIOS Data: .gblinit
  • BIOS Code: .bios, .sysinit, .hwi, .rtdx_text
  • Compiler Sections: .text, .switch, .cinit, .pinit, .const/.printf, .data

Data Placement

Since all cores on the C6472 have access to a private Local L2 memory region (Local L2 or LL2RAM) that can be addressed by the same Local L2 address starting at 0x00800000, all data can also be placed in LL2 from a single application image.

The following memory sections will be defined in the tcf file to be placed in the local LL2RAM memory:

  • Segment For DSP/BIOS Objects
  • Segment For malloc() / free()
  • BIOS Data: .args, .stack, .trcdata, .sysdata, DSP/BIOS Conf Sections
  • BIOS Code: .hwi_vec
  • Compiler Sections: .bss, .far, .cio

Configuration File Updates for Code and Data Placement

The following lines were added at the end of the singleimage.tcf file to place all of the code and data sections into LL2RAM:

/* allocate memory segments */
bios.MEM.BIOSOBJSEG = prog.get("LL2RAM");
bios.MEM.MALLOCSEG = prog.get("LL2RAM");
bios.MEM.ARGSSEG     = prog.get("LL2RAM");  /* BIOS Uninit .args          def: LL2 */
bios.MEM.STACKSEG    = prog.get("LL2RAM");  /* BIOS Uninit .stack         def: LL2 */
bios.MEM.TRCDATASEG  = prog.get("LL2RAM");  /* BIOS Uninit .trcdata       def: LL2 */
bios.MEM.SYSDATASEG  = prog.get("LL2RAM");  /* BIOS Uninit .sysdata       def: LL2 */
bios.MEM.OBJSEG      = prog.get("LL2RAM");  /* BIOS Uninit .*obj?         def: LL2 */
bios.MEM.HWIVECSEG   = prog.get("LL2RAM");  /* BIOS Init'd .hwi_vec       def: LL2 */
bios.MEM.GBLINITSEG  = prog.get("LL2RAM");  /* BIOS Init'd .gblinit       def: SL2 */
bios.MEM.BIOSSEG     = prog.get("LL2RAM");  /* BIOS Init'd .bios          def: SL2 */
bios.MEM.SYSINITSEG  = prog.get("LL2RAM");  /* BIOS Init'd .sysinit       def: SL2 */
bios.MEM.HWISEG      = prog.get("LL2RAM");  /* BIOS Init'd .hwi           def: SL2 */
bios.MEM.RTDXTEXTSEG = prog.get("LL2RAM");  /* BIOS Init'd .rtdx_text     def: SL2 */
bios.MEM.BSSSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .bss           def: LL2 */
bios.MEM.FARSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .far           def: LL2 */
bios.MEM.CIOSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .cio           def: LL2 */
bios.MEM.TEXTSEG     = prog.get("LL2RAM");  /* Cmpl Init'd .text          def: SL2 */
bios.MEM.SWITCHSEG   = prog.get("LL2RAM");  /* Cmpl Init'd .switch        def: SL2 */
bios.MEM.CINITSEG    = prog.get("LL2RAM");  /* Cmpl Init'd .cinit         def: SL2 */
bios.MEM.PINITSEG    = prog.get("LL2RAM");  /* Cmpl Init'd .pinit         def: SL2 */
bios.MEM.CONSTSEG    = prog.get("LL2RAM");  /* Cmpl Init'd .const/.printf def: SL2 */
bios.MEM.DATASEG     = prog.get("LL2RAM");  /* Cmpl Init'd .data          def: LL2 */

Installing the Application

Download the Randyp_singleimage.zip file from here to a temporary location on your computer. Use the CCSv4 File->Import command to import the singleimage project into your workspace using these steps:

  1. From the CCSv4 main menu, select the File->Import command
  2. Select as source type CCS:Existing CCS/CCE Eclipse Projects
  3. Select an archive file
  4. Browse to the Randyp_singleimage.zip file or enter the path to it
  5. Select the singleimage project
  6. Click Finish

Since this example was built and archived from a workspace using CCSv4.2.4.00033, DSP/BIOS 5.41.10.36, Code Generation Tools 7.0.5, and the on-board XDS100USB emulator, there may be some "housekeeping" needed to make your build and debug experience run smoothly. Please follow these steps for each project to make sure the right tools are selected:

  1. In the C/C++ Projects window, right-click on the project folder name and select Build Properties..., select CCS Build in the left pane then the General tab
  2. Click the drop-down arrow for Code Generation tools and select the latest version of CGT 7.0.x that you have. Earlier versions like 6.0.x may work but have not been tested (please comment here if you test them). If your latest version is not yet in the list, click More then Select tool from file-system and browse to the folder, such as C:\Program Files\Texas Instruments\C6000 Code Generation Tools 6.1.17, then click OK and OK.
  3. Click the drop-down arrow for DSP/BIOS version and select the latest version of BIOS 5.xx that you have. Earlier versions like 5.33 may work but have not been tested, and they will not display the RTA Printf Logs correctly. SYS/BIOS 6.x is not supported for this application note. If your latest version is not in the list, click More then Select tool from file-system and browse to the folder, such as C:\Program Files\Texas Instruments\bios_5_41_10_36, then click OK and OK.
  4. Click OK to save these changes and select Apply changes to existing build configuration in the Save Build Configuration Settings window if it comes up.
  5. Repeat the steps above for the Release configuration when you want to build your final application with optimization. Use the Debug configuration for evaluation and functional debug.

Building the Applications

Follow the steps below to get a successful build of the project.

  1. Select the singleimage project, right-click and Set as Active Project.
  2. On the main icon row click the Build Active Project icon.

Randyp BIOS Multicore si build.png

Loading and Running the Application

Each core has the same memory range; therefore you can use Code Composer Studio (CCS) to individually load the same application on each core. You can also take advantage of the CCSv4 Debugger's Synchronous Mode to load and run the same application on all cores at one time.

To run the application, you may either start each core individually or use the Synchronous Mode to start all cores in parallel.

After a successful build has been completed, follow these steps in the Debug View to load and run the singleimage application:

Randyp BIOS Multicore si Debug.png

  1. Launch TI Debugger to load the Target Configuration
  2. On the Debug window icon row, click Enable Synchronous Mode
  3. On the main icon row, click Connect Target to connect to all the cores
  4. On the main icon row, click Load Program and find the singleimage.out to load to all the cores
  5. On the CCS menu bar, go to Tools->RTA->Printf Logs
  6. (This step may not be required with all releases) On the Debug icon row click Collapse All (for ease), then select each core one-at-a-time and make sure in the Printf Logs window that the "Stream RTA data" icon is selected and highlighted.
  7. On the Debug window icon row, click Run, wait 5 seconds and click Halt.
  8. Observe the Printf Logs window for each of the cores. Use Collapse All if it makes it easier to go through the list of cores. When Core5 is selected in the Debug window, the display will be as shown here. Note the Core N number on some lines.

Printf Logs for Core5

Some points to know:

  • Once you have loaded all the cores, when you later make changes and do a Rebuild, CCSv4 will let you select the option to Reload the program automatically when it detects that a loaded .out file has changed. Checking Remember my decision will save having to answer this every time.
  • After the load or reload, the processor will automatically run to main() and halt. If it is stuck running, click Halt and then Restart (or Reload Program, or CPU Reset and then Reload Program).

Problems with Alternative Methods for a Single Image

Other methods could be considered for building and running the same program on all six cores. We will briefly discuss some of these and the issues that you would have with those alternatives.

Shared L2 (SL2RAM)

One attractive alternative would be to place all code and data in the Shared L2 (SL2RAM). The same thing could be done with any shared memory location, including external DDR memory or using a single core's global L2 address space such as DSP3 L2 SRAM at 0x13800000. Using any of these locations would allow each core to run from the exact same memory. This would save duplication by using only one image loaded into one location, instead of six different copies of the same image, one for each core.

The following lines could be added to the end of the singleimage.tcf file to place all memory sections in SL2RAM:

/* allocate memory segments */
bios.MEM.BIOSOBJSEG = prog.get("SL2RAM");
bios.MEM.MALLOCSEG = prog.get("SL2RAM");
bios.MEM.ARGSSEG     = prog.get("SL2RAM");  /* BIOS Uninit .args          def: LL2 */
bios.MEM.STACKSEG    = prog.get("SL2RAM");  /* BIOS Uninit .stack         def: LL2 */
bios.MEM.TRCDATASEG  = prog.get("SL2RAM");  /* BIOS Uninit .trcdata       def: LL2 */
bios.MEM.SYSDATASEG  = prog.get("SL2RAM");  /* BIOS Uninit .sysdata       def: LL2 */
bios.MEM.OBJSEG      = prog.get("SL2RAM");  /* BIOS Uninit .*obj?         def: LL2 */
bios.MEM.HWIVECSEG   = prog.get("SL2RAM");  /* BIOS Init'd .hwi_vec       def: LL2 */
bios.MEM.GBLINITSEG  = prog.get("SL2RAM");  /* BIOS Init'd .gblinit       def: SL2 */
bios.MEM.BIOSSEG     = prog.get("SL2RAM");  /* BIOS Init'd .bios          def: SL2 */
bios.MEM.SYSINITSEG  = prog.get("SL2RAM");  /* BIOS Init'd .sysinit       def: SL2 */
bios.MEM.HWISEG      = prog.get("SL2RAM");  /* BIOS Init'd .hwi           def: SL2 */
bios.MEM.RTDXTEXTSEG = prog.get("SL2RAM");  /* BIOS Init'd .rtdx_text     def: SL2 */
bios.MEM.BSSSEG      = prog.get("SL2RAM");  /* Cmpl Uninit .bss           def: LL2 */
bios.MEM.FARSEG      = prog.get("SL2RAM");  /* Cmpl Uninit .far           def: LL2 */
bios.MEM.CIOSEG      = prog.get("SL2RAM");  /* Cmpl Uninit .cio           def: LL2 */
bios.MEM.TEXTSEG     = prog.get("SL2RAM");  /* Cmpl Init'd .text          def: SL2 */
bios.MEM.SWITCHSEG   = prog.get("SL2RAM");  /* Cmpl Init'd .switch        def: SL2 */
bios.MEM.CINITSEG    = prog.get("SL2RAM");  /* Cmpl Init'd .cinit         def: SL2 */
bios.MEM.PINITSEG    = prog.get("SL2RAM");  /* Cmpl Init'd .pinit         def: SL2 */
bios.MEM.CONSTSEG    = prog.get("SL2RAM");  /* Cmpl Init'd .const/.printf def: SL2 */
bios.MEM.DATASEG     = prog.get("SL2RAM");  /* Cmpl Init'd .data          def: LL2 */

Unfortunately, there are several problems with all cores running from a single image loaded into one location.

Read/write data corruption between the cores

The first problem is that read/write data will be corrupted by the other cores. Any global variable that Core0 writes to, for example to save its core number or ID, would be the same memory location that Core1 would write its core number or ID to. Whichever core writes first will lose that data when the other core writes to the same location.

Move read/write data to LL2RAM

A solution to the read/write data corruption problem is to move all read/write data to the Local L2 memory space for each core using the Local L2 (LL2RAM) address starting at 0x00800000. Since every core would use the same LL2 address to access its own unique LL2 location, there would be no corruption of Core0's data at Core0's 0x00800000 address when Core1 writes to Core1's data at Core1's 0x00800000 address.

The read/write sections that would need to be relocated are

  • Segment For DSP/BIOS Objects
  • Segment For malloc() / free()
  • BIOS Data: .args, .stack, .trcdata, .sysdata, DSP/BIOS Conf Sections
  • BIOS Code: .hwi_vec
  • Compiler Sections: .bss, .far, .cio

The following lines could be updated or added to the end of the singleimage.tcf file to place these memory sections in LL2RAM:

bios.MEM.BIOSOBJSEG = prog.get("LL2RAM");
bios.MEM.MALLOCSEG = prog.get("LL2RAM");
bios.MEM.ARGSSEG     = prog.get("LL2RAM");  /* BIOS Uninit .args          def: LL2 */
bios.MEM.STACKSEG    = prog.get("LL2RAM");  /* BIOS Uninit .stack         def: LL2 */
bios.MEM.TRCDATASEG  = prog.get("LL2RAM");  /* BIOS Uninit .trcdata       def: LL2 */
bios.MEM.SYSDATASEG  = prog.get("LL2RAM");  /* BIOS Uninit .sysdata       def: LL2 */
bios.MEM.OBJSEG      = prog.get("LL2RAM");  /* BIOS Uninit .*obj?         def: LL2 */
bios.MEM.HWIVECSEG   = prog.get("LL2RAM");  /* BIOS Init'd .hwi_vec       def: LL2 */
bios.MEM.BSSSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .bss           def: LL2 */
bios.MEM.FARSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .far           def: LL2 */
bios.MEM.CIOSEG      = prog.get("LL2RAM");  /* Cmpl Uninit .cio           def: LL2 */

The .hwi_vec section is not a data section, but it has to be moved to a unique area. This is recommended in the original app note, although I cannot offer an explanation here. It may have something to do with details in BIOS and how BIOS handles this section.

The changes described above will avoid the problems with inter-core data corruption by making the read/write data sections unique for each core. Putting these sections into Local L2 space in one way to make these sections unique, and it allows the same application image to be loaded for each core and still run successfully for each core.

With this change moving read/write data to LL2RAM, the program can run successfully with the unique data locations and the shared program locations. If all you want to do is run your application and never worry about debugging, this will be fine. But that is usually impractical.

Unfortunately, there are still problems with all cores running from a single code image loaded into one location, even with the read/write data moved into Local L2.

Breakpoint corruption between the cores

The next problem has to do with program breakpoints being set in a common program memory location. If you use the Debug Window's Synchronous Mode and load this single image into all six cores at once, each core will normally automatically run to the beginning of the main() function for convenience. This is the default setting and usually saves a step in the debug process.

Once Core0 has finished loading from singleimage.out, the CCS debugger will save the instruction at _main, set a breakpoint instruction at _main and then start the processor running. When Core0 stops at that breakpoint, CCS will replace the breakpoint instruction with the original instruction at that location. Everything looks fine in the source window and in the Disassembly window.

Core1 will also load from singleimage.out, writing to the exact same memory locations as Core0 used for the .text section, which is still in SL2RAM. CCS will then write a breakpoint instruction at the same _main address as Core0 did, after saving the contents to be restored later.

One race condition occurs between CCS writing a breakpoint instruction at _main for Core0 (after Core0 loads and before Core0 runs) and CCS writing the original instruction at _main for Core1 (during Core1's load process). If the Core1 write happens between the Core0 breakpoint write but before Core0 reaches that breakpoint, then Core0 might continue running and might never reach a breakpoint.

Another race condition occurs between CCS writing a breakpoint instruction at _main for Core0 (after Core0 loads and before Core0 stops at that breakpoint) and CCS writing a breakpoint instruction at _main for Core1 (after Core1 loads and before Core1 runs). If the Core1 breakpoint is set while Core0 is running to that breakpoint, then CCS for Core1 may have read the Core0 breakpoint instead of the original _main instruction. If this happens, then when Core1 runs and reaches the breakpoint it will restore the Core0 breakpoint instead of the correct instruction. In this case, Core1 might never see the correct instruction that should be at _main and might never execute the correct code.

The use of program cache makes these situations more difficult to debug and discover because the same memory location for _main may appear to be a different instruction when viewed through the cache of the different cores.

Disable Auto Run Option to main()

One solution to the breakpoint corruption problem at _main is to disable the Auto Run Option in the Generic Debugger Options menu. The steps to do this are:

  1. Tools->Debugger Options->Generic Debugger Options
  2. Select Core0/C64XP_A, under Auto Run Option uncheck "On a program load or restart", click OK
  3. Repeat 2 for all cores
  • Note: Remember My Settings would have to be clicked for each core, if desired.

This will avoid the first breakpoint corruption problem, and this will work as long as all you want to do is load and run the application without ever setting any breakpoints. Since one of the primary values of Code Composer Studio is the capability to do source-level debugging of your program, this is not a very effective solution. Also, there are other breakpoints that may be set automatically, for C I/O and program exit, for example. Any of these can cause a problem.

Load the program image one-at-a-time

Another solution would be to load all six cores' programs one-at-a-time instead of using the Synchronous Mode to load them all at once. This way, each core will have time to load and run to main() before the next core starts to do the same.

This solves the breakpoint corruption problem at _main. But the problem still remains that you cannot set any other breakpoints in the program while any other core is running. That would make multi-core debug difficult.

Only use Hardware Breakpoints

Another solution would be to turn off all of the automatic breakpoints and only use hardware breakpoints. Since these are handled individually by each core, they are unique between the cores.

But this would be inconvenient, both by requiring a few more steps to set hardware breakpoints and by the limited number of hardware breakpoints available.

Move .text application code to LL2RAM

A more debugger-friendly solution to the breakpoint corruption problem is to move the .text section to the Local L2 memory space for each core. This would allow software breakpoints to be set anywhere within the application code, which is where almost all of the code debug would occur.

The following line could be updated or added to the end of the singleimage.tcf file to place the .text memory section in LL2RAM:

bios.MEM.TEXTSEG     = prog.get("LL2RAM");  /* Cmpl Init'd .text          def: SL2 */

Unfortunately, this defeats most of the purpose of putting the image in shared memory in the first place, which was to save space in memory.

Creating the singleimage Project from an Empty DSP/BIOS v5 Project

To create a new project like singleimage from the beginning, follow these steps:

  1. File->New->CCS Project
  2. Project name: singleimage (or any name that does not yet exist), click Next
  3. Project Type: C6000, click Next
  4. Additional Project Settings, click Next
  5. Project Settings: Output type: Executable, Device Variant: Generic C64x+ Device, click Next
  6. Project Templates: DSP/BIOS v5.xx Examples, Empty Example, click Finish
  7. Copy singleimage.c and GetDnum.asm into the new Project folder, and they are automatically included in builds

To create a new singleimage.tcf file from the beginning, follow these steps:

  1. Right-click on the Project name and select New->DSP/BIOS v5.x Configuration File
  2. The default name will be Project.tcf, click Next
  3. Choose a platform from the list (for C6472, type 647 in the Filter Platforms box to shorten the list), select the evm6472 line, click Next
  4. Keep the default features until you know which ones you do not need, since you may not need to remove any, click Finish
  5. Wait a short time, and if the Configuration Tool does not open, double-click on the new .tcf file in your project file list.
  6. Enable heap: click the + by System, the + by MEM, right-click Properties on MEM, uncheck "No Dynamic Memory Heaps", click OK on the Config message box if it pops up, click OK on MEM
  7. Create heap: right-click Properties on LL2RAM, check "create a heap in this memory", set size to 0x800, check "enter a user...label", set the heap label to _HEAP, click OK
  8. Assign heap: right-click Properties on MEM, change both Segment dropboxes to LL2RAM, increase Stack Size to 0x1000, click Apply
  9. Memory section change: still in MEM, go to Compiler Sections tab, change "Data Section (.data)" to SL2RAM, click OK
  10. LOG: click the + by Instrumentation, the + by LOG, right-click Properties on LOG_system, change buflen to 512, click OK
  11. LOG: right-click on LOG to select Insert LOG, change name to "trace", click OK
  12. LOG: right-click Properties on "trace", change buflen to 256, click OK
  13. SEM: click the + by Synchronization, right-click on SEM to select Insert SEM, change name to "sem", click OK
  14. TSK: click the + by Scheduling, the + by TSK, right-click on TSK to select Insert TSK, change name to "reader0", click OK
  15. TSK: right-click Properties on "reader0", change Priority to 2, go to Function tab, change Task function to _reader, click OK
  16. TSK: right-click on TSK to select Insert TSK, change name to writer0, click OK
  17. TSK: right-click Properties on writer0, go to Function tab, change Task function to _writer, click OK
  18. TSK: right-click on TSK to select Insert TSK, change name to writer1, click OK
  19. TSK: right-click Properties on writer1, go to Function tab, change Task function to _writer, change Task function argument 0 to 1, click OK
  20. TSK: right-click on TSK to select Insert TSK, change name to writer2, click OK
  21. TSK: right-click Properties on writer2, go to Function tab, change Task function to _writer, change Task function argument 0 to 2, click OK
  22. IDL: right-click on IDL to select Insert IDL, change name to IDL_cnt, click OK
  23. IDL: right-click Properties on IDL_cnt, change function to _IDL_testfunc, click OK

Summary

The easiest way to build and run an application on a C6472 multicore device is to take advantage of the local addressing for the LL2 RAM. The same address range can be used for every core, because each core's C64x+ MegaModule can access its local L2 memory using the address 0x00800000. One program can be written, compiled and linked to load and run from this local LL2 address range, loading six copies into the LL2 address range of all six cores. The same application image, singleimage.out, can be loaded onto each core and run independently on each core.

The CCSv4 debugger supports multicore loading and debugging in a variety of ways. This application note has shown the steps to build, load, and run the same singleimage project on all of the cores.

There are many other scenarios that can be used for multi-core devices. The DSP/BIOS on Multi-Core multipleimage scenario uses multiple independent program images by allocating separate partitions of the shared memory regions for each core, and using those to keep the multiple programs independent from each other. The DSP/BIOS on Multi-Core sharedimage scenario builds on the multipleimage partitioning by showing a way to build a partial image from the DSP/BIOS library such that all of the cores can link to and run with a single shared image of that part of DSP/BIOS from a common region of shared memory.

Return to Using DSP/BIOS on Multi-Core DSP Devices.