|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Tue Mar 22, 2016 8:30 am |
|
|
Use the code buttons....
Use the first version. Two alternatives:
1) Add #device PASS_STRINGS=IN_RAM near the start of the code, so that the compiler will automatically copy ROM strings over into the RAM address space for use.
2) Use strcpy, to move the ROM data into a RAM buffer, and return the pointer to this. |
|
|
mparzgnat
Joined: 22 Mar 2016 Posts: 2
|
|
Posted: Tue Mar 22, 2016 12:09 pm |
|
|
I am digesting your answer, but it would be nice to know a little more on the background. Could you answer the questions based on your answers:
1) Any guesses on the overhead need to support the #device PASS_STRINGS=IN_RAM both in code size and slower performance?
2) By strcpy to a RAM buffer, I am assuming creating RAM by either of the following methods:
* Create a static or global character array.
* Passing character array from calling function.
I understand there are issues with dealing with separate Program and Data spaces. Is there any good documentation on how the CCS compiler, which affects how the programmer implements their code, handling the spaces? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Tue Mar 22, 2016 12:47 pm |
|
|
Try searching the forum. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Mar 22, 2016 2:05 pm |
|
|
I'm with easyflyer 10000000%
I swear by the stability and reliability of open-log modules.
I've designed a simple socket method for logging test data using that item, on some of the medical devices i've designed. It has been invaluable during field testing and with a 4GB card - a vast amount of data can be streamed and saved.
The OP seems to be happy to ignore the time domain and code over head implications of adding an SD card capture system to his PIC design on top of his other code.
The open-log requires NO code support and has proven totally reliable in my use of it. Have over a hundred at this moment - in use -with ZERO regrets.
I would NEVER use PIC code on top of my own program to merely log.
my 2 cents |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Wed Mar 23, 2016 3:23 am |
|
|
Lets agree that the solution is probably by no means optimal.
However lets also give a bit more for mparzgnat.
If you search the forum for 'pointer to constant', or 'Harvard', you will find a whole suite of threads about the 'reason' there is any problem.
A rom pointer (using rom rather than const), can be used, but is still a _rom_ pointer, not a pointer to the RAM address space. So unless the code is written to understand rom pointers, won't work. You can't just take a rom pointer, cast it implicitly to a RAM pointer, and expect magically to be able to access the ROM address space.
So to work with already written functions expecting a pointer to RAM, the data has to be copied into the RAM address space. There are two ways of doing this. Either you do it yourself (strcpy), or let the compiler do it for you (PASS_STRINGS=IN_RAM). The overhead of both approaches is about the same. The third alternative (using rom char *), is to write the target functions to expect a rom pointer, which then avoids the need for such copying. This has a similar overhead in program size (since the data still has to be read from ROM), but saves on the RAM storage. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Mar 23, 2016 4:48 am |
|
|
Just to add that with PICs all string literals have to be stored in ROM. They all have to be copied at some point to RAM to be used by routines, even those which "understand" ROM pointers, as they will have to copy internally. The questions then are when that copying is done and by what.
Pretty much every way of doing it involves much the same time and code ROM penalty for copying the string from ROM to RAM. Reading ROM is not as fast as RAM. Reading in blocks makes more sense and is often more efficient. Note different PICS do it in different ways, some very old ones don't allow reading from directly ROM at all, hence requiring other, even less efficient implementations of literal strings.
There is no data stack for many PICs. Data cannot be "pushed" or "popped", therefore parameters cannot be passed on the stack, and local variables cannot be allocated on the stack as would be the case in most other C implementations. This means that local variables in CCS are allocated from RAM almost as if they were local. The compiler does reuse such RAM wherever it can. So the RAM required to hold local copies of strings may not be a big a price to pay as might at first be assumed. Essentially, the RAM required is that allocated to the routine with the most/largest local variables.
A routine that knows about ROM pointers can copy internally, either character by character or as a string. Character by character uses least RAM but is probably not going to be fast, and will probably use most program ROM. As a string is simpler - copy the whole thing to RAM and then do what a RAM-pointer version of the function would do. Uses more RAM, a bit more ROM (to implement the copying) and suffers the copy from ROM speed penalty. In both cases the compiler
The compiler can do the copying for the programmer in two ways. One is by PASS_STRINGS_IN_RAM. This, probably though not necessarily, does the copying when the routine is called, pretty much like an automated version of a routine written to accept ROM pointers. The costs therefore are likely to be much the same.
The second way for the compiler to deal with copying is for all literals to be treated as variables, and to live in RAM all the time, being copied once only during initialisation of the program. I think the programmer can make this happen by creating a structures - which don't use const - containing strings, such as for menus or tables for different localisations.
The programmer can also do the copying themselves using strcpy or similar. This is the approach I prefer as it makes it explicit as to what's going on and I can control the process, typically using one string buffer to handle all the strings. This is how I've implemented an SCPI parser, for example.
So, there are speed, RAM use and ROM use penalties inherent to the Harvard architecture. They have to be copied somewhere. |
|
|
|
|
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
|