|
|
View previous topic :: View next topic |
Author |
Message |
pault
Joined: 22 Jan 2009 Posts: 2
|
PCD: const or ROM - Do these really work? |
Posted: Thu Jan 22, 2009 5:44 pm |
|
|
I am using a DSPIC30F6010A, compiler V4.085, CCSLOAD, MACHX Firmware 00.49/HW Rev 5, CCSLoad V?.?? (latest off website)
In the code way below, I can't get const or ROM to work properly. Failures are as follows:
Declaration #1 : char copyfrom[6]="stuff";
- Works as expected.
- My understanding of this is that the compiler generates code and puts "stuff" into RAM with copyfrom being a pointer to it. Using the copyfrom pointer, the contents "stuff" can be changed.
Declaration #2 : char const copyfrom[6]="stuff";
- Compiles fine but does not work.
- It looks like the compiler puts "stuff" together with a bunch of code to access it into low program memory. "stuff" is read-only as it is in program flash.
Declaration #3 : char rom copyfrom[6]="stuff";
- Compiles fine
- Program memory verification fails at address where copyfrom is stored
- It looks like the compiler puts "stuff" at the high end of the program memory space. Copyfrom is a pointer to it. "stuff" is read only as it is not in RAM but in the program flash. This declaration uses less space as it requires no special code to initialize or access "stuff".
- It looks like the compiler is messing up and trying to put "stuff" in memory that does not exist 017FFC-018001. The verification complains about addresses 00018002,00018003,00018004 being FF,FF,FF and not an expected 66,00,00.
Anyone have any idea of what I am missing? Seems to me that all three of these declarations should work.
Code: |
#include <30F6010A.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS2_PLL16
#FUSES PR_PLL //Primary Oscillator with PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES WPSB16 //Watch Dog Timer PreScalar B 1:16
#FUSES WPSA512 //Watch Dog Timer PreScalar A 1:512
#FUSES PUT64 //Power On Reset Timer value 64ms
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES LPOL_HIGH //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
#FUSES HPOL_HIGH //High-Side Transistors Polarity is Active-High (PWM 1,3,5 and 7)
#FUSES NOPWMPIN //PWM outputs drive active state upon Reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOCOE //Device will reset into operational mode
#FUSES ICS0 //ICD communication channel 0
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=80000000)
void main()
{
// ***UNCOMMENT ONE OF THE FOLLOWING THREE LINES
char copyfrom[6]="stuff";
// char const copyfrom[6]="stuff";
// char rom copyfrom[6]="stuff";
char copyhere[6]=" ";
int8 temp;
for(temp=6;temp--;)
copyhere[temp]=copyfrom[temp];
for(;;);
} |
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jan 23, 2009 6:15 pm |
|
|
It may be the case, that some syntax variants mentioned somewhere in a compiler manual are not working. The standard syntax for ROM constants however works, with PCD as well as with other compilers:
Code: | const char myromstring[] = "This is a string"; |
To be usable with any string function, the string must be copied to RAM. I prefer strcpy() for this purpose, cause it automatically determines the copy length, but copying single characters in a loop also works. Basically, CCS C supports only such operations with ROM strings, that can be translated to fetching single characters. Pointers are not supported by the default const=ROM mode. |
|
|
Guest
|
|
Posted: Mon Jan 26, 2009 2:16 pm |
|
|
Thanks FVM for taking a look
I actually have no need to use the standard string functions with the strings. The purpose is to find a more efficient way of storing strings which are never changed in a way that minimizes memory footprint. The new ROM methods (not the old default ROMI) look ideal but simply do not seem to work. The const char declarations are extremely memory hungry due to the extra code the compiler uses to deal with the way they are stored in program memory. Short strings require way more code in program memory to access them than the string itself requires to be stored. In this case 6+ words to access a 3 word string.
The declaration
Code: | const char myromstring[]="This is a string"; |
is the same as
Code: | char const myromstring[]="This is a string"; |
which is the same as
Code: | char const myromstring[17]="This is a string"; |
just a bit easier as you don't have to count characters.
After a bit more experimenting, I did find that my declaration #2 did not work not because of the const declaration but due to the declaration of temp as an int8 instead of int16. (Another CCS compiler wonder?) Now the const method works but, as described above, its implementation is hugely memory inefficient.
Code: | char const copyfrom[6]="stuff";
char copyhere[6]=" ";
int16 temp; // INT16 WORKS, INT8 DOES NOT!!!
for(temp=0;temp<6;temp++)
copyhere[temp]=copyfrom[temp]; |
I am really hoping to get the new ROM method (declaration #3) working but, at this point, it looks like there is no hope because of what appears to be more compiler problems.
Code: | char rom copyfrom[6]="stuff";
char copyhere[6]=" ";
int16 temp;
for(temp=0;temp<6;temp++)
copyhere[temp]=copyfrom[temp]; |
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Jan 26, 2009 3:54 pm |
|
|
To my opinion some of your statements are missing the point.
Quote: | its implementation is hugely memory inefficient | The necessity of using TBLRD statements to access data in program memory is set by the PIC architecture. They have to be implemented in one or another way and are basically consuming some program memory.
When I see your example, that copies single characters in a loop, these complaints don't sound very serious in my ears.
As another point, your are not always free to choose a const mode as you like. If you import e.g. USB drivers, that are already requiring a particular mode (usual default const=ROM mode), you can't use a different mode without rewriting the driver. |
|
|
pault
Joined: 22 Jan 2009 Posts: 2
|
|
Posted: Mon Jan 26, 2009 6:12 pm |
|
|
FvM
My understanding of the dsPIC30/33 architecture is that there are now ways to access data in program memory without the wastefullness of such things as the TBLRD methods. That is why CCS has implemented the new ROM methods. The ROMI methods should not be required by the dsPIC30 chips.
I don't believe (someone correct me if I am wrong) that your statement
Quote: | The necessity of using TBLRD statements to access data in program memory is set by the PIC architecture. |
is correct when working with the dsPIC30 and thoeretically with version 4+ of the CCS compiler. (See compiler Readme.txt and DSPIC30F6010A manuals.)
If the new ROM methods actually work, the old ROMI methods are "hugely memory inefficient" in comparison. When working with the dsPIC30, I stand by that statement.
As for the program that copies single characters in a loop, you are right, who cares? However, this example is only shown to demonstrate the problem. If this simple bit of code would work, what I really needed to do would work. I could post the real program, but the custom motion profiler, PID tuning loops, motor control routines, LCD output routines, operator input routines, menu routines, encoder routines, bootstrap loader routines, CANbus routines... (that are starting to fill the chips memory) would probably confuse the issue. The reason I need to conserve space wherever possible is because it may be required for other functions. One area where I could possibly conserve space is in the large amounts of character strings for the operator interface that could be read-only with pointer only access (as the ROM method is supposed to do).
I still ask the last half of my original topic question... Do the new ROM methods actually work for anyone? (Particularily with the DSPIC30). If so, can anyone tell me what I am missing?
I am not looking for a fight here, it would be better for me if I am wrong, totally incompetent, and missing something with the usage of the ROM method that someone could point out. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Jan 27, 2009 1:08 am |
|
|
To answer your question directly, I wasn't yet able to use the new const access method with PCD. I guessed, it belongs to the categorie not yet implemented features of the compiler, although I may be wrong in this point.
General PIC program memory access is through TBLRD instructions, also with PIC24/30, and this is surely the case with CCS new access method. The chip has an option, to map part of the flash to data memory, but I don't see, that it's supported by PCD. I also doubt, if it's suited as a general solution for supplying const data, because the compiler would need to distinguish different const data storage classes (or access methods) internally. Some compilers go this way, e.g. for Renessas M16/M32, but their concept is very different from CCS.
Previously, I struggled with more elementary PCD issues than evaluating another constant data access method, so I put it aside. But I most likely come back to it. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|