- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.
I’ve got a problem with simple interrupt from interval timer in uC/OS-II System frequency is 75Mhz. There are PIO and timer. It makes strobe. Duration 10 ms. Here it is:
// global variablesint err;
// handler
static void handle_timer(void* context)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 1);
timer_exit();
err = 1;
return;
}
// set handler
void timer_init(alt_u32 _base, alt_u32 _interrupt, alt_u32 _irq)
{
timer_base = _base;
timer_interrupt = _interrupt;
timer_irq = _irq;
alt_ic_irq_disable (timer_interrupt, timer_irq);//disable interrupt
alt_ic_isr_register(timer_interrupt, timer_irq, handle_timer, NULL, NULL); break;
return;
}
// reset / set timeout
void timer_set_period(alt_u32 timer_period)
{
timer_period = HIGHT_RES_TIMER_LOAD_VALUE * timer_period;
IOWR_ALTERA_AVALON_TIMER_PERIODL(timer_base, timer_period&ALTERA_AVALON_TIMER_PERIODL_MSK); //write timer period l
IOWR_ALTERA_AVALON_TIMER_PERIODH(timer_base, (timer_period>>16)&ALTERA_AVALON_TIMER_PERIODH_MSK); //write timer period h
return;
}
// start counting
void timer_start(void)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ( ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
ALTERA_AVALON_TIMER_CONTROL_START_MSK)); //start timer, enable interrupt
return;
}
// pause counting
void timer_stop(void)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
return;
}
// timer deactivation
void timer_exit(void)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
alt_ic_irq_disable (timer_interrupt, timer_irq);//disable interrupt
return;
}
// timer usage
int foo(void)
{
int nop;
err = 0;
/*A*/ IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0); //set PIO
/*B*/ timer_init(HIGHT_RES_TIMER_BASE, HIGHT_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID, HIGHT_RES_TIMER_IRQ);
/*C*/ timer_set_period(10);
/*D*/ timer_start();
while(err == 0)
{nop=0;} //waiting for timer
timer_exit();
return 1;
}
Timer’s description from system.h
/*
* hight_res_timer configuration
*
*/# define ALT_MODULE_CLASS_hight_res_timer altera_avalon_timer# define HIGHT_RES_TIMER_ALWAYS_RUN 0# define HIGHT_RES_TIMER_BASE 0x1003520# define HIGHT_RES_TIMER_COUNTER_SIZE 32# define HIGHT_RES_TIMER_FIXED_PERIOD 0# define HIGHT_RES_TIMER_FREQ 75000000u# define HIGHT_RES_TIMER_IRQ 1# define HIGHT_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0# define HIGHT_RES_TIMER_LOAD_VALUE 74ull# define HIGHT_RES_TIMER_MULT 1.0E-6# define HIGHT_RES_TIMER_NAME "/dev/hight_res_timer"# define HIGHT_RES_TIMER_PERIOD 1.0# define HIGHT_RES_TIMER_PERIOD_UNITS "us"# define HIGHT_RES_TIMER_RESET_OUTPUT 0# define HIGHT_RES_TIMER_SNAPSHOT 1# define HIGHT_RES_TIMER_SPAN 32# define HIGHT_RES_TIMER_TICKS_PER_SEC 1000000u# define HIGHT_RES_TIMER_TIMEOUT_PULSE_OUTPUT 0
I debugged this code and it works perfectly. My project became more complicated and I had to use uC/OS-II. This part of code is very simple and has no changes but it works very strange. Duration of strobe became about 30 ms! After some manipulation with code I found out that functions of setting timer on are very slow. I put line A between lines C and D. It makes duration of strobe about 16 ms. why simple register’s writing become slow? what should i do to make it working faster?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, What do you want to see ?
Are timer interruptions happening at equal period : to verify the accuracy. If this is the answer, you go to the wrong way. or how many time does Nios take to initialize the timer ? Your program starts and stops at the first timer interrupt. Maybe I misunderstood something.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ohh. I apologize for the confusing post. English is not my native language.
I'd like to get strobe with a duration 10ms. And I got it without uC. Timer initialization takes about 250ns without uC. But when I use uC it takes about 20ms to initialize timer. I want to make it faster than 20ms. I also want to understand why it takes 20ms to write 7 registers.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How do you measure the strobe ? You power up the board and start a chronometer until your "err=1" happens ?
uC/OS has its own initialization that shall take time. Do you want your board to start very fast ? Why such a constraint. OR do you want your board to "produce" a regular strobe ? which is more usual. I think you want THIS. You code is hard to understand.
static void handle_timer(void* context)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 1); // <----------------------This is THE stobe signal, I think
timer_exit(); // <--------------------- ?????????? ----------------- you are in an interrupt routine, so it should be as short as possible and easy to read
err = 1;
return;
}
Your code doesn't do what you expect (I am 95% sure). I suggest to rewrite the code. Keep in mind the algorithm of what you expect. Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I measure strobe with oscilloscope.
I describe behavior of my code In main function (int foo(void)) I set strob signal in high level byIOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0); //set PIO
(cause I has inverter on ouput pin). Then init timer to 10ms, and start it. Enter endless loop and wait for interrupt. I expect it takes 10ms to get interrupt. But it takes much longer because init functions work so slow in uC. In interrupt handler I deactivate srobe and timer. IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 1);
timer_exit(); That’s all. Time to exec timer_exit();
err=1;
and following instructions doesn’t meters because I measure time between --- Quote Start --- IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0); --- Quote End --- and --- Quote Start --- IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 1); --- Quote End ---
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, the question is : why writing to a register is so slooooooooooooooooow with uc/os ?
Probably the scheduler, other interrupts... something linked to uC/OS. My questions : Do you really matters of the duration of writing to an interrupt register ? AS said before : do you want to verify the accuracy of the timer OR do you want to minimize time for the board to be initialized ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am satisfied with the accuracy of the timer. It works perfect - proved experimentally.
--- Quote Start --- ... something linked to uC/OS. --- Quote End --- :) I got it. But there are no other interrupts with higher priority and no other treads(tasks) ... I want to be sure that delay of timer initialization functions is constant, so it can be considered when calculating the timeout (timer init value). I also want to minimize time to execute timer initialization functions, because it is longer than my strobe duration.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, you want your board to boot in less than 10 ms ?! or only the program ?
I guess your board will be "hot inserted". High constraint you get. why such a constraint ? Maybe you have very good reason to hardly work on that. Please be aware that FPGA takes time to be configured with user logic and start running user program ? Written in Altera handbooks. Since your board has no routine that modify boot sequence (unlike Windows ;-)), and is deterministic, I think you can consider the boot time constant, but I would put high margin to be sure. To resume, You can't be sure that delay of timer initialization functions is constant because of bad luck, upset events, température, electromagnetic field, altitude, humidity............ "Starting the scheduler, reserve RAM space, checking configuration...." of uC/OS must be time consuming. Good luck- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't need board to boot in less than 10 ms. My board starts for a long time. And that is all right.
I need to do something like this:https://www.alteraforum.com/forum/attachment.php?attachmentid=7682 t1 - is first strobe with a duration 10ms, t2 - time to reinit and restart timer. To make stobe with duration 10ms I first init and start timer, and then set pioout1 up But I can't make t2=0, becausevoid timer_start(void)
{
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ( ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
ALTERA_AVALON_TIMER_CONTROL_START_MSK)); //start timer, enable interrupt
return;
}
takes 6ms! I can set timer for 4ms it can help me get second strobe with 10ms duration, but it is dirty hack. maybe there is some optimization, and i should turn it on in bsp/hal configuration?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1)
If you want really hard real time, you can do this by using a counter with a pll on the clock. All in pure FPGA logic : no random external events (except upset events caused by radiations of course), very ultra deterministic, very easy to make... ^^^ Very optimized !! :-) ultra low resources, quite robust, MTBF near MTBFof FPGA, ultra simple to design.... 2) You can configure timer to produce interruptions at a fixed period : no need to stop and start by the software. Take the features of FPGA : programmable gate array. Else a computer (PC, MAC, rasberry...) would be sufficent ;-) 3) optimisations of uc/OS : tedious work and may not be sufficient. (Mistake) --- Quote Start --- My board starts for a long time --- Quote End --- BUT your operating procedure show us that you measure the boot time + duration until first interruption. (Am I Right ?) You mismatch yourself OR I misunderstood/forgot something. I am very confused HERE NOW.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not care about the boot time of my board, and the duration of the execution of other instructions. But at a certain moment NIOS' application must produce a series of strobes with various durations. But it does not produce them because timer init instructions get stuck in layers of HAL uC. I asked how to speed up their execution. And that’s all.
It’s hard to realize this staff on FPGA logic because it works closely to other subprograms. I got that there is no any settings in bsp property to make writing to an interrupt register exec faster. I understand that I should work with timer like with pll. I should configure timer to produce interruptions at a fixed period, and count interruptions to produce strobes with longer duration. Thank you.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To resume, you want to produce strobe with various durations.
This strobe signal is on an OUTPUT FPGA pin (destination : other device) right ? If you want hard real time (I mean that durations are strictly constrained and if one time is missed then fatal error), I don't recommand using software interrupts, because of what you have seen. --- Quote Start --- It’s hard to realize this staff on FPGA logic because it works closely to other subprograms. --- Quote End --- To produce strobe at various duration is not hard. You can load the value to a external (but inside FPGA) counter which produce strobe. To load the value, just employ a PIO ins Qsys. could you describe more of your project ? could you give a basic algorithm and structure of this part of your project (moslty relation between strobe and (sub)program)? Not enough info to help you and still confusing.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page