Original articleReprint please register source HTTP://BLOG.CSDN.NET/TOSTQ directory: http://blog.csdn.net/tostq/article/details/51245979
Originally this section is to talk about the multi-core image grayscale conversion routines, but too much content, split into two sections, the content of the multi-core DSP is mainly on the basis of the single core to increase the inter-core memory sharing and inter-core communication, the previous section introduced a simple inter-core communication method using the Notify notification mechanism, In this section we will describe how to use the Sharedregion module for inter-core memory sharing. The next section will be a complex message passing method through the Messageq module. This section continues with a simple example of the Notify module in the previous section to introduce the Sharedregion module
first, the new project We have described how to create a new CCS project, which is no longer covered in detail, but the recommended way is to first import the IPC template example and then enter the modification on the template, which reduces the amount of time to configure Sys/bios. The examples in this article do the following tasks: (1) Core 0 creates shared memory, writes data to memory, and then sends the memory address to the slave kernel via notify. (2) receive the kernel 0 notification from the core (1 to 7 cores), open the memory address, and read the data. (3) completed.
second, import sharedregion module Sharedregion module is IPC from the name can be seen, it is a shared area, especially for multiprocessor environments, the Sharedregion module is used to let a memory area can be shared by different processors and operations. This module creates a shared memory area lookup table for each processor, which guarantees that each processor can see all the shared areas within the system. The region ID of the shared memory area in the lookup table is consistent across all lookup tables, and at run time, the lookup table can quickly find the shared area by sharing the zone ID and the shared zone name. (1) Adding a lookup table Adding a lookup table actually means adding a shared area to the lookup table (Entry), and after importing the Sharedregion module, a sharedregion with a zone ID of 0 has been added by default, and the shared area with ID 0 can be shared by all processors. There are two ways to add a lookup table, one is static, adding a shared area in this way is generally all the kernel shares, and the other is dynamic addition, this way can add some only partially core valid shared areas. a). Static add: Static additions are primarily done in the. cfg file, and the configuration of the Sharedregion module is completed when calling Ipc_start (). The following code is directly added in the. cfg file to import the Sharedregion module first, complete the global setting, first sharedregion.numentries to set the maximum number of shared areas in the system. If all shared memory areas have the same base address on all processors, the translate option will be set to false to mean no address translation, and if set to true, address translation is required. (The routines in this section only need to use a shared area, so these two options can actually be used without setting, which is OK by default) Add a shared area entry (Entry):
the entry parameter here has the following meanings: 1)Base: The bases address of the zone, and the base addresses of different processors can be different2)Len: The length of the zone, the same shared area should be the same length in the lookup table of all processors3)Ownerprocid: Manages the processor ID for the zone, and if there is a zone owner, the owner of the zone is the creator of the HEAPMEMMP instance, while the other cores open the instance4)IsValid: Indicates whether the zone is available on the current kernel,determines whether the current kernel can use this shared zone. 5) Cachelinesize: This value should be the same for all cores in the lookup table 6) Createheap: Indicates whether a heap is required to be created for the current zone7)Name: Names of zones The maximum number of entry in a lookup table usually uses the static setting in Shareregion.numentries. Because each processor stores information about the areas of shared memory in the Sharedregion lookup table, when you add or delete a shared zone entry in a lookup table, you must update the data in all other lookup tables, and the more entries in the lookup table, the longer the lookup table looks. b). Dynamic add (generally rare, here is a little mention of it): Dynamic add mainly through the Sharedregion_setentry () function to set the following entry parameters. This section describes a multi-core image grayscale conversion program that requires a shared area, and this shared area is valid for all cores, so there is no need for a dynamic method to set the zone for a kernel attribute.
(2) The use of shared area memory, its general method of use: heap = (iheap_handle) sharedregion_getheap (RegionID); Get a heap handle for a shared area by zone IDbuf = Memory_alloc (heap, size, align, NULL); Allocating area memory through heaps Parametric analysis:1)RegionID: is the zone ID, which is set in the. cfg file in static add, and if you do not know it, you can get the current zone ID by Sharedregion_getid () according to a specific address. Or, the zone ID is obtained by Sharedregion_getidbyname () based on the name of the zone.2)BUF: The allocated memory buffer pointer,3)Heap: A stack handle that can be used to allocate memory4)Size: Allocated Memory buffer sizes5)Align: Alignment parameters Add the appropriate header file:
The main task function is added:
(3) Address translation: In an environment with shared memory areas, one of the main problems is that these shared areas may be mapped to different address spaces on different processors, that is, the same piece of shared memory area in the different processing of the local address space logical location is different, Therefore, it is necessary to convert the address pointers between different processors at this point. Before setting the Sharedregion.translate option to true in static settings, address translation is required. When set to False, the same memory buffers on different processors have the same corresponding address, so no address translation is required. Here we set this to True (the default) in order to describe the process of address translation between shared memory. You first need to introduce two concepts: Shared area address srptr: The shared area address is the address of the current memory buffer on the shared zone sharedregion, which can be treated as a global address, and the Srptr address pointing to the same memory is the same on all processors, so we pass this address to the other cores. The shared area pointer (SRPTR) is a 32-bit pointer that consists of an ID and its offset. The most important bit of a srptr is used to indicate the ID number, and the ID number indicates the position of the current zone entry in the lookup table.
Local address addr: Shared area address srptr is not available locally, and in general, cost-of-place addresses need to be converted to be used by the local processor. Several functions for address translation:sharedregion_getptr () get local pointers based on shared area pointers
Sharedregion_getsrptr () obtains the current shared area pointer based on the given local pointer and region ID
The primary core passes the shared zone address pointer through the MESSAGEQ to the slave core, and then the corresponding address translation from the kernel to get the local address
(4) Caching cache issues When the primary kernel writes data to memory, it is most likely that the data is written to the cache and not written to memory, so at this point the kernel must not read from memory to write the data. This question is very important, it's been bothering me for two days. =_=| |, the workaround is to write the cache back. Specific steps: a). import header File #include <ti/sysbios/hal/Cache.h> b). After writing the data to the memory, write back the cache Void CACHE_WB (Ptr blockptr, Sizet bytecnt, BITS16 type, Bool wait); Blockprt refers to the memory address, bytecnt refers to the size of the writeback data, type refers to the cache types, and wait refers to whether to wait. Write back all caches can callVoid Cache_wball ();c). Let the cache expire before reading the data from memory Void cache_disable (Bits16 type); type refers to the cache types, where you can select Cache_type_all, which is the full cache
three, notify modulein the previous section we introduced the Notify module, this section is not detailed, this section of the Notify module has the following key points (1)The first thing is to ensure that there is a connection between the cores, because 8 cores are connected, so you can set them directly to(2) Although only the primary core sends the message from the issue, but both the primary and the core are registered to the event
(3) Set the registration function, the main completion of the address delivery, in addition to set a semaphore here (the semaphore is set in the 5th section has), from the core only the address to activate the semaphore, start reading memory data
(4) Primary kernel gives the ability to read data events from the issuing send
(5) The primary core has been waiting for the semaphore to activate
Iv. Analysis of the results of the routine process
with the above results, it can be seen that the kernel 1-7 perfectly reads the kernel 0 writes the shared memory data. It is important to note that in some cases, the local address of each processor may be the same even if the address translation is required, as is the case in this section, but when the data component of the shared memory region is more complex, the local address of the same region on different processors is likely to be different. So address translation is very necessary.
This section routines: Https://github.com/tostq/EasyMulticoreDSP/tree/master/7.SharedMem
(Multi-core DSP QuickStart) 7. Using Sharedregion for inter-core memory sharing