The purpose of this document is to capture common frequently asked questions (FAQs) that we at Critical Link, LLC receive regarding the development systems employing the MityDSP. The goal is to provide additional resources to other customers who may have similar questions.
Back to TopThis section is intended to answer FAQs commonly raised by MityDSP software development engineers.
Back to TopOn the C6000 architecture, interrupts cannot be taken in the delay slots of a branch. In some instances the compiler can generate code that cannot be interrupted for a potentially large number of cycles.
What this means is that it is possible for the TI compiler to generate code that can cause the CPU to not respond to an interrupt for quite some time. Note that the CPU will always detect the interrupt condition, but simply not call the related ISR until it is out of the code block in question.
In general this situation only occurs in optimized code, and only in sections of code that utilize tight for-loop conditions, such as:
for (i = 0; i < 100000; i++) { a[i] = b[i]; }
By using the -mi option (e.g., -mi2000) in the Build Options for your project, you can instruct the compiler to force gauranteed window of interrupt handling opportunity every N CPU instructions. This is necessary if you have ISRs that require low latency (say, a high speed ADC FIFO drain routine or an ethernet driver). All MityDSP libraries provided by CL employ a -mi setting of 10000 or less. By default, the compiler will assume no restrictions on interrupt latency requirements.
As of CCS version 3.1, the TI provided realtime common libraries (the rts6700.lib, containing functions like memcpy) and the downloadable DSP libraries (containing floating point FFT algorithms) are compiled with the -mi flag disabled. Therefore, a user will be required to rebuild the runtime libraries with the flag set in order to ensure low latency interrupts are achieved.
Our experience has been that many problems relating to lost tick-timer clocks, network hick-ups, ADC capture FIFO overflows, parser errors (due to bad message data), and any other long interrupt latency problems have ultimately be tied back to this issue. Further information can be found by researching the -mu and -mi options on the CCS compiler.
This is a new procedure, beginning with version 6.1 of TI's Code Generation Tools:
This is the procedure prior to version 6.1 of TI's Code Generation Tools:
If your project needs different settings for the -mi flag, you may change the argument to the "-mi" flag supplied above.
NOTE: For the MityDSP-Pro, the procedure is the same, except the library name is "rts64plus.lib". In addition, the argument to the -mv flag in the mk6x command changes from 6700 to 6400+.
For version 3.1 of Code Composer Studio, we have discovered that the rts.src supplied by the CCS install disks from TI are corrupt. TI will provide an update for this code if you request it, or if you download the latest CGTOOLS patch (from the CCS Update Advisor) the rts.src file should be correct.
Back to TopKeep in mind that the if you are using the tcDspFlash::write() method, the following operations take place:
So regardless of how small a write you are performing, if you are writing to a sector that is 16 KBytes big, you are effectively reading 16 KBytes, erasing 16 KBytes, then reprogramming 16 KBytes of data. The FLASH memory interface is slow, and such an operation may take hundreds of milliseconds to complete.
Users that wish to avoid such long intervals, or anticipate frequent FLASH update cycles should consider using the tcDspFlash::rawWrite() method. This method does not perform a forced erase on a sector, but rather simply writes the requested bytes to the locations in FLASH and returns, a fairly quick operation. However, the data in FLASH must be all 0xF's for this technique to work.
Typically, a user writing small chunks of data will erase a sector in FLASH, then write a small structure out in memory and "walk" up in the sector (writing to a different location within the same FLASH) until it hits the top of the sector, then re-erase the sector and start over. This requires a bit more management in the application but yeilds much longer FLASH life (which is specified at 100,000 cycles for the MityDSP) as well as much faster FLASH update cycles.
Another option is to use the tcDspStorageCache class to cache FLASH writes. See the documentation provided in the Core Library for details.
Back to TopOftentimes when using the TI emulator/debugger to walk line-by-line through software a user will issue a tcDspSerial::put() command, then be surprised to see that no data is displayed on the attached serial device. This is due to the underlying UART design and the way that the Spectrum Digital Emulator works with the TI CCS debugging suite.
The MityDSP UART core consists of an FPGA based UART containing a 64 byte transmit and 64 byte receive buffer. The FPGA issues two interrupts, one indicating receive data is available and one indicating that the transmit FIFO is empty. The DSP tcDspSerial class also provides transmit and receive buffers (4K and 32K bytes, respectively), and installs an interrupt handler that moves data between these buffers and the FPGA FIFOs based on the received FPGA interrupts.
When a tcDspSerial::put() command is issued, data is transferred from the user supplied buffer to the DSP transmit buffer, and if necessary the transmit FIFO empty interrupt is then enabled and the function returns. Because of the high priority of the TI emulator, quite often the TX interrupt ISR is not called prior to the next effective breakpoint inserted by the emulator while line-by-line debugging is being performed. If no data is sent to the FPGA, then no data is transmitted by the UART. Note also than only 64 bytes will be transferred before another ISR call will be required.
Back to TopBy default, the system tick timer ISR in a normal MityDSP BIOS enabled program runs at the lowest interrupt priority. The tick timer works by generating a counter based interrupt once a millisecond (by default). The BIOS inserted ISR handles the interrupt and bumps a system counter used by CLK_getltime() and the other timer driven functions (TSK_delay(), etc.). Often during debugging or runtime users have observed that the tick-timer runs "slow". This is due to the fact that the tick timer ISR is not able to run fast enough to keep up with the timer generated interrupts. Reasons for this behaviour include:
For the TI 6000 series processors, CCS interprets the long keyword as a 40 bit (5 byte) integer. This isn't necessarily a problem, and in some cases users may require the additional integer dynamic range that the processor supports. However, this subtlety can create issues if you are:
The Chip Support Library for the 645x processor found on the MityDSP is not included in the CCS3.3 standard installation. Here are the steps to obtain it, and rebuild the libraries for use with the MityDSP-Pro:
If you're using DSP/BIOS in your project, that's it. However, if you need to use the INTC module from the CSL (never use this with DSP/BIOS), there are a few more steps...
If your project needs different settings for the -mi flag, you may change the argument to the "-mi" flag supplied above. Also, don't forget to update the rts64plus.lib file i while you're at it... see 2.1 Why does it take the DSP so long to respond to an interrupt?.
Back to TopWhen TI moved from v6.0 of their Code Generation Tools to v6.1, there were some significant changes to the run-time libraries and C/C++ header files. While the changes added some new functionality, there was also at least one piece of "questionable" code introduced. In the errno.h header file the following is now present:
extern _DATA_ACCESS int errno;
#ifdef __cplusplus
#define errno ::std::errno
#else
#define errno errno
#endif
Therefore, everywhere the word "errno" appears in C++ code, the preprocessor will change it to "::std::errno". This means that if your application has a structure or class member named "errno", or even an enumeration, macro, or method named "errno", the above substitution will be made and your code will likely not compile. To fix this, either rename the item in your code, or make sure errno.h is not included in the file.
What's worse, TI actually caught themselves in this trap. Several of their DSP/BIOS header files (tsk.h, sem.h, etc.) have data structures with members named "errno". If you get compilation errors that point to these DSP/BIOS headers, the only thing you can do is to move the inclusion of the DSP/BIOS headers to a point prior to the includion of errno.h.
NOTE: Few of the MityDSP MDK header files include errno.h. One notable exception is DspNetStack.h. Therefore, DSP/BIOS includes must be made prior to DspNetStack.h as well.
Back to TopThis section is intended to answer FAQs commonly raised by MityDSP FPGA firmware (VHDL) development engineers.
Back to TopThis section is intended to answer FAQs concerning the MityDSP card and / or common hardware interfaces and cores provided by Critical Link.
Back to TopNOTE: This applies to the MityDSP and MityDSP-XM only.
Yes, in general the clock speed of the DSP may be increased. Usually the only penalty is power consumption and heat generated. A macro has been provided to support changing both the CPU clock speed and the external memory interface (EMIF) clock speed. Please note, though, that changing the EMIF speed requires that FPGA builds (which are primarily clocked using the EMIF clock) be made with appropriate timing constraints. Arbitrarily adjusting the EMIF is not recommended unless you know what you're doing. The nominal/recommended EMIF speed is 50 MHz.
The example below shows how you would configure the DSP to run at 200 MHz, with the EMIF running at 50 MHz. This is normally the option users pick if extra CPU cycles are required.
#includeint main(int argc, char* argv[]) { RECONFIG_CLOCKS(CPU_FREQ_200MHZ,EMIF_FREQ_50MHZ) ... rest of code here.... }
Note that you will also have to change the clock speed in your DSP/BIOS configuration file (*.cdb file) so that all operating system timers operate at the proper rate.
Back to TopThis section is intended to answer FAQs concerning MityDSP support software developed by Critical Link.
Back to TopThe MityDSP bootloader architecture is designed in such a way as to provide a certain level of abstraction of the FLASH memory devices from an application developer. In general, a software developer needing to interface to the FLASH to store non-volatile application data should not write code that hardcodes FLASH sector configuration (starting addresses, blocksizes, etc.) or attempts to directly interface to the FLASH part. Instead, the tcDspFlash class should be used. There are several reasons governing this guidance:
The Bootloader GUI tool provides a user with control over the allocation of the FLASH application code and data regions for a MityDSP. See the help page in the GUI tool for more information. Typically, the top sector(s) of the FLASH are reserved for application data.
Once the MityDSP application code and data space has been stored by the Bootloader, software developers can locate the application data area in FLASH, determine it's size and offset without any knowledge of the topology of the FLASH part. This allows for portable code between the various MityDSP platforms. As an example, the following code locates the application sector area for the MityDSP and performs a write call:
{ // This section of code is required, per tcDspFlash documentation #ifdef MITYDSP_PRO const unsigned int FLASH_BASE_ADDR = 0xB0000000; const unsigned int BANK_SEL_ADDR = 0xA0000004; #else const unsigned int FLASH_BASE_ADDR = 0x90000000; const unsigned int BANK_SEL_ADDR = 0xB0000004; #endif char* myAppBuff = new char[1024]; // Initialize the tcDspBankSelector object for the flash device tcDspBankSelect* mpBankSel = new tcDspBankSelect((void*)BANK_SEL_ADDR); // Use the factory to obtain a base class pointer to the flash device tcDspFlash* mpFlash = new tcDspFlash((void *)FLASH_BASE_ADDR, mpBankSel); // Read the base configuration of the MityDSP (Bootloader GUI settings) tcDspConfig *myConfig = tcDspConfig::GetInstance(myFlash); // Get the location of the application data area unsigned int AppFlashOffset = myConfig->GetAppDataOffset(); unsigned int AppFlashSize = myConfig->GetAppDataSize(); // Do checks if AppFlashSize is too small... // Write to the application data area mpFlash->write(AppFlashOffset, myAppBuff, 1024); }Back to Top
This section is intended to answer FAQs related to Network processing.
Back to TopWith heavy CPU usage, processing of network packets can be delayed. It was found that LWIP's internal mailbox length was set to 50. Once the mailbox is full, messages are simply dropped, and the buffer will not be released. This was seen on PBUFs, but may effect other buffer types.
You can verify that the mailbox is dropping items by checking the MboxPostDrops field of the SysArchStats structure. This should always remain at zero.
Back to TopWhile the previous tuning parameters were convenient, they were creating a significant code maintenance issue in the MDK. The lwIP stack used in the MDK is an independent, open source project. The changes to allow run-time adjustment of internal stack parameters were essentially custom changes applied by Critical Link to the lwIP baseline. Every time the lwIP project changed a file, these custom changes would have to be re-examined and possibly re-applied.
So rather than "fight city hall", starting with MDK 2.1, lwIP was broken out into a separate library, which consists of the open source lwIP project, and the few architecture files that are needed to define certain functionality specific to the MityDSP. All internal parameters are set at compile time, via the lwipopts.h file.
In most instances, the library provided with the MDK can be used as-is. Should your project have specific requirements not addressed by the default configuration, the complete source code for lwIP (and the project file to build it) is now provided with all MDK distributions. To tune lwIP for your application (if needed), simply open the lwip.prj file in Code Composer, change lwipopts.h as required for your project, and rebuild the libraries (debug and release versions).
Back to TopAs discussed in the previous question, starting with MDK 2.1, the MityDSP network libraries were reorganized. The lwIP code now sits in its own library, and the network drivers, interface layer, and various network utilities not part of lwIP are now in the Net library. The previous Clients, Telnetd, Httpd, and WINS libraries are all now part of the Net library.
This requires some changes to the include paths used in your project, the libraries linked, and a slight modification to the stack initialization code. This is all described in the documentation for the Net and lwIP libraries provided in the MDK.
Other than these path name changes, there are no changes to the API's, so no changes to the logic in your application should be required, with one minor exception. The lwIP project now includes a DHCP client, so the DSPNetDHCP and DSPNetDHCPIsBound functions no longer exist. Simply use dhcp_start() and netif_is_up() from the lwIP library in their place.
Back to TopFAQ 6.3 discussed the changes to the various MityDSP Network libraries starting with MDK 2.1. Here is a quick summary of the code changes required to update legacy code. Please refer to the full documentation for complete details.
This section is intended to answer FAQs that cannot be categorized in sections 1.0 through 5.0.
Back to TopNew MityDSP MDK's are released periodically to add features or correct problems found in previous releases. Each MDK strives to be 100% backward compatible with previous releases at an API level. However, underlying implementation details, and the internal interfaces between software and firmware objects is subject to change from release to release. This means that firmware files produced with one revision of the MDK may not be mixed and matched with software built against another release in all cases.
Therefore, all application-specific firmware and software must be built against the same MDK. Since Critical Link supplies the application firmware for many customers, even those who develop their own software, coordination of new application firmware and software builds is required between Critical Link and the customer. An update in turn requires a regression test of the application firmware on a customer's specific I/O board.
Unless your application requires new functionality, or is experiencing problems with an existing MDK, no upgrade is necessary or recommended. If you think you require an upgrade, please contact Critical Link and we'll verify whether or not the latest MDK will address your issue and assist with the upgrade process.
Back to Top