Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

How to set Idle state ?

Altera_Forum
Honored Contributor II
3,944 Views

Hello, I'm a new user so be gentle :) 

 

I need to create an Idle state, I have ISR called by the clock every 1 ms, and I need to get rid of the for(;;) loop in the main function 

 

this is my main : 

 

int main() 

// ISR registration ... 

 

for(;;); 

 

I don't want to use the for(;;) ...  

 

btw - what is the meanning of "Program never exits" ? 

 

thank you ...
0 Kudos
16 Replies
Altera_Forum
Honored Contributor II
849 Views

Your program has to be doing something while it's not executing the interrupt code, might as well be a for(...) loop. Otherwise you could have it doing something else useful, or un-useful, like calculating the last digit of pi. 

 

If you really don't have something else to do, and have some aversion to for(...), you might try this, it does the same thing. 

 

main() { while(1) { // blah, blah..., whatever code, or completely blank } }"Program never exits" is a signal to the compiler that you have either a for() or a while() loop in main. In this case, the compiler does not have to insert cleanup code after the end of main, like fclose(stdin/out/err), and a variety of other housekeeping chores that are not needed if you have used a for() or while() loop in the main program to prevent it from exiting. It is not an automatic way to make it not exit. 

 

I don't think there is a 'sleep' or 'idle' mode on Nios, but you would wrap that in a for() or while() loop anyway.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

There actually is a sleep mode in Nios 2. It's called usleep (). You can find it in the Nios II Software Developer’s Handbook. 

 

int usleep (unsigned int us) and it can be found in <unistd.h>. 

 

But the best way to not let your program end is indeed to just put in a while(1) loop.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

I think that by "sleep" mode, donq meant a low power mode where the CPU would shut down until the next interrupt. This doesn't exist on Nios II. 

The usleep function keeps the CPU busy by executing the same instruction again and again until the required delay is achieved. It should be renamed uwake ;)
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

thank you all ... 

 

I don't want to use while(1). 

 

something odd happend ... as the main function (and the alt_main) has endded , the ISR i wrote was still active be the timer interrupt. 

 

can someone explain what the CPU is doing in this state (only the ISR is active for 200 uSec, and 800 uSec nothing is running).
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Why don't you want to use for(;;) or while(1) ? 

I'm not sure about what the CPU is doing after exiting main. It should either be stuck in an infinite loop, if it exists, or start to execute random code, which could be a bad thing. 

The ISRs still run though, as long as they aren't disabled.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

There is no idle state for NIOS by default.  

But I think you can write your own small slave component which stalls the NIOS by holding the WAITREQUEST and therefore blocks the bus. You can wake it up again, in case of an interrupt (e.g. Timer). 

 

My colleague told me about it. I think there must be some older threads on this subject in the forum. 

 

I didn't do it on my own. I just know that it is possible and that it's saving power in fact.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Asserting WAITREQUEST is unlikely to save power (it will still be sampled every clock). 

Probably the only way to save power is to stop the cpu clock - and I suspect that is difficult. 

 

There is the other question about what you are actually trying to achieve. 

For a simple embedded system it is not unusual to not use any interupts, but just have the main loop check each hardware device in turn. 

Interrupts are only needed for hardware that have strong timing requirements. 

 

An ethernet interface will usually process a buffer ring, so there is no real need to take any interupts. Similarly even a serial port with a large enough FIFO can be polled. 

 

If you don't use interrupts, you save all the cpu cycles used saving and restoring registers, and those vectoring the interrupt itself. 

 

Of course, you could go the other way and leave the main processing loop being for (;;);, do all your work from ISRs, only allow one level of ISR, and then not bother saving and restoring any registers!
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

@dsl: I must object...... It does save power 

 

Maybe I didn't explain it good enough. Well I am only a softi....;-)  

Take a look at this thread 

http://www.alteraforum.com/forum/showthread.php?t=19136&highlight=reduce+power+consumption  

 

Even if it's not much but actually this approach is saving power.....
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Perhaps I meant 'save much power' ... 

 

You could also stall cpu execution in a multi-cycle custom instruction. 

That gives you two 32bit values to play with as well, and a result. 

One could be a bit-mask of IRQ bits (or similar), the other a maximum clock count. The result could be the bit(s) that woke the system up. 

 

Quite possibly both these stalls cause the clock to almost all of the nios cpu to get suspended. Removing the instruction fetch and all the associated signal changes. 

(hmmm... if you disable dynamic branch prediction and execute 'foo: bxx foo' from tightly coupled instruction memory then almost nothing is likely to change!)
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

 

--- Quote Start ---  

@dsl: I must object...... It does save power 

 

Maybe I didn't explain it good enough. Well I am only a softi....;-)  

Take a look at this thread 

http://www.alteraforum.com/forum/showthread.php?t=19136&highlight=reduce+power+consumption  

 

Even if it's not much but actually this approach is saving power..... 

--- Quote End ---  

 

 

How much power? Did you take a measurement? If you post "this approach is saving power" - then please post how much savings so user's can benefit from this approach and know if it is worthwhile to implement. 

 

Bill
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

I didn't measure it myself.... 

 

My colleague told me it was a few mA. Don't know how reliable it ist but I guess for mobile devices you can save at least something ....
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

 

--- Quote Start ---  

I don't want to use while(1). 

--- Quote End ---  

 

The point is, when the processor is not running the interrupt code, it will be running some code, somewhere. It would probably be better if it was your code, rather than some random bits scattered across uninitialized memory somewhere. 

 

--- Quote Start ---  

something odd happend ... as the main function (and the alt_main) has endded , the ISR i wrote was still active be the timer interrupt. 

--- Quote End ---  

 

All bets are off until you wrap your embedded run-time code in an endless loop. The moment your program 'falls off the end', your program is over and you should no longer consider yourself in charge of the hardware. The fact that the interrupt routine keeps running after your program ends is more of an example of poor programming practices than something you should be trying to exploit. 

 

--- Quote Start ---  

can someone explain what the CPU is doing in this state (only the ISR is active for 200 uSec, and 800 uSec nothing is running). 

--- Quote End ---  

 

If it is not running your code, it is running some other code. As long as this completely unknown code does not alter the hardware, or change the stack pointer, or overwrite the stack frame, or any of a huge number of other possiblilities, your interrupt routine will keep running. 

--- Quote Start ---  

 

The ISRs still run though, as long as they aren't disabled. 

--- Quote End ---  

Or the code overwritten, or the stack pointer altered, or the stack data overwritten, or the interrupt pointed at another routine, or any of about a kazillion other possibilities... 

 

 

 

Yossi, just put some sort of loop in your code! If you don't like if() and you don't like while(), then do something else, but just do it!
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Thank you all, I added some sort of while(1) to my code - I wrote scheduler that registered my function, and every tick run it and some other routines ... 

 

I think that an Idle state is necessary to the NIOS, after all, if my code is event driven, so most of the time (80%) the cpu should do NOTHING !!!!!!  

power consumption is an issue in embedded real time systems, and so is cpu temp, especially if one uses two cpu's or more . 

 

 

donq - if you are correct, so alt_main must disable all interrupts, just like any other real time operation system (I know i'm working OSless ...) 

 

how can I contact Altera to ask about cpu behavior after main has ended ?
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Actually, especially if you're running it from the Quartus downloader/debugger, there is an "operating system" of sorts. And Altera already told you how it works because they gave you the source code. 

 

The easiest way to see what happens is to run the code in debug mode and look at the disassembly view.  

 

First, see what your 'while(1)' code looks like, then take it out and see where the code eventually winds up. Does it look familiar? 

 

Problem with depending on the _exit() routine to catch you, or lacking that, another 'bsr here' further along in the code, is that it may not be there in a final implementation of your code, running without the debugger, etc. 

 

Also, other environments will not have the same safety net. It is simply a bad practice to let your code run off the end. Once it does so, you are no longer in control of what happens. Even if you know exactly what happens today, you do not know what will happen in version 1.01, 1.02, 1.02b, 2.0, etc. 

 

An idle state might be nice, but if it doesn't exist on this processor, it's useless to try to invent it here. Even so, many processors come out of idle state on an interrupt and have to loop back to the 'Idle' instruction to re-enter the 'Idle' state. There's the while(1) loop again! Wrapped around the 'Idle' instruction. 

 

Curious is good... spend it on exploring the source code supplied by Altera. Do a text search for 'alt_main' and that will get you close. But leave the while(1) loop in your embedded code regardless of processor, operating system, and the availability (or not) of 'Idle' instructions.  

 

The point is not to see if you can make something unusual work under exactly the right conditions, it is to make it most likely to work under all conditions. There are enough problems with getting good code to run right, you don't need to stack bad coding on top of that.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

 

--- Quote Start ---  

 

Do a text search for 'alt_main' and that will get you close. But leave the while(1) loop in your embedded code regardless of processor, operating system, and the availability (or not) of 'Idle' instructions.  

 

The point is not to see if you can make something unusual work under exactly the right conditions, it is to make it most likely to work under all conditions. There are enough problems with getting good code to run right, you don't need to stack bad coding on top of that. 

--- Quote End ---  

 

 

Thank you,  

where did you get your training, i'm searching for a good book/site and It seems that this forum is the only place ... 

 

Always happy to write better code :)
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

Writing device drivers for over 30 years :-)

0 Kudos
Reply