Searching \ for '[PIC]Initialised data initialisation' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/memory.htm?key=data
Search entire site for: 'Initialised data initialisation'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]Initialised data initialisation'
2004\11\09@064028 by Mcgee, Mark

flavicon
face
Hi

I'm programming my PIC project (PIC16F628A) in assembler.  I created an
initialised data section idata, but I'm not sure how I can actually make this
data available to my program.

The MPASM and MPLINK documentation gives a spectacularly undetailed
explanation of how to use this feature.  I gather that the initialised data
gets placed in program (non-volatile) memory, and some file register locations
(volatile) are reserved for the data.  The problem I have is how do I get the
data from the non-volatile ROM to volatile where I can use it.

The docs mention some kind of link script and initialisation code but don't
give any examples or suggestions, and I found a PIC16F628Ai.lkr script on my
machine, but ran out of time this morning to have a play with it (I'm doing my
PIC stuff on my laptop on the train to and from work).

I assume I can just add the link script to my project (it is a relocatable
code base, already using the linker).  But then what?  Is there something I
need to call on reset, or will all work somehow magically (I expect not)?

Thanks
Mark

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\09@071738 by Jan-Erik Soderholm

face picon face
Mcgee, Mark wrote :

> Hi
>
> I'm programming my PIC project (PIC16F628A) in assembler.  I
> created an initialised data section idata, but I'm not sure how I can
> actually make this data available to my program.

If you describe what problem you think you are solving using this,
it would be easier to tell.

> The MPASM and MPLINK documentation gives a spectacularly
> undetailed explanation of how to use this feature.

Not sure about that. The online help file seems not that bad.

> I gather that the  initialised data gets placed in program
> (non-volatile) memory, and some file register locations
> (volatile) are reserved for the data. The problem I have is
> how do I get the data from the non-volatile ROM to volatile
> where I can use it.

The 628A can not directly read it's (own) Flash memory, so it
have to be RETLW instructions. Havn't tried it. Then you probably
have to "call" that "lookup table" and MOVWF your values into
the RAM space (reserved but not initialized by the IDATA driective).

> The docs mention some kind of link script and initialisation
> code but don't give any examples or suggestions, and I found a
> PIC16F628Ai.lkr script on my machine, but ran out of time
> this morning to have a play with  it (I'm doing my
> PIC stuff on my laptop on the train to and from work).
>
> I assume I can just add the link script to my project (it is
> a relocatable code base, already using the linker).

Then you must already be using a LNK script !?
Or havn't you done *any* (non-error) build yet ?
And you don't have to "play" with it, just add the LNK
file to your project, you must do that anyway, no matter
the IDATA directive...


> But then what?  Is there something I need to call on reset,

Yes. code calling your "lookup table". Just as usual. The IDATA
directive just helps creating the RETLW instructions (I think ! ).

> or will all work somehow magically (I expect not)?

Nothing does, does it ? :-) :-)

Why not just try it and see what code MPASM spits out ?

Jan-Erik.

____________________________________________

2004\11\09@081432 by olin_piclist

face picon face
Mcgee, Mark wrote:
> I'm programming my PIC project (PIC16F628A) in assembler.  I created an
> initialised data section idata, but I'm not sure how I can actually
> make this data available to my program.

The linker writes information about the location and desired content of
"initialized" RAM to a special section called .CINIT.  The .CINIT table is
intended to be read by special startup code that writes the initial values
to the specified RAM locations.

I have never used this feature, and don't know where to find this startup
code.  It is part of the initialization between the reset vector and
function MAIN when using the C compiler.  The code to read the .CINIT table
and write to RAM has got to be trivial.  It may be easier to find
documentation on the .CINIT table format and write it yourself.

I've sometimes had the opposite problem.  Unfortunately, the linker creates
a .CINIT section even when nothing is declared IDATA in the source code.  It
is 2 words long on a PIC 16 and 2 bytes on a PIC 18.  This can be a hassle
when working with small chips that only have 512 or 1024 words of memory.

> The docs mention some kind of link script and initialisation code but
> don't give any examples or suggestions, and I found a PIC16F628Ai.lkr
> script on my machine, but ran out of time this morning to have a play
> with it (I'm doing my PIC stuff on my laptop on the train to and from
> work).

I don't think you need anything special in the linker script.  I get that
annoying .CINIT section every time, and wish I could get rid of it.  What
you do need is the initialization code.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@084926 by Mcgee, Mark

flavicon
face
Hi

> If you describe what problem you think you are solving using this,
> it would be easier to tell.
Ok, on receipt of an RS232 command (a single character followed by optional
argument characters depending on the command), I want to 'goto' the unique
handling code for each command.  So I thought I'd have a table of command
characters :- db "abcde",0x00.  When I find a match, I use the offset of the
matching command as an index in to a 'jump table' using FSR/INDF.  The jump
table looks like this;
goto handler_a
goto handler_b
goto handler_c
goto handler_d
goto handler_e

The only problem is getting the "abcde", 0x00 inititialised data table set up.
Seems pointless having an idata section if I have to manually movlw, mvwf for
each value.

> The 628A can not directly read it's (own) Flash memory, so it
> have to be RETLW instructions. Havn't tried it. Then you probably
> have to "call" that "lookup table" and MOVWF your values into
> the RAM space (reserved but not initialized by the IDATA driective).
I got the ideas/opinions from MPASM/MPLINK docs, so I guess this doesn't
necessarily apply to 16F628A?

> Then you must already be using a LNK script !?
> Or havn't you done *any* (non-error) build yet ?
> And you don't have to "play" with it, just add the LNK
> file to your project, you must do that anyway, no matter
> the IDATA directive...
Yes indeed I have, and all works fine; I currently usepic16f628a.lnk, NOT
pic16f628a*i*.lnk - which I just found, just wondered what the difference was
and if it'd help with the initialised data.  I've been writing my code and
running it on the simulator for a few weeks now.

Just thought I'd post for any ideas/suggestions before my train journey home
tonight, where I'll get my next chance to do some PIC work.

> Yes. code calling your "lookup table". Just as usual. The IDATA
> directive just helps creating the RETLW instructions (I think ! ).
Forgive my ignorance, but how do I do this?  I did notice an idata_i (or
something like that) in the map file, and had a look with the program memory
window at the location in the map file - I see my data there, but not in the
actual file register (as expected).

Actually, I think I have just realised what you refer to: the linker converts
the idata stuff in to some RETLW <mydata> for each byte, and I need to 'call'
the relevant offset to get the value, is that right?  I'm still not sure how I
know what memory location to offset my 'call' from though.

Cheers,
Mark

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\09@085620 by Mcgee, Mark
flavicon
face
Yes, that's right.  That's what I should've asked for, but I rambled on, as I
tend to do...

> The linker writes information about the location and desired
> content of
> "initialized" RAM to a special section called .CINIT.  The
> .CINIT table is
> intended to be read by special startup code that writes the
> initial values
> to the specified RAM locations.

Anybody know how to invoke this code?  How about a tool to examine the lkr
file - anything?

Cheers,
Mark

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\09@090733 by olin_piclist

face picon face
Mcgee, Mark wrote:
>> The linker writes information about the location and desired
>> content of
>> "initialized" RAM to a special section called .CINIT.  The
>> .CINIT table is
>> intended to be read by special startup code that writes the
>> initial values
>> to the specified RAM locations.
>
> Anybody know how to invoke this code?  How about a tool to examine the
> lkr file - anything?

You are missing the point.  There is nothing special required in the .LKR
(linker control) file.  The linker always creates the .CINIT section, even
when not asked.  Besides, the .LKR file is something you create, so you can
examine it with a text editor anytime you want.

Have you searched the Microchip web site for the format of the .CINIT
section?


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@093136 by olin_piclist

face picon face
Mcgee, Mark wrote:
> Ok, on receipt of an RS232 command (a single character followed by
> optional argument characters depending on the command), I want to
> 'goto' the unique handling code for each command.  So I thought I'd
> have a table of command characters :- db "abcde",0x00.  When I find a
> match, I use the offset of the matching command as an index in to a
> 'jump table' using FSR/INDF.  The jump table looks like this;
> goto handler_a
> goto handler_b
> goto handler_c
> goto handler_d
> goto handler_e
>
> The only problem is getting the "abcde", 0x00 inititialised data table
> set up. Seems pointless having an idata section if I have to manually
> movlw, mvwf for each value.

I guess this is a long way of saying you want a dispatch table.  This is a
standard construct that has been done many times before.

Unless the dispatch routines are being switched dynamically (usually not the
case), it is better to put the table into program memory than the very
limited RAM.  Your not saving on program memory by using RAM either, because
the initial data starts out in program memory in the .CINIT section.

I've got a complete template project that does what you want.  Go to my PIC
development environment page http://www.embedinc.com/pic and then go to the
HOS example project.  The HOS_CMD.ASPIC module reads commands from the
serial port and jumps to different command handling routines via a dispatch
table just like you described.  In this example, the dispatch table is a
bunch of GOTO instruction in program memory.

For a different technique to solve the same problem, install the PIC
programmer development software at http://www.embedinc.com/picprg/sw.htm and
look at PRG_CMD.ASPIC module in the SOURCE/PICPRG directory.  This uses two
RETLW instructions per dispatch table entry.  This was done so that code
could examine a table entry without just jumping to the command processing
routine.  It also allows the command routine to be anywhere in memory, as
apposed to the GOTO method which depends on the PCLATH setting.

For a basic command interpreter, I would use the HOS project method.  If
you're not far along with your project yet, you could start with the HOS
source code and add your project specific stuff.  That's what the HOS
template project was intended for.

> Forgive my ignorance, but how do I do this?  I did notice an idata_i (or
> something like that) in the map file, and had a look with the program
> memory window at the location in the map file - I see my data there,
> but not in the actual file register (as expected).

Think about how the chip works.  All RAM is volatile, so there is no way to
"program" initial values into RAM and have them survive power down.  The
only way specific values get into RAM is if the program writes them there.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@094224 by Mark Scoville

flavicon
face
> I've sometimes had the opposite problem.  Unfortunately, the
> linker creates
> a .CINIT section even when nothing is declared IDATA in the
> source code.  It
> is 2 words long on a PIC 16 and 2 bytes on a PIC 18.  This can be a hassle
> when working with small chips that only have 512 or 1024 words of memory.
>

Olin, I have had the same problem with the "two extra words/bytes". I
complained to MicroChip a while back and here is thier explanation and
suggestion...

The linker automatically creates a ".cinit" section for initialized
variables. If there are no initialized variables then the section will
contain zeros (implemented as RETLW 0). This is a feature mainly for the C
compilers and does not really apply to assembly code. The two RETLW 0
instructions can be ignored and there is no way to stop them from being
generated.

If you are really pushing the limits of memory size cannot fit an extra two
instructions, then you can probably create a protected code section outside
the normal program memory area and force the ".cinit" section into this
code section. That will place the two RETLW instructions in the hex file
but out of the part's program memory.

<end of MicroChip explanation/suggestion>

I have used the technique suggested to force the .cinit section into an area
out of the parts memory range - I always thought it was a strange way to go,
but you can't argue with success. It did work.

-Mark



____________________________________________

2004\11\09@095711 by Jan-Erik Soderholm

face picon face
Mcgee, Mark wrote :

{Quote hidden}

I know of no other way on a 16F628...
That's what the still-to-be-indentified startup code
has to do, as far as I understand.

Anyway, I don't see the real benefit of having the "jump-table"
in *RAM*, but maybe one can use IDATA just to create the
RETLW table in flash and then not move it at all !?.

>
> > The 628A can not directly read it's (own) Flash memory, so it
> > have to be RETLW instructions. Havn't tried it. Then you probably
> > have to "call" that "lookup table" and MOVWF your values into
> > the RAM space (reserved but not initialized by the IDATA driective).

> I got the ideas/opinions from MPASM/MPLINK docs, so I guess
> this doesn't necessarily apply to 16F628A?

It only says that it doesn work on the 12-bit PICs.

> I did notice an
> idata_i (or something like that) in the map file, and had a look with the
> program memory window at the location in the map file - I see my data there,
> but not in the actual file register (as expected).

That is *not* expected.
I'm sure you see the data as a section in flash (program memory space)
There can be *NO* data from MPASM/MPLINK for the RAM !!

There is one thing you can be sure of, there is no way you
can have a table in RAM with known values without running *any*
code to set it up.

> Actually, I think I have just realised what you refer to: the
> linker converts the idata stuff in to some RETLW <mydata>
>  for each byte,

I'd guess the *assembler* put in the RETWL codes when it sees
the IDATA directive, the linker then calculates the proper addresses.

> and I need to 'call' the relevant offset to get the value, is that right?

That's what I'm guessing is happening on a 16F628 at least, yes.

> I'm still not sure how I know what memory location to offset my
> 'call' from though.

By the name you give the IDATA section.
In that startupcode (that moves the data from flask to RAM) you probably
use the name of the symbol that points to the "table". Probably there must be
two symbols, one pointing the the flash/retlw table, and one to the RAM table,
I'm not sure there...

Anyway, don't take this for the truth :-),
I'm mainly rambling around trying to get something out of this.
I don't think I have even seen IDATA used, and, thinking about your
jump table, it's probably just as easy to create that the "usual" way... :-)

Regards,
Jan-Erik.

____________________________________________

2004\11\09@114857 by Mcgee, Mark

flavicon
face
I do understand that the file registers will be lost on power down, so the
data will have to be kept in flash or EEPROM memory and copied to file
registers on start up.

As Olin suggests it's probably easier to make your own tables in program
memory and save the file registers for something else.  I guess that's what
everybody does, otherwise my original question would probably have been
answered in 5 seconds flat!

It would be nice to know what's supposed to happen with the CDATA, and if the
startup code to perform the copy does actually live somewhere.

So I'll just do something like;
CmdTbl        addwf PCL, F
               retlw 'c'
               retlw 'h'
               retlw 'v'
               ..etc

call with;
               movlw 0
               call CmdTbl
               ... value is now in W
               .. but in a loop and using correct PCLATH etc...

And the same idea again for the jump table;
CmdHndler        addwf PCL, F
               goto hanler_c
               goto hanler_h
               goto hanler_v
               ...etc

               movlw 0
               goto CmdHndler...

How would you implement this then - I have a standard message format to send
back, something like (IIRC);
"st:t=-000.0C:d=0:v=0......".  I need to fill in the blanks (the 0's) with
real live data.  So the message is a kind of template.  Am I best just to do a
movlw 's', call sendRS232Char for each item/character, or try to fill in the
blanks of the template and do a sendRS232 string in one go?

Cheers,
Mark

> {Original Message removed}

2004\11\09@115748 by olin_piclist

face picon face
Mark Scoville wrote:
> I have used the technique suggested to force the .cinit section into an
> area out of the parts memory range - I always thought it was a strange
> way to go, but you can't argue with success. It did work.

I guess your programmer software doesn't check for addresses outside the
target chip's range then.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@120222 by olin_piclist

face picon face
Jan-Erik Soderholm wrote:
> By the name you give the IDATA section.
> In that startupcode (that moves the data from flask to RAM) you probably
> use the name of the symbol that points to the "table". Probably there
> must be two symbols, one pointing the the flash/retlw table, and one to
> the RAM table, I'm not sure there...

It was my understanding that the .CINIT table contained all the information
about what values to put at what addresses.  This would mean the generic
startup code to set up initialized RAM doesn't need to know your IDATA
section names, which actually makes a lot of sense when you think about it.
However, I can't recall where I heard this about the .CINIT table, and I
don't really know what's in there.  I can say that in dozens of PIC
projects, I've never used an IDATA section.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@123114 by Bob Ammerman

picon face
Or, forget the table altogether and use:

   movf    cmd,W
   xorlw    'c'
   skpnz
   goto    hanler_c
   xorlw    'c'^'h'
   skpnz
   goto    hanler_h
   xorlw    'h'^'v'
   skpnz
   goto    hanler_v

Bob Ammerman
RAm Systems



----- Original Message -----
From: "Mcgee, Mark" <spam_OUTmark.mcgeeTakeThisOuTspamcsfb.com>
To: "'Microcontroller discussion list - Public.'" <.....piclistKILLspamspam@spam@mit.edu>
Sent: Tuesday, November 09, 2004 11:48 AM
Subject: RE: [PIC]Initialised data initialisation


{Quote hidden}

>> {Original Message removed}

2004\11\09@123330 by Alan B. Pearce

face picon face
>However, I can't recall where I heard this about
>the .CINIT table, and I don't really know what's
>in there.  I can say that in dozens of PIC
>projects, I've never used an IDATA section.

It really does seem to be aimed at using an HLL in programming, where as
part of the definition of variables an initial value is also specified,
rather than assembler where one would tend to do it differently anyway.

____________________________________________

2004\11\09@124432 by Mcgee, Mark

flavicon
face
I did have a little search around the microchip web site for .CINIT, but drew
a blank....however my poor web browsing ability is legendary.

Cheers,
Mark

> {Original Message removed}

2004\11\09@125211 by Mcgee, Mark

flavicon
face
HLL?  

Pretty well all discussions on this topic I've read have been in the 'C'
programming world.  I'm using assembler because it seems like more fun, back
to my programming origins, or quite probably that I'm insane.

Cheers,
Mark

I can see the benefit of using 'C' and libraries for I2C, LCD display drivers
etc...
> It really does seem to be aimed at using an HLL in
> programming, where as
> part of the definition of variables an initial value is also
> specified,
> rather than assembler where one would tend to do it
> differently anyway.

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\09@140234 by Bob Ammerman

picon face
> Mark Scoville wrote:
>> I have used the technique suggested to force the .cinit section into an
>> area out of the parts memory range - I always thought it was a strange
>> way to go, but you can't argue with success. It did work.
>
> I guess your programmer software doesn't check for addresses outside the
> target chip's range then.

How about a little filter that deletes the data from the .HEX file.

Bob Ammerman
RAm Systems

____________________________________________

2004\11\09@140834 by Jan-Erik Soderholm

face picon face
Hi !
I had to run a little test with idata... :-)

I built the following code :

--------------------------------------
       list     p=16f628a
       #include p16f628a.inc

PROG    CODE

main
       goto    main

test1   idata

testx1  db h'11'
testx2  db h'22'
testx3  db h'33'

       end
--------------------------------------

When using "View -> Program Memory" in MPALB, I got the following :
(the texts after "<=" are my comments...)

Line  Address  Opcode Label   Disassembly              

    1   0000  3FFF           ADDLW 0xff
    2   0001  3FFF           ADDLW 0xff
    3   0002  3FFF           ADDLW 0xff
    4   0003  3FFF           ADDLW 0xff
    5   0004  3FFF           ADDLW 0xff
    6   0005  2805   MAIN    GOTO MAIN
    7   0006  3401           RETLW 0x1    <= .cinit address.
    8   0007  3400           RETLW 0
    9   0008  340E           RETLW 0xe    <= address of TEST1_i
   10   0009  3400           RETLW 0
   11   000A  3420           RETLW 0x20   <= first avail GPR ?
   12   000B  3401           RETLW 0x1    <= size of each table "entry" ?
   13   000C  3403           RETLW 0x3    <= Table "size" ?
   14   000D  3400           RETLW 0
   15   000E  3411           RETLW 0x11   <= values from the source code !
   16   000F  3422           RETLW 0x22   <= values from the source code !
   17   0010  3433           RETLW 0x33   <= values from the source code !
   18   0011  3FFF           ADDLW 0xff
   19   0012  3FFF           ADDLW 0xff

(The rest was 3FFF, as expected...)

The "section" part of the MAP file :

               Section Info
 Section       Type    Address   Location Size(Bytes)
---------  ---------  ---------  ---------  ---------
    PROG       code   0x000005    program   0x000002
  .cinit    romdata   0x000006    program   0x000010
 TEST1_i    romdata   0x00000e    program   0x000006
   TEST1      idata   0x000120       data   0x000003

Ot would be possible to write some code to use this to populate
a table in RAM, I'd guess.

Regards,
Jan-Erik.
____________________________________________

2004\11\09@141331 by John J. McDonough

flavicon
face
----- Original Message -----
From: "Jan-Erik Soderholm" <jan-erik.soderholmspamKILLspamtelia.com>
Subject: RE: [PIC]Initialised data initialisation


> Yes. code calling your "lookup table". Just as usual. The IDATA
> directive just helps creating the RETLW instructions (I think ! ).

Well, the dt directive will do that.  I did a little reverse engineering and
here is what I found.

Using an idata directive results in (at least) three program sections.  If
you use one idata, you get a .cinit section, a .idata section, and a
.idata_i section.   The second two sections get replicated for additional
(named) idata directives.

The .cinit section contains data in 16 bit words, organized as 2 retlw
instructions per word, low byte first.  The first value contains the number
of sections to initialize.  For each section, there are then three words.
In order, they are the address (in program memory) of the .idata_i section,
the address (in GPR memory) of the .idata section, and the length of the
section.

The .idata_i section contains a retlw instruction for each byte to be
initialized.

If you name an idata section, the section names become your name, and your
name _i. So

   b2   idata

causes sections named b2 and b2_i.

What isn't at all obvious to me is how to describe to the assembler the
addresses of these sections.  So it's not clear to me that this is even
useable from assembler, at least not without manually patching in the
address of .cinit.

Much simpler just to use dt.

--McD


____________________________________________

2004\11\09@145710 by Ken Pergola

flavicon
face
John J. McDonough wrote:

> What isn't at all obvious to me is how to describe to the assembler the
> addresses of these sections.

To try to get those addresses I would try MPASM's currently undocumented
operators I mentioned in a past thread:


OPERATORS
---------

SCNSZ     (obtains size of the section)
SCNSTART  (obtains the starting address of the section)
SCNEND    (obtains the ending address of the section)


Best regards,

Ken Pergola




____________________________________________

2004\11\09@161146 by olin_piclist

face picon face
Bob Ammerman wrote:
>> Mark Scoville wrote:
>>> I have used the technique suggested to force the .cinit section into
>>> an area out of the parts memory range - I always thought it was a
>>> strange way to go, but you can't argue with success. It did work.
>>
>> I guess your programmer software doesn't check for addresses outside
>> the target chip's range then.
>
> How about a little filter that deletes the data from the .HEX file.

That's exactly what I did one time when I just couldn't spare the 2 extra
words.  I didn't want to give the customer something that various
programmers might barf on.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\09@161320 by Bob Ammerman

picon face
I have made my guesses for the format of the .cinit data below:

two byte count - number of initialized data blocks
>     7   0006  3401           RETLW 0x1    <= .cinit address.
>     8   0007  3400           RETLW 0

two bytes - starting address of data in program memory
>     9   0008  340E           RETLW 0xe    <= address of TEST1_i
>    10   0009  3400          RETLW 0

two byte address of initialized data area (for some reason it was placed in
bank 2, see the map file)
>    11   000A  3420         RETLW 0x20
>    12   000B  3401          RETLW 0x1

two byte data count
>    13   000C  3403           RETLW 0x3
>    14   000D  3400           RETLW 0

If there were more blocks to be initialized then there would be additional
groups of 6 bytes here containing starting address in program memory,
starting address in data memory and length of each additional block.

the actual data
>    15   000E  3411           RETLW 0x11   <= values from the source code !
>    16   000F  3422           RETLW 0x22   <= values from the source code !
>    17   0010  3433           RETLW 0x33   <= values from the source code !

Bob Ammerman
RAm Systems

____________________________________________

2004\11\09@161947 by John J. McDonough

flavicon
face
----- Original Message -----
From: "Ken Pergola" <.....no_spamKILLspamspam.....localnet.com>
Subject: RE: [PIC]Initialised data initialisation


> To try to get those addresses I would try MPASM's currently undocumented
> operators I mentioned in a past thread:

No joy.

   movlw SCNSTART_LOW .cinit

assembles fine, but the linker can't resolve .cinit.   .cinit happens to end
up with the starting address of the codepage page0 which holds the section
named PROG0, but neither of those get resolved, either.  The linker barfs if
I try to name a section .cinit so I can stick a label there.  However,
instead of an unresolved error, it ends up with an assertion failure.

--McD


____________________________________________

2004\11\09@162914 by Jan-Erik Soderholm

face picon face
Ken Pergola wrote :

> John J. McDonough wrote:
>
> > What isn't at all obvious to me is how to describe to the
> > assembler the addresses of these sections.
>
> To try to get those addresses I would try MPASM's currently
> undocumented operators I mentioned in a past thread:
>
>
> OPERATORS
> ---------
>
> SCNSZ     (obtains size of the section)
> SCNSTART  (obtains the starting address of the section)
> SCNEND    (obtains the ending address of the section)
>

Hi.
What you'd like to do, is to make a "call" to the first
address in the section ".cinit", right ?

I have not been able to make that work.
When using "SCNSTART_LOW .cinit", I get
"onresolved reference, .cinit" from MPLINK.

My test code looks like this :

       list p=16f628a
       #include p16f628a.inc

PROG    CODE
main
       movlw   scnstart_low .cinit
       goto    main

test1   idata
testx1  db h'11'
testx2  db h'22'
testx3  db h'33'
       end

Can the SCN* functions onle those sections already
in the LNK file and not those created on-the-fly ?

Anyway, this seems the way C-compilers are handling
pre-initialized variables. There must be a way of getting
this to work. With the informatin created by IDATA, one common
bit of code should be able to dymamiclay handle any number
of variables.

Interesting anyway... :-)
Jan-Erik.
____________________________________________

2004\11\10@044252 by Mcgee, Mark

flavicon
face
Hi

I did some investigative work of my own last night, and Bob, I think you have
the structure right.

The good news is that there is a file which comes with MPASM to do the copy
for you!  There are actually two of them, presumably for different
architectures, but the one I used was called IDASM16.ASM.  The other IIRC was
IDASM17.ASM.  I just copied the file to my project, and added it to the
project.

The file has a function called _copy_idata which you call, and hey presto!

Looking inside the file, it shows the format of the .cdata section, and I
think that correlates with Bob's research.

btw, try "extern _cdata" to access the cdata section.

There is also a couple of nifty coding techniques in this file, something like
this (from memory);
       goto label 2
label1
       does some _cdata access, then does
       movwf PCL.... to call the actual _cdata RETLW
       .. and it returns to label3 below!  cool!
       
label2
       call label1 ; save return location
label3
       ... do stuff with W register loaded

Cheers,
Mark

{Quote hidden}

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\10@074906 by Bob Ammerman

picon face
I just look at IDASM16.ASM and, unless I am greatly mistaken, it has a MAJOR
bug in it!

It will break if there is more than 1 block of data to be copied. It will
simply copy the first block over and over again.

I am guessing that in its actual application with idata and especially the C
compiler that there is only ever one block of data to copy and so this bug
hasn't been exposed.

Bob Ammerman
RAm Systems


{Original Message removed}

2004\11\10@082432 by Mcgee, Mark

flavicon
face
I must admit, once I'd seen what was going on, I didn't hang around to study
the multi-block looping too deeply.

Unless you're getting confused with the VARIABLE used for offsetting blocks (i
don't have the file here at work so this is from memory) - something like
"idata + VARIABLE + 2" - IIRD I think the idata offset does get updated each
time 'round the loop, and the VARIABLE is an assembly time variable, not run
time, so the offset is correct each time around the loop, but it's not
obvious.  I remember studying this and being confused for a few moments, now I
think about it.  However you may have spotted something else that I didn't,
and I'm talkiing rubbish!

I found the iorwf comparisons quite confusing, and didn't fully understand
what was going on at these parts other than to see that they were used as
comparisons.  I use xorf for comparisons myself.

Cheers,
Mark
{Quote hidden}

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\10@104004 by Bob Ammerman

picon face

----- Original Message -----
From: "Mcgee, Mark" <EraseMEmark.mcgeespam_OUTspamTakeThisOuTcsfb.com>
To: "'Microcontroller discussion list - Public.'" <piclistspamspam_OUTmit.edu>
Sent: Wednesday, November 10, 2004 8:24 AM
Subject: RE: [PIC]Initialised data initialisation


{Quote hidden}

Actually, it is broken _because_ it is using an assembly time variable. If
you think about it, there is exactly one copy of the instructions that fetch
the six bytes of block description, and those instructions will thus always
fetch from the same locations in program memory.

> I found the iorwf comparisons quite confusing, and didn't fully understand
> what was going on at these parts other than to see that they were used as
> comparisons.  I use xorf for comparisons myself.
>
> Cheers,
> Mark

'xorwf' is good for comparing for a specific value. 'iorwf' is a nice trick
to check a 16-bit value for zero.

Bob Ammerman
RAm Systems


____________________________________________

2004\11\10@110309 by Mcgee, Mark

flavicon
face
>From what I remember, it doesn't use indirect addressing, does it?  So you're
right there.

So I assume you ior the msb with the lsb and if the Z flag is set then the
whole 16-bit word is 0, correct?  Neat.  There seems to be all sorts of tricks
specific to each and architecture/chip.  I'm gradually learning!

Cheers,
Mark
{Quote hidden}

==============================================================================
This message is for the sole use of the intended recipient. If you received
this message in error please delete it and notify us. If this message was
misdirected, CSFB does not waive any confidentiality or privilege. CSFB
retains and monitors electronic communications sent through its network.
Instructions transmitted over this system are not binding on CSFB until they
are confirmed by us. Message transmission is not guaranteed to be secure.
==============================================================================

____________________________________________

2004\11\10@112738 by Bob Ammerman

picon face
For what it is worth, I would have designed the whole .cinit thing very
differently....

First, the data would be a byte stream starting at location _cinit. Each
'chunk' would be stored as follows:

1 byte - length of chunk
2 bytes - address in RAM to store into
N bytes - data to be stored in RAM

The code to do the copying would be (WARNING: Untested code ahead):

; Assumptions made:
;
;    On entry to this routine PCLATH is correct for this code.
;    This code fits entirely within one 2K page of program memory.
;

CopyIdataToRam:

; get the initial pointer

   movlw    high(_cinit)
   movwf    pHigh
   movlw    low(_cinit)
   movwf    pLow

outer_loop:

; get the count, get out if zero

   call        get_byte
   skpnz
   return
   movwf    counter

; get the ram address

   call        get_byte
   iorlw      0
   movwf   FSR

   call        get_byte
   iorlw     0
   bcf        STATUS,IRP
   skpz
   bsf        STATUS,IRP

;  process all the data bytes

inner_loop:
   call       get_byte
   movwf  INDF
   incf       FSR,F    ; note: we assume this doesn't carry

   decfsz  counter,F
   goto     inner_loop
   goto     outer_loop

; Local subroutine 'get_byte'
; Advance the pointer and gets a data byte
; Sets Z if the data byte is zero
; Exits with PCLATH correct for this code

get_byte:
   call       get_byte_2        ; fetch the byte

   movwf  temp                 ; save byte we got

   incf       pHigh,F            ; advance the pointer
   incfsz    pLow,F
   decf      pHigh,F

   movlw  high(get_byte)  ; restore PCLATH
   movwf  PCLATH

   movf    temp,W            ; get byte to return, set Z flag

   return

get_byte_2:
   movf    pHigh,W
   movwf   PCLATH
   movf    pLow,W
   movwf    PCL



____________________________________________

2004\11\10@160022 by Danny Decell

picon face
Hi Olin,

I'm new to the piclist (and pics for that matter) and this is my first post
so if I do anything wrong please let me know. I also checked out the code
at your site, it an amazing framework that must really streamline the
designs using the PIC family of processors. I wish I could understand more
of the abstraction than what I can but maybe with time. In the meanwhile
could you help me with a couple of questions?

1) Where does the file hos.inc actually reside? I must be blind because I
couldn't find it in the extracted files and folders provided when I
downloaded the whole package.

2) When I do find hos.inc is that where the actual hard coded values for
w_save and status_save are when you take your interrupt? I am interested in
seeing where you save these values and how you guard context when the data
bank is somewhere other than bank zero at the time of an interrupt.

Thank you for you help. It's greatly appreciated.



>I've got a complete template project that does what you want.  Go to my PIC
>development environment page http://www.embedinc.com/pic and then go to the
>HOS example project.  The HOS_CMD.ASPIC module reads commands from the
>serial port and jumps to different command handling routines via a dispatch
>table just like you described.  In this example, the dispatch table is a
>bunch of GOTO instruction in program memory.

____________________________________________

2004\11\10@165416 by olin_piclist

face picon face
Danny Decell wrote:
> 1) Where does the file hos.inc actually reside? I must be blind because
> I couldn't find it in the extracted files and folders provided when I
> downloaded the whole package.

I use a different naming convention for files so that the build system can
automatically identify them.  All regular PIC assembler source file names
end in .aspic.  The file you are looking for is called HOS.INS.ASPIC and is
in the SOURCE/PICS directory.  All the ASPIC files are translated to the
native MPASM files by the preprocessor.

> 2) When I do find hos.inc is that where the actual hard coded values for
> w_save and status_save are when you take your interrupt?

No, these are local variables in HOS_INTR.ASPIC.  They are only used during
interrupts, so there is no need to make them visible outside the interrupt
module.  That's one of the nice things about using the linker and having
multiple source modules.

The addresses of W_SAVE and STATUS_SAVE are not hard coded.  The source code
defines the linker section they must be allocated from, but the linker
decides the exact address.  There is no reason the source code needs them to
be at a particular address within their sections (that's why the sections
are defined as they are).

> I am
> interested in seeing where you save these values and how you guard
> context when the data bank is somewhere other than bank zero at the
> time of an interrupt.

The code is in HOS_INTR.ASPIC.  W is saved into global (unbanked RAM) so
that the bank settings at the time of the interrupt don't matter.  STATUS is
saved into bank 0, but the value is written to STATUS_SAVE only after a CLRF
STATUS is done to ensure bank 0 is set.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\11@025851 by Jan-Erik Soderholm

face picon face
Danny Decell wrote :

> 2) When I do find hos.inc is that where the actual hard coded
> values for w_save and status_save are when you take your
> interrupt? I am interested in seeing where you save these
> values and how you guard context when the data bank is
> somewhere other than bank zero at the time of an interrupt.

Hi.
You didn't say what PIC you are using, but note that *if*
you are looking at the PIC18-line, those registers are
saved on interrupt automaticly. No need for the *_save
registers in that case. The exception is if you are using
both high and low prio interrupt, since there is only one
set of shadow registers...
And, as usual, see the data sheets for the details... :-)

Regards,
Jan-Erik
.
____________________________________________

More... (looser matching)
- Last day of these posts
- In 2004 , 2005 only
- Today
- New search...