Searching \ for '[PIC]MPLAB C30 beginners question' 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/begin.htm?key=mplab
Search entire site for: 'MPLAB C30 beginners question'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]MPLAB C30 beginners question'
2005\12\06@231114 by Stephen D. Barnes

picon face
Hi all,
When I simulate the following code in MPLAB,

int test;
/************* START OF MAIN FUNCTION ***************/
int main ( void )
{
   test = 1;
   while (test < 10)
   {
       test ++;
   }
}

when the last bracket is reached, a software reset occurs. Why?

--
Regards,
Stephen D. Barnes

2005\12\06@233845 by Lee Jones

flavicon
face
> When I simulate the following code in MPLAB,
>
> int test;
> /************* START OF MAIN FUNCTION ***************/
> int main ( void )
> {
>     test = 1;
>     while (test < 10)
>     {
>         test ++;
>     }
> }
>
> when the last bracket is reached, a software reset occurs. Why?

In a "normal" C environment, main() is "called" by the overlying
operating system and there is an implied return following the end
of main().  Roughly, this is handled through cooperation between
the operating system's process creation and the C run-time library.

An embedded system does not have an overlying operating system
(usually, Microchip certainly doesn't provide one).

At the end of main(), the C run-time has only two choices:
(1) branch to the CPU's reset vector or (2) continue executing
instructions (random bit patterns that may frequently be 0xFF)
that follows main() in memory.  Apparently, MPSIM chose to branch
to the reset vector.

                                               Lee Jones

2005\12\06@234122 by Douglas Wood

picon face
The last bracket, in the main() function, is equivalent to executing the END
statement in BASIC: the program ends. On a PC, this action would return
control to the operating system (e.g., DOS, etc.). In an embedded system,
there is typically nothing to "go back to"; in the case of the PIC, the
compiler places a jump (goto) at the last bracket, forcing the PIC to jump
to the beginning of the C startup code.

Douglas Wood

{Original Message removed}

2005\12\06@235245 by Stephen D. Barnes

picon face
Lee Jones wrote:

>In a "normal" C environment, main() is "called" by the overlying
>operating system and there is an implied return following the end
>of main().  Roughly, this is handled through cooperation between
>the operating system's process creation and the C run-time library.
>
>An embedded system does not have an overlying operating system
>(usually, Microchip certainly doesn't provide one).
>
>At the end of main(), the C run-time has only two choices:
>(1) branch to the CPU's reset vector or (2) continue executing
>instructions (random bit patterns that may frequently be 0xFF)
>that follows main() in memory.  Apparently, MPSIM chose to branch
>to the reset vector.
>
>                                                Lee Jones
>
>  
>
OK, I follow you...but this leads to two more questions!

  1. In assembly, when the end of the program is reached, "end" causes
     execution to terminate as I understand it. What is the equivalent
     in C?
  2. If I compile the C code in the previous post and load it into a
     PIC, will the PIC continuously reset like the simulator, as I    
     assume it would from your explanation?

Please note that I do realize that for most code to be useful in a PIC,
it should be continouosly executing....not just a one pass piece of
software. The code in question was my first venture into embedded C and
the result worked but the behavior surprised me!

--
Regards,
Stephen D. Barnes

2005\12\06@235357 by Stephen D. Barnes

picon face
I previously wrote:

>When I simulate the following code in MPLAB,

>int test;
>/************* START OF MAIN FUNCTION ***************/
>int main ( void )
>{
>    test = 1;
>    while (test < 10)
>    {
>        test ++;
>    }
>when the last bracket is reached, a software reset occurs. Why?

What I mean by a software reset may be clarified by the following which is displayed in MPLAB's output window:

CORE-W0008: Software Reset Instruction called

What is causing this? I have read and read and cannot find out why!


Regards,
Stephen D. Barnes

2005\12\06@235717 by Stephen D. Barnes

picon face
Douglas Wood wrote:

>The last bracket, in the main() function, is equivalent to executing the END
>statement in BASIC: the program ends. On a PC, this action would return
>control to the operating system (e.g., DOS, etc.). In an embedded system,
>there is typically nothing to "go back to"; in the case of the PIC, the
>compiler places a jump (goto) at the last bracket, forcing the PIC to jump
>to the beginning of the C startup code.
>
>Douglas Wood
>
>  
>

Ok, that make sense and answers one of the questions I raised in a reply to Lee Jones which apparently has not hit the list yet.

Thanks


--
Regards,
Stephen D. Barnes

2005\12\07@022833 by Stephen D. Barnes

picon face
Lee Jones wrote:

{Quote hidden}

Hey, after reading it two times I finally saw what I had been reading,
and with your explanation and the docs, I won't soon forget it.
In DS51284D-page 63 (C30_Compiler Users Guide) it states,
quote:
   4. The function main is called with no parameters.
   5. If main returns, the processor will reset.
unquote.
I did not see the forrest for the trees!

--
Regards,
Stephen D. Barnes

2005\12\07@024804 by WH Tan

flavicon
face
Hello Stephen,

Have a look in the file crt0.s.  It should be located in <C30
directory>/src/pic30. This is one of the source to make the library file
"libpic30-coff.a", which you put it in your project tree "Library Files"!

Best regards,

WH Tan

> {Original Message removed}

2005\12\07@031122 by Wouter van Ooijen

face picon face
> When I simulate the following code in MPLAB,
>
> int test;
> /************* START OF MAIN FUNCTION ***************/
> int main ( void )
> {
>     test = 1;
>     while (test < 10)
>     {
>         test ++;
>     }
> }
>
> when the last bracket is reached, a software reset occurs. Why?

what would you expect to happen after your main() terminates? the first
thing I tell my embedded students is that an embedded main() never
terminates!

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@032239 by Stephen D. Barnes

picon face
Wouter van Ooijen wrote:

{Quote hidden}

OK...pretend I am one of your students as I really am at the beginners
level with C30. If an embedded main() never terminates, why is the
software reset occurring? My next question would be, how do I keep the
"main program loop" running. In assembly,
I would have a label main: at the beginning of my user code and a goto
main and the end of my user code to ensure that the code kept running.
My current problem is that I do not understand how this is traditionally
accomplished in C. Any help is appreciated!

--
Regards,
Stephen D. Barnes

2005\12\07@034931 by William Chops Westfield

face picon face
On Dec 7, 2005, at 12:24 AM, Stephen D. Barnes wrote:

> If an embedded main() never terminates,
> why is the software reset occurring?

A C compiler inserts code in your program that does initialization
(the "crt0" that someone mentioned), calls main() as a function with
the appropriate arguments (if any), and then cleans up.  In this case,
"cleaning up" apparently means executing a software reset instruction,
which is not at all a bad idea (if your processor HAS a reset
instruction!)

You should be able to see this by disassembling the code...


> how do I keep the "main program loop" running.

It depends on what you want it to do.  Most embedded programs will
have a natural loop that just never happens to exit.  You can
add one artificially if you want:

    main() {
        while (1) {
            /*
             * lots of code
             */
        }
    }

Or you can define a routine or loop at the end of your program
that does something specific OTHER than randomness:

   main() {
       /*
        * Lots of code
        */
       while (1);     /* Done; sit in tight loop forever */
   }

BillW

2005\12\07@040559 by Stephen D. Barnes

picon face
William Chops Westfield wrote:

{Quote hidden}

Now I understand! Thanks. Can you clarifiy what you mean by "Most
embedded programs will have a natural loop that just never happens to exit"?

--
Regards,
Stephen D. Barnes

2005\12\07@040642 by Wouter van Ooijen

face picon face
> OK...pretend I am one of your students as I really am at the
> beginners level with C30. If an embedded main() never terminates,
> why is the software reset occurring?

An embedded main *should* never terminate, that's your responsibility as
programmer. When a desktop main() terminates, control passes back to the
command interpreter, or to windows, or whatever has the control of your
PC. But on a PIC you and only you are in control. You should decide what
must happen when you are done, and you must code that in your main,
because there is nothing else.

So why exactly the software reset occurs is not realy interesting: it's
like asking 'how can using this uninitialised pointer screw up my code'.

> My next question would be, how do I
> keep the
> "main program loop" running. In assembly,
> I would have a label main: at the beginning of my user code
> and a goto
> main and the end of my user code to ensure that the code kept
> running.

void main( ){
  for(;;){
     // your code here
  }
}

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@041657 by Stephen D. Barnes

picon face
Wouter van Ooijen wrote:

{Quote hidden}

The reason the software reset happened was because I did not account for
termination of the main()! Thanks for posting the snippet showing me how
to avoid that.

--
Regards,
Stephen D. Barnes

2005\12\07@042015 by Wouter van Ooijen

face picon face
> A C compiler inserts code in your program that does initialization
> (the "crt0" that someone mentioned), calls main() as a function with
> the appropriate arguments (if any), and then cleans up.  In this case,
> "cleaning up" apparently means executing a software reset instruction,
> which is not at all a bad idea (if your processor HAS a reset
> instruction!)

The trouble here is that C does not define what an embedded (barew
metal) compiler should do after main(), so each compiler makes his own
choice. The two obvious choices are:
- restart
- sit in a tight loop
but there is no guarantee that a different compiler won't make a
different choice. So for this aspect you'd better not rely on the
compiler but insert the appropriate code yourself.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@042617 by Stephen D. Barnes

picon face
Wouter van Ooijen explained that the following code will prevent main() from terminating:

void main( ){
  for(;;){
     // your code here
  }
}

William Chops Westfield explained another method that also works:
    main() {
        while (1) {
            /*
             * lots of code
             */
        }
    }
What is the difference between the two? Any advantages of one method over the other?

--
Regards,
Stephen D. Barnes

2005\12\07@042813 by Wouter van Ooijen

face picon face
> Now I understand! Thanks. Can you clarifiy what you mean by "Most
> embedded programs will have a natural loop that just never
> happens to exit"?

(sideline) could *you* trim your reply a bit more? (trim == remove lines
from what you are replying to unless they are absolutely needed to
follow the discussion)

A typical embedded thing could be box with a battery. Reset occurs only
once in its lifetime, when the battery is inserted. If it's main()
terminates the thingy is dead. So there is apparently something that
thingy will do over and over. Maybe it's just cheking whether a button
is pressed and then sounding a melody, or something more complicated,
but the principle is the same: its task never ends.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@043618 by Stephen D. Barnes

picon face
Wouter van Ooijen wrote:

>(sideline) could *you* trim your reply a bit more? (trim == remove lines
>from what you are replying to unless they are absolutely needed to
>follow the discussion)
>
>  
>
No problem. I was getting carried away with what I was learning. I'll trim!

--
Regards,
Stephen D. Barnes

2005\12\07@074009 by Lee Jones

flavicon
face
>> In a "normal" C environment, main() is "called" by the overlying
>> operating system and there is an implied return following main()
>> An embedded system does not have an overlying operating system
>>
>> At the end of main(), the C run-time has only two choices:
>> (1) branch to the CPU's reset vector or (2) continue executing
>> instructions (random bit patterns that may frequently be 0xFF)
>> that follows main() in memory.  Apparently, MPSIM chose to branch
>> to the reset vector.

> OK, I follow you...but this leads to two more questions!
>
>    1. In assembly, when the end of the program is reached, "end"
>       causes execution to terminate as I understand it.  What is
>       the equivalent in C?

No.  In assembler, the END directive simply tells the assembler
program that no other textual instructions (opcodes & operands)
follow and to stop processing that source file.  It does not
cause the generation of any code nor does assembler provide a
run-time support structure (unless you write it).

"execution to terminate" implies that there is another process
on the CPU that can take control when your program abdicates it.
Small embedded systems don't have one.  Your program is the one
and only process tree.  If you stop supplying instructions (by
falling through the end of your program), the CPU may wind up
randomly executing anything anywhere in memory.

An embedded CPU can't really terminate unless you have some
hardware support to remove power from the CPU under control of
some code that you supply.

Sleep and Halt instructions simply postpone execution until an
external event wakes the CPU.  The reset instruction or a branch
to the reset vector changes the location where the CPU will fetch
its next instruction -- CPU always continues to execute something.


>    2. If I compile the C code in the previous post and load it into a
>       PIC, will the PIC continuously reset like the simulator, as I    
>       assume it would from your explanation?

Depends on the run-time library.  Usually, the compiler's default
run-time library is included in your program.  How it handles this
case depends on the compiler vendor.  You can modify the run-time
library to do whatever you feel is appropriate for your task.

                                               Lee Jones

2005\12\07@075611 by olin piclist

face picon face
Stephen D. Barnes wrote:
> int test;
> /************* START OF MAIN FUNCTION ***************/
> int main ( void )
> {
>    test = 1;
>    while (test < 10)
>    {
>        test ++;
>    }
> }
>
> when the last bracket is reached, a software reset occurs. Why?

Well what *should* it do when the top level MAIN returns?  This is something
that makes no sense in a microcontroller, so the compiler probably sticks a
RESET instruction or jump to 0 in there.

Short answer: Don't do that.

2005\12\07@080045 by olin piclist

face picon face
Stephen D. Barnes wrote:
>   1. In assembly, when the end of the program is reached, "end" causes
>      execution to terminate as I understand it.

No, no, no!  END is merely a directive that tells the assembler that no more
source lines follow.  READ THE MANUAL.  END has nothing to do with
execution.  Look at the assembly listing and you will see that no code is
generated for END.

Keep in mind you're on a microcontroller.  Even if you could say "end the
program", what exactly do you want the micro to do?  Shut off it's clock
until a hardware reset?  If so, you can get this with the SLEEP instruction.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2005\12\07@080438 by olin piclist

face picon face
Stephen D. Barnes wrote:
> What I mean by a software reset may be clarified by the following which
> is displayed in MPLAB's output window:
> CORE-W0008: Software Reset Instruction called
>
> What is causing this? I have read and read and cannot find out why!

This just goes to show the danger of trying to learn a PIC using a compiler.
People forget to think for themselves.

If you really want to see what it's doing, step in the program memory
window.  You can then see every instruction.  You will probably find that
the end of MAIN either executes a RESET, GOTO 0, or RETURN.  In the case of
RETURN you will probably find a RESET or GOTO 0 shortly after the return
point.  So instead of asking what's going on an people guessing, go look.
Why is this not the first thing you tried?

2005\12\07@080522 by Wouter van Ooijen

face picon face
> No.  In assembler, the END directive simply tells the assembler
> program that no other textual instructions (opcodes & operands)
> follow and to stop processing that source file.  It does not
> cause the generation of any code nor does assembler provide a
> run-time support structure (unless you write it).

In my classes this always causes confusion, beginners often assume 'end'
does something with the processor. I tell them the 'end'
pseudo-instruction is a leftover from the stone age, when programs were
punched on paper tape. It signalled to the computer that it had reached
the end of the tape. (right or wrong, this does get the message through)
It is totally unneeded in these times, but apparently nobody took the
step to remove it.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@083306 by Byron A Jeff

face picon face
On Wed, Dec 07, 2005 at 04:28:10AM -0500, Stephen D. Barnes wrote:
> Wouter van Ooijen explained that the following code will prevent main()
> from terminating:
>
> void main( ){
>   for(;;){
>      // your code here
>   }
> }
>
> William Chops Westfield explained another method that also works:
>     main() {
>         while (1) {
>             /*
>              * lots of code
>              */
>         }
>     }
> What is the difference between the two?

None. Both are infinite loops.

> Any advantages of one method over the other?

Nope. It's strictly a style issue. Functionally they are equivalent.

BAJ

2005\12\07@084605 by WH Tan

picon face
On 12/7/05, Wouter van Ooijen <spam_OUTwouterTakeThisOuTspamvoti.nl> wrote:

> It is totally unneeded in these times, but apparently nobody took the
> step to remove it.

Hello Wouter,

If I am asked whether the 'end' should be abandoned or not, I will
tend to put my vote against it!  Not really strong objection, but I
will say this:

In some circumstances, the 'end' directive may provide some help to
the programmer.  Say if you have a block of code that you're going to
append to your program, that code is just merely for testing purpose
to prove something, you know that it will eventually removed when
everything is done.  One might say that using conditional compile...
but I would prefer put those at the end of the file, just above the
'end'.  When I need to temporary remove the testing code, I can type
an 'end' before it!


Best regards,

--
WH Tan

2005\12\07@085407 by WH Tan

picon face
And to help other from guessing what is behind the scene of C30
initialization, here is the snip from "crt0.s":

__reset:

       mov      #__SP_init,w15    ; initialize w15
       mov      #__SPLIM_init,w0  ;
       mov      w0,_SPLIM         ; initialize SPLIM
       nop                        ; wait 1 cycle

       rcall    __psv_init        ; initialize PSV
       rcall    __data_init       ; initialize data
                                  ;  clears w0, so ARGC = 0

       .ifdef __ARGV
         rcall  __main            ; call two-parameter main() setup
       .else
         call  _main              ; call user's main()
       .endif

       .pword 0xDA4000            ; halt the simulator
       reset                      ; reset the processor



--
WH Tan

2005\12\07@090216 by Wouter van Ooijen

face picon face
>> (infinite loops)
>> What is the difference between the two?
>
> None. Both are infinite loops.
>
> > Any advantages of one method over the other?
>
> Nope. It's strictly a style issue. Functionally they are equivalent.

A specific compiler might generate more effecicient code for either the
one or the other. This depends on the specific compiler. But the
difference will be very small anyway, so you might as well forget it.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@090420 by Wouter van Ooijen

face picon face
> If I am asked whether the 'end' should be abandoned or not, I will
> tend to put my vote against it!  Not really strong objection, but I
> will say this:

IMHO you would be better of with a more general mechansim, like a
block-comment feature. It is a bit silly to force everyone to use the
otherwise useless (and confusing) 'end'.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\12\07@110100 by Dave Tweed

face
flavicon
face
Wouter van Ooijen <.....wouterKILLspamspam@spam@voti.nl> wrote:
> > > (infinite loops)
> > > What is the difference between the two?
> >
> > None. Both are infinite loops.
> >
> > > Any advantages of one method over the other?
> >
> > Nope. It's strictly a style issue. Functionally they are equivalent.
>
> A specific compiler might generate more effecicient code for either
> the one or the other. This depends on the specific compiler. But the
> difference will be very small anyway, so you might as well forget it.

It really shouldn't matter. For any given C expressions "a", "b", "c"
and "d",

  for (a; b; c) {
     d:
  }

is supposed to be nothing more than syntactic shorthand for

  a;
  while (b) {
     d:
     c;
  }

If "a", "b" and "c" are all empty (empty "b" is taken to evaluate to
"true"), then they are exactly equivalent.

However, some compilers are not able to recognize certain optimizable
relationships among "a", "b" and "c" unless the for() syntax is used.
I consider these to be second-class compilers. They may be quite usable,
but I tend to keep a close eye on the generated code throughout.

-- Dave Tweed

2005\12\07@141721 by Peter

picon face


> I would have a label main: at the beginning of my user code and a goto main
> and the end of my user code to ensure that the code kept running. My current
> problem is that I do not understand how this is traditionally accomplished in
> C. Any help is appreciated!

There are several ways. Basically any closed loop works. Examples:

main() {

       // run once here
forever:
       // code here
       goto forever;
}

main() {

       // run once here
       do {
               // code here
       } while(1);
}

main() {

       // run once here
       for (;;) {
               // code here
       }
}

//run once refers to code that is run only once (initialization etc)

Peter

2005\12\07@153740 by Stephen D. Barnes

picon face
Olin Lathrop wrote:

{Quote hidden}

BTW, I am not learning the PIC using a compiler...I started with the 16F
series two years ago and have used assembly the whole time. I progressed
into the 18F's earlier this year and am now working with dsPIC's. I am
interested in learning C to help out with various routines which I find
tedious in assembly. I am completely new to C and, yes a novice at PIC
assembly as well, but not quite a beginner!

--
Regards,
Stephen D. Barnes

2005\12\07@164140 by Byron A Jeff

face picon face
On Wed, Dec 07, 2005 at 03:00:11PM +0100, Wouter van Ooijen wrote:
> >> (infinite loops)
> >> What is the difference between the two?
> >
> > None. Both are infinite loops.
> >
> > > Any advantages of one method over the other?
> >
> > Nope. It's strictly a style issue. Functionally they are equivalent.
>
> A specific compiler might generate more effecicient code for either the
> one or the other.

True. A real dumb compiler might actually evaluate the 1 in the
while (1) statement.

> This depends on the specific compiler. But the
> difference will be very small anyway, so you might as well forget it.

Exactly.

BAJ

2005\12\08@080934 by WH Tan

picon face
On 12/7/05, Wouter van Ooijen <wouterspamKILLspamvoti.nl> wrote:
> > If I am asked whether the 'end' should be abandoned or not, I will
> > tend to put my vote against it!  Not really strong objection, but I
> > will say this:
>
> IMHO you would be better of with a more general mechansim, like a
> block-comment feature. It is a bit silly to force everyone to use the
> otherwise useless (and confusing) 'end'.
>

Hi Wouter,

I think ASM30 should have block comment feature, but not  ASM for
PIC18, PIC16...  The idea here is just as an alternative for one to
use the space after the 'end' as a scratch paper... and you can turn
those lines to live/sleep by moving the 'end' directive. You know
typing something rather long for testing purpose and then find that
you have to temporary disable those line,  only way to do that is
manually commented all lines...  or put in a temporary conditional
compile with #if and remove the conditional compile after it was done.
But playing around with 'end' should be an easy alternative.  This is
especially true when you're testing a complex code and you want to
revert original condition before you apply the change.

As I said this is just an alternative... I seldom use it actually but
occasionally in some special circumstances, I found that it's useful.


--
WH Tan

2005\12\08@082847 by Wouter van Ooijen

face picon face
> only way to do that is
> manually commented all lines...

>From a language designer vieuwpoint I still say: what you need is a
block-comment, so you would makrk only the start and end of the block
you want to comment out.

BTW when I face somthing like this in most cases I use #ifdefs because
otherwise I would have to remember where to put those test code blocks.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


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