OK, I've got an "interesting" bug-hunt going on, and it's about time I asked
a couple of sanity-check questions! I was going to post the entire .asm,
but perhaps that's not (yet) necessary... we'll see!
Using '16F877. I've set up a data structure in Bank 1:
B1_COUNT equ 0xA0
B1_ARRAY equ 0xA0
B1_OTHERDATA equ 0xC3
B1_MOREDATA equ 0xC4
; A method "foo" is called twice by my main program logic.
;
foo
banksel B1_COUNT
; This is the ONLY reference to B1_COUNT anywhere:
incf B1_COUNT
movlw B1_ARRAY
addwf B1_COUNT, W
movwf FSR
incf INDF
return
The interrupt service saves and restores FSR (and W, STATUS, PCLATH) in the
"standard" manner. (FSR *is* used in the intsvc to store characters
received from serial port, but it is set
to point to a buffer space in Bank 0).
THE PROBLEM: sometime well after "foo" is called (exactly twice), when I go
to read the contents of B1_COUNT.... it's sporadically incorrect!
I note that ALL of what I expect to see elsewhere in both Bank 0 and Bank 1
data space is correct... except for this one address!
Is there anything "odd" about what I'm doing? I can't seem to think of new
ways to look at this one!
(Oh, BTW, this one's not easily simulated, due to the need for RS232 and I2C
I/O.. :^(
Thanks for any helpful thoughts you might have!
Jim
> OK, I've got an "interesting" bug-hunt going on, and
> it's about time I asked
> a couple of sanity-check questions! I was going to
> post the entire .asm,
> but perhaps that's not (yet) necessary... we'll see!
>
> Using '16F877. I've set up a data structure in Bank
> 1:
> B1_COUNT equ 0xA0
> B1_ARRAY equ 0xA0
> B1_OTHERDATA equ 0xC3
> B1_MOREDATA equ 0xC4
>
> ; A method "foo" is called twice by my main program
> logic.
> ;
> foo
> banksel B1_COUNT
> ; This is the ONLY reference to B1_COUNT
> anywhere:
> incf B1_COUNT
> movlw B1_ARRAY
> addwf B1_COUNT, W
> movwf FSR
> incf INDF
> return
>
> The interrupt service saves and restores FSR (and W,
> STATUS, PCLATH) in the
> "standard" manner. (FSR *is* used in the intsvc to
> store characters
> received from serial port, but it is set
> to point to a buffer space in Bank 0).
>
> THE PROBLEM: sometime well after "foo" is called
> (exactly twice), when I go
> to read the contents of B1_COUNT.... it's
> sporadically incorrect!
> I note that ALL of what I expect to see elsewhere in
> both Bank 0 and Bank 1
> data space is correct... except for this one
> address!
>
> Is there anything "odd" about what I'm doing? I
> can't seem to think of new
> ways to look at this one!
> (Oh, BTW, this one's not easily simulated, due to
> the need for RS232 and I2C
> I/O.. :^(
> Thanks for any helpful thoughts you might have!
> Jim
>
>
> > --
> > http://www.piclist.com#nomail Going offline? Don't
> AutoReply us!
> > email .....listservKILLspam.....mitvma.mit.edu with SET PICList
> DIGEST in the body
> >
>
> --
> http://www.piclist.com#nomail Going offline? Don't
> AutoReply us!
> email EraseMElistservspam_OUTTakeThisOuTmitvma.mit.edu with SET PICList
> DIGEST in the body
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com
Sorry guys, I should have said that B1_ARRAY index is "1-based", so Yes, it
is correct that it is the same address as B1_COUNT.
Another way to say the same thing is that this is a "counted array": the 0th
element contains the # of entries in the array. (Of course that only works
for 1-based indexing of elements).
Jim
----- Original Message -----
From: "Ken Pergola" <@spam@no_spamKILLspamLOCALNET.COM>
To: <KILLspamPICLISTKILLspamMITVMA.MIT.EDU>
Sent: Monday, August 18, 2003 5:32 PM
Subject: Re: [PIC:] Addressing Bank 1 data space
> Hi Jim,
>
> Took a quick glance:
>
> Are B1_COUNT and B1_ARRAY aliases on purpose (since they are the same
> location 0xA0) or was that just a typo?
>
> Regards,
>
> Ken Pergola
>
>
Manually allocating RAM is a bad idea. Your B1_xxx symbols are just
integer values, and none of the RAM is reserved for anything. Other
symbols could be defined with those same addresses and you'd get no error
or warning messages.
> foo
> banksel B1_COUNT
> ; This is the ONLY reference to B1_COUNT anywhere:
> incf B1_COUNT
> movlw B1_ARRAY
> addwf B1_COUNT, W
> movwf FSR
> incf INDF
> return
If you want help from others, you should first take the steps within your
power to solve the problem yourself. It's rather dissappointing to see
someone ask for help with undocumented absolute mode code that manually
assigns variables to specific addresses, especially after the many many
discussions about this on the list. Such irresponsible code is just
asking for problems, and doesn't deserve help.
By the way I think I know what your problem is (hard to tell since there
are no comments to show what it's *supposed* to do), and it's directly
related to a bad coding practice. Clean up your act and you'll probably
find the problem yourself, or at least you can then post your code here
without shame.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
Just a quick glimpse thru this, I'm wondering whether the destination on the "incf INDF" instruction makes a difference?
Cheers,
-Neil.
On Tuesday 19 August 2003 02:59, Jim Tellier scribbled: {Quote hidden}
> Sorry guys, I should have said that B1_ARRAY index is "1-based", so Yes, it
> is correct that it is the same address as B1_COUNT.
> Another way to say the same thing is that this is a "counted array": the
> 0th element contains the # of entries in the array. (Of course that only
> works for 1-based indexing of elements).
> Jim
> ----- Original Message -----
> From: "Ken Pergola" <spamBeGoneno_spamspamBeGoneLOCALNET.COM>
> To: <TakeThisOuTPICLISTEraseMEspam_OUTMITVMA.MIT.EDU>
> Sent: Monday, August 18, 2003 5:32 PM
> Subject: Re: [PIC:] Addressing Bank 1 data space
>
> > Hi Jim,
> >
> > Took a quick glance:
> >
> > Are B1_COUNT and B1_ARRAY aliases on purpose (since they are the same
> > location 0xA0) or was that just a typo?
> >
> > Regards,
> >
> > Ken Pergola
> >
> >
> B1_COUNT equ 0xA0
> B1_ARRAY equ 0xA0
>
> Is it OK, that this is one and the same register?
and Ken Pergola wrote:
> Took a quick glance:
>
> Are B1_COUNT and B1_ARRAY aliases on purpose (since they are the same
> location 0xA0) or was that just a typo?
Now, and this is a rather importent point, B1_COUNT and
B1_ARRAY are neither "registers" nor "locations". They are
just two SYMBOLS that (in this case) happens to be set to
the same value. Those values could represent anything,
temperatures, times, seconds even (as might be the case
in this case) addresses of memory locations. It all depends
on how the symbols are used later on in the code.
> OK, I've got an "interesting" bug-hunt going on, and
> it's about time I asked
> a couple of sanity-check questions! I was going to
> post the entire .asm,
> but perhaps that's not (yet) necessary... we'll see!
>
> Using '16F877. I've set up a data structure in Bank
> 1:
> B1_COUNT equ 0xA0
> B1_ARRAY equ 0xA0
> B1_OTHERDATA equ 0xC3
> B1_MOREDATA equ 0xC4
>
> ; A method "foo" is called twice by my main program
> logic.
> ;
> foo
> banksel B1_COUNT
> ; This is the ONLY reference to B1_COUNT
> anywhere:
> incf B1_COUNT
> movlw B1_ARRAY
> addwf B1_COUNT, W
> movwf FSR
> incf INDF
> return
>
> The interrupt service saves and restores FSR (and W,
> STATUS, PCLATH) in the
> "standard" manner. (FSR *is* used in the intsvc to
> store characters
> received from serial port, but it is set
> to point to a buffer space in Bank 0).
>
> THE PROBLEM: sometime well after "foo" is called
> (exactly twice), when I go
> to read the contents of B1_COUNT.... it's
> sporadically incorrect!
> I note that ALL of what I expect to see elsewhere in
> both Bank 0 and Bank 1
> data space is correct... except for this one
> address!
>
> Is there anything "odd" about what I'm doing? I
> can't seem to think of new
> ways to look at this one!
> (Oh, BTW, this one's not easily simulated, due to
> the need for RS232 and I2C
> I/O.. :^(
> Thanks for any helpful thoughts you might have!
> Jim
>
>
> > --
> > http://www.piclist.com#nomail Going offline? Don't
> AutoReply us!
> > email listservEraseME.....mitvma.mit.edu with SET PICList
> DIGEST in the body
> >
>
> --
> http://www.piclist.com#nomail Going offline? Don't
> AutoReply us!
> email EraseMElistservmitvma.mit.edu with SET PICList
> DIGEST in the body
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com
>> B1_COUNT equ 0xA0
>> B1_ARRAY equ 0xA0
>
> Is it OK, that this is one and the same register?
and Ken Pergola wrote:
> Took a quick glance:
>
> Are B1_COUNT and B1_ARRAY aliases on purpose (since they are the same
> location 0xA0) or was that just a typo?
How do you know that this symbols are "registers" or "locations" just
from the equ's ?
They could represent just about anything, temps, secs, or
*maybe* addresses of memory locations. It depends on how
these two symbols are used later on in the code...
> How do you know that this symbols are "registers" or
> "locations" just
> from the equ's ?
>
> They could represent just about anything, temps,
> secs, or
> *maybe* addresses of memory locations. It depends on
> how
> these two symbols are used later on in the code...
>
> Jan-Erik.
>
> --
> http://www.piclist.com hint: The list server can
> filter out subtopics
> (like ads or off topics) for you. See
Yepp, and a good example why relocatable code is better
(in this regard) where you use the "RES" directive to
*allocate memory* and "EQU" for setting any *symbol value*.
It's clearer and you don't have to assume anything.
:-)
Jan-Erik.
Samo Benedicic wrote:
> Thanks for the point. Obvious case of one-track mind.
> I just assumed that this is part of RAM space
> allocation code.
>> How do you know that this symbols are "registers" or
>> "locations" just from the equ's ?
>> How do you know that this symbols are "registers" or "locations" just
>> from the equ's ?
Since is the second time you've posted a message quoting me, I guess you are
waiting for my response, right? :)
Of course one doesn't know just by looking at the equates.
Yes, I was irresponsible in saying "location", I should have said "value". I
am well aware of and totally understand the excellent points you make.
In all fairness, I feel you made an incorrect assumption about my post. I
did not *just* look at the equates as your question implies -- I read
between the lines, read his comments and saw how he used these equates in
the *context* of his code snippet.
Please remember that the original poster specifically said "I've set up a
data structure in Bank 1" and listed those equates right after that comment.
It was obvious from this statement of his that he was allocating (but not
reserving) RAM manually.
Poster said, "when I go to read the contents of B1_COUNT.... it's
sporadically incorrect!". It is clear from this comment and from his code
that the B1_COUNT equate represents the address of a data memory location.
Again, looking at the context used in the code, the 'B1_ARRAY' equate
represents the address of a data memory location. He is using the FSR so we
know that the array is not in program memory, but rather in data memory.
Ken,
Thanks for clarifying that! I was about to re-post the code snippet,
since folks seem to have lost the context of this thread. Yes, in fact, the
B1_xxxx equates are absolute address allocations. There's good reason for
this, but it's not evident (or relevant to) my code snippet post. I chose
not to complicate the question that I originally posed.
Jim
No need to feel this way -- I value your opinion and your posts. I feel that
this has been a great, productive thread. There have been many people on
this list extolling the virtues of relocatable code (you, Olin, Lyle, Dave
Dilatush, etc come to mind right now). It is definitely *the* way to go. I
am surprised at myself for not investing the time in doing so yet, but for
the past couple of years I've been using the HI-TECH PICC/PICC-18 compiler
and never wanted to program in ASM in full force -- at least not in the
workforce arena. The portability of C source code is just too valuable in
the workplace especially if you need to switch to nonPIC microcontrollers.
But then the PIC18F architecture came out and I fell in love with PIC
assembly language again (with my personal time and side projects). It's just
been a pure blast for me with the augmented PIC18F instruction set -- make
things fun again. Now, I've decided it would be in my best interest to learn
MPLINK/MPLIB to write better code. Olin gave me some great help and I
appreciate that. I feel that one can always improve their chops.
Seriously, I wish I had Olin beating on my head when I started out
programming PICs -- at least I would have started writing relocatable code
from the get go. I learned PIC ASM on my own and that has its own drawbacks.
Anyway Jan, I'm getting off-topic here so I better stop.
> Yes, in fact, the B1_xxxx equates are absolute address allocations.
> There's good reason for this,
Oh? What is it? I've seen this done usually because someone is too lazy
to use the linker or even CBLOCK, not a very good programmer, copied some
badly written example (unfortunately some of these come directly from
Microchip) verbatim, etc. However, none of these are *good* reasons.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
I wrote:
> > Yes, in fact, the B1_xxxx equates are absolute address allocations.
> > There's good reason for this,
>
Olin Lathrop wrote:
> Oh? What is it? I've seen this done usually because someone is too lazy
> to use the linker or even CBLOCK, not a very good programmer, copied some
> badly written example (unfortunately some of these come directly from
> Microchip) verbatim, etc. However, none of these are *good* reasons.
>
As someone with plenty of experience, I agree. I don't claim any of those
reasons, but my reasons are not relevant to this post, and are in fact,
proprietary IP.
To everyone who particpated in this thread: I thank those of you who
contributed useful, productive suggestions and comments.
As I recently pointed out in private communication to Olin, due to his
arrogant, caustic and anti-productive replies (not just this one), I have
added his name to my SPAM filter. I won't be poked, ridiculed or subject
to anyone's abuse in the context of trying to Help and/or Be Helped in a
public Technical forum. For anyone interested in continuing to pursue the
technical aspects of this thread, I'll note that this problem (the sporadic
modification of 0xA0 contents, w.r.t. my original post) has yet to be
solved. Any other nonsense can be take [OT].
Thanks again for your interest!
Jim
I guess the thing one needs to remember is that we all know each other on
this list simply by what we write in our post -- which is only a small
fraction of who we actually are. I had a lab instructor in college that
seemed to be really tough on me (actually everyone) and I sort of took it
personally. Looking back I am such a better designer for knowing him -- he
really challenged me and opened my eyes to electronics. I really wish I
could tell him this today and especially thank him, but unfortunately he
died not too long after I graduated. I didn't realize it at the time, but he
was hard on us because he cared about us.
Every time someone criticized my engineering work, be it hardware, software,
or firmware, it has made me a much better designer. It doesn't feel good
walking away with my tail between my legs, but boy have these experiences
been extremely helpful.
Anyway, getting back to the root of the thread, you said you still have a
problem with your code. Are you at liberty to discuss where you currently
are with the problem?
Are you able to pump out some registers out the serial port for debugging
purposes?
Olin gave you a hint about a possible bad coding practice -- maybe FSR
related?
Is the ISR modifying the bank select register?
I haven't had much time to plow through the code you posted.
Let us know your current status -- it would be nice to see you find out what
the problem is in your code.
you wrote:
> ...
> Every time someone criticized my engineering work, be it hardware,
software,
> or firmware, it has made me a much better designer.
I, too, have learned to appreciate constructive criticism; and, believe me -
I've had
my share! - but that's not what I've had my hackles raised about!
you wrote:
> Are you able to pump out some registers out the serial port for debugging
> purposes?
> Olin gave you a hint about a possible bad coding practice -- maybe FSR
> related?
> Is the ISR modifying the bank select register?
!!! I think I'm onto something!
Due to the sporadic nature of the "failure" [which was that B1_COUNT was
getting trashed], it appears that something asynchronous to the main
execution thread must be the culprit. So, I went directly to the ISR with
my suspicions: far as I can see, ISR is as correct as it can be... *IF*
execution was interrupted from Bank 0 ! The ISR saves 'W', 'STATUS', 'FSR'
etc. into temp variables that are defined in Bank 0. Now, I've not written
code before that operates on Data Memory in Bank1...3. Could it possibily
be that I need to 'shadow' my ISR Temp variables in each Bank? As it turns
out, my "W_TEMP" variable is allocated at address 0x20 (bank 0). What is
supposed to happen if, while I'm executing code that's referencing Bank 1, I
get an interrupt and attempt to save "w" in "W_TEMP" (0x20)? I'm guessing
that this might be the source of 0xA0 being whacked? Does this sound right
to you?
I did one experiment that seems to reinforce my conjecture: moved the data
structure definition to be based at address 0xA1... never see any execution
problems (after MANY retries!).
I've got to try one more experiment: to see if the value that "clobbers"
0xA0 was in fact the "W" value being saved by the ISR.
To quote "Arnold"... "I'll be back!"
Jim
>> Is the ISR modifying the bank select register?
>
> !!! I think I'm onto something!
This is a perfect example the true problem being very different than what
the original poster was asking about. This is why everything is and should
be suspect and up for reexamination when someone is asking for help about a
bug.
> The ISR saves 'W', 'STATUS',
> 'FSR' etc. into temp variables that are defined in Bank 0.
The W save area needs to be either reserved at the same offset in all banks,
or reserved in the unbanked memory many PICs have in the last 16 bytes of
each bank. I do the latter. The remaining state can be saved in a
particular bank because STATUS can be altered after W is saved and STATUS
then moved into W. I put the save area for the other state in bank 0 so
that the new bank can be set in the ISR with the single instruction CLRF
STATUS.
There is no need to reinvent the framework for an interrupt service routine.
I believe there are several examples out there, including the QQQ_INTR.ASPIC
module of my PIC development environment at http://www.embedinc.com/pic.
All the state save/restore code is already there, and even automatically
configures itself per machine as to whether PCLATH is saved/restored. It
also allows you to set a single assembly time switch at the top to indicate
whether FSR should be saved/restored in the interrupt service routine (it
only needs to be if FSR is used in the ISR).
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com