I am using CCS, I need to enter a loop, do the loop until the interrupt. Exit the loop, do whatever, then
restart the loop.
What is the best way to exit the loop in the middle of the loop, regardless of the status of that loop?
SETUP_TIMER_0(100) //start timer 0 at 100
PART_1
DOTHIS
COUNT_10
GOTO PART_2
PART_2
DOTHAT
COUNT_10
GOTO PART_1
INT_ON_TIMER_0 //interrupt on overflow
? //Must exit PART_1 and PART_2
//in order to restart from beginning of PART_1
> I am using CCS, I need to enter a loop, do the loop until the
> interrupt. Exit the loop, do whatever, then restart the loop. What is
> the best way to exit the loop in the middle of the loop, regardless of
> the status of that loop?
I'd set a global variable flag in the interrupt service routine and check
it in the loop, then use break if the flag is set. I assume you'll be
using something other than goto for your loops...
while (1) {
while (1) {
if (FLAG) break;
}
}
If you can wait to exit the loop at the end of the current iteration, you
could use 'while (!flag) {...}' and clear the flag in the interrupt
routine.
while (1) {
while (!flag) {
loop1...
loop2...
}
}
Dale
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
> I am using CCS, I need to enter a loop, do the loop until the
> interrupt. Exit the loop, do whatever, then restart the loop.
> What is the best way to exit the loop in the middle of the loop,
> regardless of the status of that loop?
Since you mention CCS, I assume you're talking C.
2 statements for getting out of 'for' and 'while' loops are:
break - exits the loop immediately
continue - skips the rest of the loop and executes the conditional that
controls the loop
It's possible that you can accomplish what's in the pseudo-code without
either - it depends on whether parts 1 & 2 truly need to stop in the
middle of what they are doing, how involved they are, if this is the
only thing happening (the basis for the 'master' while(1) loop), etc.:
while(1)
{
part_1();
part_2();
if (int_flag)
{
int_flag = 0;
part_3();
}
}
the timer_0 isr sets int_flag
>> pseudo-code from original post:
SETUP_TIMER_0(100) //start timer 0 at 100
PART_1
DOTHIS
COUNT_10
GOTO PART_2
PART_2
DOTHAT
COUNT_10
GOTO PART_1
INT_ON_TIMER_0 //interrupt on overflow
? //Must exit PART_1 and PART_2
//in order to restart from beginning of PART_1
PART_3
DOWHATEVER
GOTO PART_1
<<
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
> -----Original Message-----
> On Wed, 17 Apr 2002, Gordon Varney wrote:
>
> > I am using CCS, I need to enter a loop, do the loop until the
> > interrupt. Exit the loop, do whatever, then restart the loop. What is
> > the best way to exit the loop in the middle of the loop, regardless of
> > the status of that loop?
>
I am not sure that a C Interrupt will be fast enough.
This has some potential. I may be able to pull this off in assembly.
If I write the loop functions in ASM and the rest of the code in C.
It might be do-able.
> I'd set a global variable flag in the interrupt service routine and check
> it in the loop, then use break if the flag is set. I assume you'll be
> using something other than goto for your loops...
>
> while (1) {
> while (1) {
> if (FLAG) break;
> }
> }
>
No, It will be very important to stop the loop immediately.
>
> If you can wait to exit the loop at the end of the current iteration, you
> could use 'while (!flag) {...}' and clear the flag in the interrupt
> routine.
>
> while (1) {
> while (!flag) {
> loop1...
> loop2...
> }
> }
>
> Dale
Am I missing something, or isn't that the whole point of an ISR? To handle
interrupts immediately so the body of your code doesn't have to worry about
it? Why can't your ISR handle the interrupt (or at least jump to a
function that can) in the first place?
Or is there some limitation of the C compiler you're using?
Tim Massey
P.S.: I'm new to PIC's. I understand the value of C compilers on "normal"
computers, especially computers like IBM PC's, with 10 different memory
models, 100 different hardware devices to manage, 1,000 different ASM
instructions and 1,000,000 lines of code. But on a PIC? Why do people
choose C over straight ASM when you're almost always talking about just a
couple of k of code and few hardware devices to worry about? Or am I just
not sophisticated enough yet?
T.J.M.
Gordon Varney
<gordonv@IAMNE To: spam_OUTPICLISTTakeThisOuTMITVMA.MIT.EDU
E.COM> cc:
Sent by: pic Subject: Re: [PIC]:c interrupts
microcontrolle
r discussion
list
<PICLIST@MITVM
A.MIT.EDU>
04/17/02 05:23
PM
Please respond
to pic
microcontrolle
r discussion
list
> I'd set a global variable flag in the interrupt service routine and check
> it in the loop, then use break if the flag is set. I assume you'll be
> using something other than goto for your loops...
>
> while (1) {
> while (1) {
> if (FLAG) break;
> }
> }
>
No, It will be very important to stop the loop immediately.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
I really don't understand what you are trying to do. Can you state more of
your requirements? Are you trying to do ASM in C?
Do you want to stick with strictly software interrupts?
With HiTechC, I write a function like this:
void interrupt isr(void)
{
}
And when the hardware interrupt is called, it goes there right away, with
mostly a branch penalty and a few context save instructions. If that's not
immediate enough, ASM won't help much there. And when the interrupt is
done, it will pick back up right where it left off, with only a very few
instructions of penalty to restore everything. Of course, the code in the
chip must enable the interrupts, and the ISR code must clear the particular
device's interrupt flag before it will re-interrupt. You can play a little
with turning on and off the interrupt enable depending on what part of your
code you are in.
> P.S.: I'm new to PIC's. I understand the value of C compilers on
"normal"
> computers, especially computers like IBM PC's, with 10 different memory
> models, 100 different hardware devices to manage, 1,000 different ASM
> instructions and 1,000,000 lines of code. But on a PIC? Why do people
> choose C over straight ASM when you're almost always talking about just a
> couple of k of code and few hardware devices to worry about? Or am I just
> not sophisticated enough yet?
I used to think so too, but going C eases code maintainance. Logical errors
in ASM are a pain in the butt, it seems every time I make an "if"
equivalent, I inadvertently code the inverted logic that I didn't intend. A
few K of code still can mean thousands of lines of this or worse:
btfss value, bit
goto else
if instruction
goto endif
else instruction
endif
versus:
if (bit == 1)
{instruction}
else {instruction}
This comparison gets worse when comparing multi-byte variables.
Floating point and bank handling can be painful in ASM too. C isn't the
panacaea, but I've found it to be useful and easier to work with in general.
There are cases where ASM is better, but in all, project requirements,
coding time and maintainance must be considered in choosing one language
over another.
I still suggest that people learning PICs and microcontrollers should learn
ASM first to understand the architecture and so on, after a while it might
seem like spinning wheels.
Jeff
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
Tim,
I use C to decrease the time spent programming. I can program in ASM and C, however I am a hardware engineer, and my
programming skills are not as efficient as someone that will program all day.
I need to use the ISR to exit out of the loop, not post pone it. All I am asking is, is there a way to use the ISR to
stop the loop, in only a few instructions. Keeping the loop in tack is not important. I will call the loop again when I
am ready.
> Hello!
>
> Am I missing something, or isn't that the whole point of an ISR? To handle
> interrupts immediately so the body of your code doesn't have to worry about
> it? Why can't your ISR handle the interrupt (or at least jump to a
> function that can) in the first place?
>
> Or is there some limitation of the C compiler you're using?
>
> Tim Massey
>
> P.S.: I'm new to PIC's. I understand the value of C compilers on "normal"
> computers, especially computers like IBM PC's, with 10 different memory
> models, 100 different hardware devices to manage, 1,000 different ASM
> instructions and 1,000,000 lines of code. But on a PIC? Why do people
> choose C over straight ASM when you're almost always talking about just a
> couple of k of code and few hardware devices to worry about? Or am I just
> not sophisticated enough yet?
> T.J.M.
>
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
I am programming in C. I have a clock out on one pin. One cycle of this clock is .000370s. This means that I have
approximately 370 instructions to do other functions. No matter what, when the period is over I need to stop the loop
that is running. Restart the timer for another period of 370us. Determine the status of the controller, and restart the
loop. I can write this in ASM to have better control. However, I might be able to do this in C if I can figure out how
to exit a loop fast enough in C. I don't necessarily need to save the information from the loop, since I can reenter the
loop from the beginning later.
> I really don't understand what you are trying to do. Can you state more of
> your requirements? Are you trying to do ASM in C?
>
> Do you want to stick with strictly software interrupts?
>
> With HiTechC, I write a function like this:
>
> void interrupt isr(void)
> {
> }
>
> And when the hardware interrupt is called, it goes there right away, with
> mostly a branch penalty and a few context save instructions. If that's not
> immediate enough, ASM won't help much there. And when the interrupt is
> done, it will pick back up right where it left off, with only a very few
> instructions of penalty to restore everything. Of course, the code in the
> chip must enable the interrupts, and the ISR code must clear the particular
> device's interrupt flag before it will re-interrupt. You can play a little
> with turning on and off the interrupt enable depending on what part of your
> code you are in.
>
> Jeff
>
> instructions and 1,000,000 lines of code. But on a PIC? Why do people
> choose C over straight ASM when you're almost always talking about just a
> couple of k of code and few hardware devices to worry about? Or am I
just
> not sophisticated enough yet?
> T.J.M.
When you don't need the all out speed that assembly may give you C
development may be faster. Also, if you are experimenting with control
algorithms it may be faster. Then there's the real world case where the
customer isn't sure of what they really want the product to do but they are
sure that the end date for the project absolutely can not change--you need
to develop as efficiently as possible.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
C compilers for microcontrollers are great. For very long complex
program it is very hard to make it in assembly but with c language it
works first time. I spent weeks to do project with assembly language and
had lots of hardship to make it work, then I done it with c language, it
took me 1 day to finish and added lots of extra intelligent stuff which
will take me months to do in assembly.
C code is very efficient and close to assembly language, the compiler
utilizes memory with extreme efficiency and the code u generate is
portable , u can change from 1 microcontroller to another with minimum
code modifications.
Code optimization reduces code size and increases speed for the
generated program.
You can make the ISR set a flag which is checked in the loop, when the
flag is set you break the loop and clear the flag and so on.
If nothing critical has to keep on running, why not kill it? Go to sleep
or suspend in a loop until the watchdog resets the device? This way
you'll be shure not a single instruction will be executed after the
interrupt. With the non-destructive memory of the PIC you'll still be
able to save whatever has been done before the interrupt. (Don't know if
this asumption is truly correct though.)
> P.S.: I'm new to PIC's. I understand the value of C compilers on
"normal"
> computers, especially computers like IBM PC's, with 10 different memory
> models, 100 different hardware devices to manage, 1,000 different ASM
> instructions and 1,000,000 lines of code. But on a PIC? Why do people
> choose C over straight ASM when you're almost always talking about just a
> couple of k of code and few hardware devices to worry about? Or am I just
> not sophisticated enough yet?
I've done a lot of PIC projects professionally, and have always used
assembler on PICs for exactly the reasons you state.
People that use compilers claim it lets them "develop faster" without having
to sweat the details. Personally I think this is bunk, and that the real
reason is they just aren't that good at assembler and don't want to (or
can't) learn it. People don't want to admit this, so they come up with all
kinds of reasons why using a compiler is "better". Either way you still
have to have a good grasp of what the hardware is doing. A compiler on a
small system will only hide the hardware from you to an extent, and sooner
or later you will get into trouble if you don't understand what is going on
at the instruction level.
Properly written assembler can be just as fast to write and maintainable as
compiled code, but leaves no doubt what is going on at the instruction
level. Improperly written code is useless no matter what language it is
written in. Unfortunately, 99% of all code out there I've seen is poorly
written.
Beware that this is a religious issue with many people. I know I'm going to
get the usual hate mail for saying this. Oh well. Watch the flood of
indignant responses, but keep in mind the real reason behind the protests.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
> I really don't understand what you are trying to do. Can you state more
of
> your requirements? Are you trying to do ASM in C?
>
> Do you want to stick with strictly software interrupts?
>
> With HiTechC, I write a function like this:
>
> void interrupt isr(void)
> {
> }
>
> And when the hardware interrupt is called, it goes there right away, with
> mostly a branch penalty and a few context save instructions.
It can appear that way at the C source level, but compilers often
save/restore lots of stuff in an interrupt routine.
> If that's not
> immediate enough, ASM won't help much there.
Actually it might. Have a look at the generated instructions before you say
that. Not all compilers are equal, and various settings can cause lots of
stuff to get hidden in an interrupt routine.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
> I use C to decrease the time spent programming. I can program in
ASM and C, however I am a hardware engineer, and my
> programming skills are not as efficient as someone that will program all
day.
>
> I need to use the ISR to exit out of the loop, not post pone it. All I am
asking is, is there a way to use the ISR to
> stop the loop, in only a few instructions. Keeping the loop in tack is not
important. I will call the loop again when I
> am ready.
If you are willing to "restart" the code, then the interrupt doesn't have to
return. Just re-enable GIE and jump to restart. In otherwords you can
think of an interrupt as a GOTO 4 as long as you don't intend to do a RETURN
to anything before the interrupt. I don't know if this fits your situation,
but I think I've used this trick twice in about 30 PIC projects.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
I know this discussion is pointless, nevertheless:
A higher language can be very fortunate for certain projects. I'm shure
not going to try to solve some problem in ASM if I only have to read in
an ASCII character string, convert it to 16 bit floats, do a bunch of
gonio or other math and put some digital outputs high or low depending
on the calculations. On the other hand, I would be very suspicious if I
see a high frequency A/D conversion or critical timed interrupt routine
in C code.
Bottom line: ASM is good for some, C is good for other. No matter what
your skill is. A crappy C programmer won't make great ASM code and vice
versa. I agree that 99% of the code you see is crappy, but almost all
code written by someone else is crappy. (Think of it, 1% of the world's
code base is a large chunk to write Olin :)
Last $0.02: I've written a program in ASM of about 3K. It took me about
2 or 3 months. When I found out about the C compilers and finally
purchased one, I really kicked myself in the head for not doing it
earlier. In the first 5 minutes after installation I recreated something
that took me over a _week_ in ASM.
I agree with Olin -- bad code is bad code, regardless of the language -- but
well-written assembly is the ultimate achievement (Not that I have perfected
the task. Still have a ways to go!).
It's possible that the approach you are taking that requires this type
of solution might be better coded a totally different way; I don't know
without being your Systems Analyst.
However, what you are asking is easy on non-PIC systems where access to
the stack pointer is possible. Perhaps an explanation will help you
come up with a solution that works for you.
When an interrupt occurs, the program counter is pushed onto the
hardware stack. On some processors other registers like processor status
are also pushed. Inside the interrupt routine, your code will save any
additional registers that may be used within the routine.
When the interrupt routine is done, it pops these values off the stack
and executes a return from interrupt which normally then re-enables the
interrupt code after the return instruction completes. That avoids an
interrupt occuring during the return instruction. Your applications
continues as if it had never been interrupted.
Inside your interrupt routine, on a more powerful processor, you can
save a copy of the status flags and then trash the stack back up to a
particular point by loading the stack pointer with a value saved in a
global variable. If the stack at this point has been properly
conditioned, the return from the interrupt routine will take you back
to a point before you called the loop code you were executing at the
time of the interrupt. The code at the point that you end up, (you are
in effect branching to), has to be robust enough to not expect
registers to hold certain values. Variables used at that point are best
named volatile so that the compiler loads them from RAM again.
A GOTO from inside a nested series of subroutine calls to a place
outside of the nesting does the same sort of thing. The GOTO label is a
location where the stack pointer and the code address is saved. It's
why in PASCAL, the goto's are so difficult to implement, all that
stuff saved on the stack. Just imagine doing a goto into a nested
structure that then has to do a return to get out. A return to where?
It's why GOTOs aren't really allowed in structured programming. Hard to
implement and can make messy, yucky hard to follow code.
What you are asking is for a GOTO from inside a nested function (the
interrupt routine) to some outer higher level. A high level language
that supports GOTO upwards could support this but the underlying
processor has to be able to do it too by manipulating the stack. That's
why a PIC C can never be ANSI compatible; you don't have access to the
stack pointer or the stack.
In your case, you probably have to do your processing inside the
interrupt routine, perhaps enabling interrupts while inside it to handle
other priority events. Just remember, the stack on a PIC isn't very
big and can byte you in the butt really easily.
At 04:58 PM 4/17/02 -0500, Gordon Varney wrote:
>Tim,
>
>I need to use the ISR to exit out of the loop, not post pone it. All I am
>asking is, is there a way to use the ISR to
>stop the loop, in only a few instructions. Keeping the loop in tack is not
>important. I will call the loop again when I
>am ready.
Do you even need an ISR? Can you just poll the appropriate flag (s) within
your loop and break out when the flag has become set?
In other words, if you need interrupts for only this purpose and all the
ISR is going to do is set some flag that the foreground can see, don't even
bother with an ISR.
If the issue is how to convince the compiler that you want to break out of
the loop NOW, consider coding that loop in assembler and dropping it into
the rest of your C code. That way, differences between compiler
implementations won't cause you fits.
Celebrating 18 years of Engineering Innovation (1984 - 2002)
.-. .-. .-. .-. .-. .-. .-. .-. .-. .-
`-' `-' `-' `-' `-' `-' `-' `-' `-'
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
----- Original Message -----
From: Olin Lathrop <.....olin_piclistKILLspam.....EMBEDINC.COM>
> I've done a lot of PIC projects professionally, and have always used
> assembler on PICs for exactly the reasons you state.
>
> People that use compilers claim it lets them "develop faster" without
having
> to sweat the details. Personally I think this is bunk, and that the real
> reason is they just aren't that good at assembler and don't want to (or
> can't) learn it. People don't want to admit this, so they come up with
all
> kinds of reasons why using a compiler is "better". Either way you still
> have to have a good grasp of what the hardware is doing.
Well, I wrote a well-functioning 8,000 line ASM program and decided I had
better things to do with my life than deal with pages of opcodes. What do
you think my real reason is, if you think I am making up reasons? I KNOW
how the chip works. I also know how an internal combustion engine works and
how to rebuild them, but I left that job behind for a reason.
>A compiler on a
> small system will only hide the hardware from you to an extent, and sooner
> or later you will get into trouble if you don't understand what is going
on
> at the instruction level.
>
> Properly written assembler can be just as fast to write and maintainable
as
> compiled code,
Care to write a tutorial?
> but leaves no doubt what is going on at the instruction level.
Gee, read the opcode output if something is in doubt.
>Improperly written code is useless no matter what language it is
> written in. Unfortunately, 99% of all code out there I've seen is poorly
> written.
Of course, but then, everyone seems to have their own little idea of what is
"properly written", and as such, standards are often in direct conflict.
I am sure you are different, the problem is that everyone seems to have this
"one size fits all" concept. For one, I get confused when all the opcodes
blend in to each other. My mind probably doesn't work like yours, but I
don't like the idea that someone is insinuating that I or anyone else is
stupid for preferring not to deal with ASM once a good understanding is
attained.
Jeff
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
What exactly are you trying to do? Stop the processing in C as soon as an
interrupt occurs?
The only thing you can reasonably do is repeatedly check the flag in the "C"
code. This will usually come down to just two instructions, so it isn't too
bad to sprinkle them throughout the code:
while (1)
{
while (1)
{
do_a_little();
if (flag)
break;
do_a_little_more();
if (flag)
break;
....etc..
}
flag = 0;
do_whatever_after_the_interrupt();
}
Note: you can even check the flag within called functions and exit them
early:
void do_a_little(void)
{
a = b+c;
if (flag)
return;
b = c+d;
if (flag)
return;
}
The latency between the interrupt and leaving the loop depends on how
closely you sprinkle the checks on flag.
There is one other crazy idea you can use:
void main_loop_func()
{
if (do_whatever_flag)
do_whatever();
while (1)
{
do whatever you want without worrying about checking the flag
}
}
And then the interrupt handler looks like this:
int_handler:
set do_whatever_flag
clear interrupt cause
set GIE flag
jmp to loop_func
This technique takes advantage of the fact the the stack on all pics (except
18C/F) are circular. If you use this technique then you can never return
from main_loop_func() because the stack no longer aligns.
On an 18C/F, where the stack is accesible, you could get even fancier:
I'm just the opposite: I'm a programmer who's new to hardware! :)
There are two choices in breaking out of the loop:
1) Within the loop examine a variable set by the ISR
2) Within the ISR set the PC to another location (but I'm not sure about
how to clean up the stack on a PIC: there aren't POP instructions)
If you need better than one-check-for-interrup-per-loop resolution, you
will have to check for the interrupt more often:
As for option two, I don't think it's an option for a PIC, but you could do
it on a "normal" computer...
Is there a more creative solution I'm missing?
Tim Massey
Gordon Varney
<gordonv@IAMNE To: EraseMEPICLISTspam_OUTTakeThisOuTMITVMA.MIT.EDU
E.COM> cc:
Sent by: pic Subject: Re: [PIC]:c interrupts
microcontrolle
r discussion
list
<PICLIST@MITVM
A.MIT.EDU>
04/17/02 05:58
PM
Please respond
to pic
microcontrolle
r discussion
list
Tim,
I use C to decrease the time spent programming. I can program in
ASM and C, however I am a hardware engineer, and my
programming skills are not as efficient as someone that will program all
day.
I need to use the ISR to exit out of the loop, not post pone it. All I am
asking is, is there a way to use the ISR to
stop the loop, in only a few instructions. Keeping the loop in tack is not
important. I will call the loop again when I
am ready.
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
> I agree with Olin -- bad code is bad code, regardless of the language --
but
> well-written assembly is the ultimate achievement (Not that I have
perfected
> the task. Still have a ways to go!).
A few achievemenst beyond that ultimate achievement:
- a good algorithm in hardware, software is for sissies
- a compiler that generates code that is good enough to stop the
asm-versus-hll discussion forever....
Wouter van Ooijen
--
Van Ooijen Technische Informatica: http://www.voti.nl
Jal compiler, Wisp programmer, WLoader bootloader, PICs kopen
Use what you like: smoke, drums, assembly, C , Cobol whatever, the good
one is the one you fell confortable using
Regards
Horta
> instructions and 1,000,000 lines of code. But on a PIC? Why do people
> choose C over straight ASM when you're almost always talking about just a
> couple of k of code and few hardware devices to worry about? Or am I
just
> not sophisticated enough yet?
> T.J.M.
> > -----Original Message-----
> > On Wed, 17 Apr 2002, Gordon Varney wrote:
> >
> > > I am using CCS, I need to enter a loop, do the loop until the
> > > interrupt. Exit the loop, do whatever, then restart the loop. What is
> > > the best way to exit the loop in the middle of the loop, regardless of
> > > the status of that loop?
> >
>
> I am not sure that a C Interrupt will be fast enough.
Umm... there's no difference betwen a C interrupt and any other kind.
Code's code, it works the same. Once it compiles, it's binary code just
like anything else.
> This has some potential. I may be able to pull this off in assembly.
> If I write the loop functions in ASM and the rest of the code in C.
> It might be do-able.
I'm not seeing where this would make a difference. Either way your main
loop has to know when it's been interrupted. I don't know what
specifically your main code is doing, but an interrupt may or may not
be the answer you're looking for.
If all else fails and you need to make sure that not one more instruction
of the main loop is executed after an interrupt, there *is* a goto
function in C, though it's generally not used much.
> Gordon,
>
> What exactly are you trying to do? Stop the processing in C as soon as an
> interrupt occurs?
>
> The only thing you can reasonably do is repeatedly check the flag in the "C"
> code. This will usually come down to just two instructions, so it isn't too
> bad to sprinkle them throughout the code:
>
> while (1)
> {
> while (1)
> {
> do_a_little();
> if (flag)
> break;
> do_a_little_more();
> if (flag)
> break;
> ....etc..
> }
> flag = 0;
> do_whatever_after_the_interrupt();
> }
>
> Note: you can even check the flag within called functions and exit them
> early:
>
> void do_a_little(void)
> {
> a = b+c;
> if (flag)
> return;
> b = c+d;
> if (flag)
> return;
> }
>
> The latency between the interrupt and leaving the loop depends on how
> closely you sprinkle the checks on flag.
>
> There is one other crazy idea you can use:
>
> void main_loop_func()
> {
> if (do_whatever_flag)
> do_whatever();
>
> while (1)
> {
> do whatever you want without worrying about checking the flag
> }
> }
>
> And then the interrupt handler looks like this:
>
> int_handler:
> set do_whatever_flag
> clear interrupt cause
> set GIE flag
> jmp to loop_func
>
> This technique takes advantage of the fact the the stack on all pics (except
> 18C/F) are circular. If you use this technique then you can never return
> from main_loop_func() because the stack no longer aligns.
>
> On an 18C/F, where the stack is accesible, you could get even fancier:
>
> void driver_func()
> {
> main_loop_func();
> do_whatever();
> }
>
> main_loop_func()
> {
> main_loop_stack_ptr = STKPTR;
>
> while (1)
> {
> do whatever you want without worrying about interrupts at all
> }
> }
>
> int_handler:
>
> ---clear interrupting condition---
> movf main_loop_stack_ptr,W
> movwf STKPTR
> retfie ; returns to caller of main_loop_func() !!!
>
> Bob Ammerman
> RAm Systems
>
> --
> http://www.piclist.com hint: PICList Posts must start with ONE topic:
> [PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
>
>
>
I condede. In retrospect, the real 'ultimate' is when somebody does
something novel/refreshing with a microcontroller -- regardless of their
method. That is, the ends are more important than the means.
> People that use compilers claim it lets them "develop faster" without having
> to sweat the details. Personally I think this is bunk, and that the real
> reason is they just aren't that good at assembler and don't want to (or
> can't) learn it. People don't want to admit this, so they come up with all
> kinds of reasons why using a compiler is "better". Either way you still
> have to have a good grasp of what the hardware is doing. A compiler on a
> small system will only hide the hardware from you to an extent, and sooner
> or later you will get into trouble if you don't understand what is going on
> at the instruction level.
Hmm, yes, you're quite right. We're all part of a vast conspiracy to
conceal the little-known but obvious fact that all C programmers are
incompetent, lazy people wuo lie to cover their tracks. Are we happy now?
> Properly written assembler can be just as fast to write and maintainable as
> compiled code, but leaves no doubt what is going on at the instruction
> level.
Properly written C code can be written far faster by someone more
comfortable writing C code than assembler. The compiler also generates an
ASM listing, so the programmer can -- and should -- review what the
compiler is doing as a sanity check. I for one am perfectly capable of
programming a PIC in asembly language, but compared to many other
processors I've used it's simply a colossal pain in the ass. I use C
instead of assembler because I don't have to deal with memory allocation,
bank switching or any of the other nonsense, it's got a sane syntax, and
dealing with multibyte and floating point variables is a simple matter of
writing the logic without having to hash out the low-level mechanics of
it. I know I can trust the compiler to correctly perform these operations
because I've tested them. I can, if needed, break a C statement down to
smaller component operations to gain finer control of what assembly code
is generated - but I very seldom need to do so. On the flip side, I'm not
using a PIC barely adequate for the task at hand, so getting every last
clock cycle or byte of memory out of it is not that critical. If I get to
that point, I know I'm using the wrong processor anyway.
> Improperly written code is useless no matter what language it is
> written in. Unfortunately, 99% of all code out there I've seen is
> poorly written.
By your standards, perhaps. Obviously by someone's standards 99% of it
is adequate for the task, delivered on time, and on budget. I think 99% of
all cars on the road are crap, too. Obviously they work for some people.
Have you considered that 99% of the code you look at is either something
you've been called in to fix, or was written by novices?
> Beware that this is a religious issue with many people. I know I'm going to
> get the usual hate mail for saying this. Oh well. Watch the flood of
> indignant responses, but keep in mind the real reason behind the protests.
Right, I keep forgetting - we're incompetent, lazy liars trying to mislead
people. Perhaps if your statements were not quite so narrow-minded and
patently offensive to anyone who happens to have a different point of view
than your own, you wouldn't get so many irritated responses.
At 12:51 AM 4/18/02 +0200, you wrote:
>I know this discussion is pointless, nevertheless:
<snip>
>Last $0.02: I've written a program in ASM of about 3K. It took me about
>2 or 3 months. When I found out about the C compilers and finally
>purchased one, I really kicked myself in the head for not doing it
>earlier. In the first 5 minutes after installation I recreated something
>that took me over a _week_ in ASM.
There are several things at work here:
1) The first time you do something a good part of the time is
used for design (data structures and algorithms). This is
independent of language. *Implementing* the design in pretty
much any procedural language from Postscript to Lisp to
PIC ASM is often a minority of the hours spent. Before I
used C directly, I tended to prototype and test complex
things in C. I have a library of C functions that simulates
things I normally write in ASM (integer math, in particular)
Using a cross compiler allows me to skip some of the
implementation in ASM step. Of course many things are still
best done in assembler, including many or most ISRs.
2) After doing years of work programming in ASM you'll accumulate
a good-sized library of functions that can be dropped into
projects. A kind of library comes with C, but you'll have
to learn to use and adapt it, plus many functions may have
to be written or re-written in C anyway (and you'll accumulate
a library of *those*).
3) A cross-compiler is an investment in time and dollars (there
are complexities there that are not present in ASM).
Chances are that if you do heavy-duty work in ASM you'll
need to invest in something like an emulator or ICD. This
is not quite as necessary in C.
4) If you ever have to do a project with another processor,
having used C will eliminate some drudgery, and a bit of
thought and planning. There are enough differences and
complexities between cross compiled Cs (even those that
try really hard to be ANSI-like) that there is still some
porting required, and translating ASM isn't really all
that difficult once you overcome architectural
differences.
5) If you can drop in complex code (such as a TCP/IP stack
or MODBUS implementation written in C), only a masochist
would spend weeks or months re-writing that in assembler
to get a small improvement in performance. The same holds
true if you have "drop-in" assembler code available.
6) The MSP430, MC68HC908, PICS etc. are available with 60K+ of
FLASH (bytes). I really don't want to deal with more than
about 16K of ASM again. Life is too short.
7) I find clients insisting on C (and sometimes asking for
other HLLs) because they want to be able to maintain
programs themselves. There is some validity to this
point of view. Also, when macros are used heavily (in any
language), it starts to resemble some language that only
the author of the macros is familiar with.
8) This has been said before, but there can be enough of a
saving in code space and speed to allow a cheaper micro to
be used. Irrelevant in small quantities, may be very
important in larger quantities (depending on the price
structure of the micro manufacturer). On the opposite side,
a bit faster to market may mean a stronger position and
higher sales and profits. It may not be an either-or, but
a first this, then that situation. In some industries a
6 month delay to market means the *total* life-cycle profits
are halved!
> GEE!
>
> PANDORA'S BOX IS WIDE OPEN NOW
>
> Please LORD, be mercifull.
>
>
>
> Use what you like: smoke, drums, assembly, C , Cobol whatever,
> the good
> one is the one you fell confortable using
>
>
> Regards
> Horta
>
________________________________________________________________
GET INTERNET ACCESS FROM JUNO!
Juno offers FREE or PREMIUM Internet access for less!
Join Juno today! For your FREE software, visit:
dl.http://www.juno.com/get/web/.