Sorry, you need to enable JavaScript to visit this website.

Using a timer when running a C program as 'bare metal'

Unsolved
14 posts / 0 new
anders's picture
anders
Junior(0)
Using a timer when running a C program as 'bare metal'

Hi,

I'm trying to run a benchmark-like algoritm on the zedboard using the SDK (like the helloWorld program in the labs here on ZedBoard.org).

My poblem is that when i'm trying to get the time,
startTime = ftime(&tmb);
I get an error that ftime cannot be found.

Is there an commonly used way to get the time?

Thanks for answers :)

Anders Viken

james t kennedy's picture
james t kennedy
Junior(0)
axi_timer ip sw drivers

one way is to use the axi_timer IP. you must add this to your design using XPS. In SDK when you creste the BPS you should get the scutimer_v1_02_a library under ps7_cortex\libsrc.

in your app source:

#include "xil_types.h"
#include "xtmrctr.h"
#include "xparameters.h"

The API you want to use:

unsigned int time1, time2, cum_time;

Status = XTmrCtr_Initialize(&TmrCtrInstancePtr, XPAR_AXI_TIMER_0_DEVICE_ID);
if (Status != XST_SUCCESS)
{
return;
}

time1 = XTmrCtr_GetValue(&TmrCtrInstancePtr, 0);
XTmrCtr_Start(&TmrCtrInstancePtr, 0);

// your process

XTmrCtr_Stop(&TmrCtrInstancePtr, 0);
time2 = XTmrCtr_GetValue(&TmrCtrInstancePtr, 0);

This gives you clock ticks, so if your clock tick is 10 ns, divide by 100 to get us.

i found that i had to reinitialize the timer for each measurement. i would be interested if you figure out why.

hope this helps.

anders's picture
anders
Junior(0)
thanks for answer

I followed your instructions, but it seems like xtmrctr.h can't be found in the directory. What do you suggest to do here?

james t kennedy's picture
james t kennedy
Junior(0)
tmrctr driver lib in BSP

do you have tmrctr_v_2_04_a in your BSP ps7_cortexa9_1\libsrc?
did you add an axi_timer in XPS and then redo the BSP for the modified HW?
I think you should get the library in BSP.
What libraries do you get?
scutimer but nor timrctr? i got both but maybe i did somehting different.
we'll get this sorted out -- no worries!

anders's picture
anders
Junior(0)
Program using long time

Hi, thanks again for your reply. Got all the include files worked out now :)

But when I try to run the program, it "stops" after checkpoint 3 (see code). The program doesn't terminate, but it uses several minutes with nothing happening.

The code has no errors or warnings. When I start the program I get the message: "FPGA configuration is not done on the target. Do you still want to continue launching application?"

Do you have any idea what I might do here?

Again thanks for your answers, much appreciated :)

Anders Viken

Code:
#include "xil_types.h"
#include "xtmrctr.h"
#include "xparameters.h"
#include<stdio.h>

int main()
{
printf("Checkpoint 1\n");
XTmrCtr TmrCtrInstancePtr;

printf("Checkpoint 2\n");
unsigned int startTime, endTime, usedTime;

printf("Checkpoint 3\n");
XStatus Status = XTmrCtr_Initialize(&TmrCtrInstancePtr, XPAR_AXI_TIMER_0_DEVICE_ID);

printf("Checkpoint 4\n");
if (Status != XST_SUCCESS)
{
printf("Problem with timer initialization. Exiting.\n");
return 1;
}

printf("Checkpoint 5\n");
startTime = XTmrCtr_GetValue(&TmrCtrInstancePtr, 0);

printf("Checkpoint 6\n");
XTmrCtr_Start(&TmrCtrInstancePtr, 0);

// the process
printf("Hello World\n");

XTmrCtr_Stop(&TmrCtrInstancePtr, 0);
endTime = XTmrCtr_GetValue(&TmrCtrInstancePtr, 0);

usedTime = endTime - startTime;

printf("Number of ticks used: %d\n", usedTime);

return 0;

}

zackshef's picture
zackshef
Junior(0)
Program FPGA

As far as the FPGA configuration, I can help you there. First, make sure the hardware server is running (Xilinx Tools->Launch Hardware Server) and then select Xilinx Tools->Program FPGA. You'll have to select a bitstream. Zynqgeek's Hello_world walkthrough can show you how to get that if you don't have one. That should get rid of that error.

When I run your code, it goes from checkpoint 1 to 2 to 3 then repeats main from the beginning. Apparently the XTmrCtr_Initialize function (at checkpoint 3) isn't acting as you think it is/should. I'm interested in getting this working too so I'll also be working on it.

zackshef's picture
zackshef
Junior(0)
Problem found...

I found where the problem is, but I'm not sure how to fix it...

In the XTmfCtr_Initialize() function, theres a for loop:

for (TmrCtrNumber = 0; TmrCtrNumber < XTC_DEVICE_TIMER_COUNT;
TmrCtrNumber++) {
/*
* Read the current register contents and check if the timer
* counter is started and running, note that the register read
* is not using the base address in the instance so this is not
* destructive if the timer counter is already started
*/
StatusReg = XTmrCtr_ReadReg(TmrCtrConfigPtr->BaseAddress,
TmrCtrNumber, XTC_TCSR_OFFSET);
if (StatusReg & XTC_CSR_ENABLE_TMR_MASK) {
printf("********** Timer %d already started ********** \n\n", TmrCtrNumber);
return XST_DEVICE_IS_STARTED;
}
}

The description is "Check each of the timer counters of the device, if any are already running, then the device should not be initialized. This allows the user to stop the device and reinitialize, but prevents a user from inadvertently initializing."

Within this loop, I think there's an interrupt being fired, which is resetting something, and causing the program to go to the top of main(). I'm not sure how to overcome this, as it continues to happen during ever iteration. Could it be another timer that's firing the interrupt? I'll continue to look into this.

(If the code above doesn't format nicely, I'll repost it)

anders's picture
anders
Junior(0)
Thanks for answer

I tried installing the 14.5 xilinx package. then the program worked as intended :)

I have no idea why...

Anders Viken

james t kennedy's picture
james t kennedy
Junior(0)
XTmfCtr_Initialize() is working for me

do you get the printf message?
It sounds more like it is transferring execution to something uninitialized -- bad code. i think somehow your timer is not instantiated properly from the hw configuration.
what is the deviceid? if you only have one timer -- it should be 0. i hardcoded 0 in subsequent calls -- not good practice. but the deviceid passed to the function, XPAR_AXI_TIMER_0_DEVICE_ID was 0 in my xparamters.h file. if you passed something else, it could be reading some inadvertant location causing erratic behavior.
good luck.
freertos has timers that i have not used, so does the scutimer library.

zackshef's picture
zackshef
Junior(0)
I also use XPAR_AXI_TIMER_0

I also use XPAR_AXI_TIMER_0_DEVICE_ID (which is a macro, defined as 0 in xparameters.h). It never gets to the printf statement. I'm not sure what's going on... I'll try freeRTOS or scutimer... Or maybe just reinstall v14.5

james t kennedy's picture
james t kennedy
Junior(0)
good news!

good for you. i am just installing 14.4.
and keeping 14.2 around for the speedway course makes 3. this is too much space on my SSD!

zackshef's picture
zackshef
Junior(0)
scutimer

I tried implementing the scutimer library and things work like a charm. I did notice that the timerInstance was in global scope, whereas I was putting my axi timer in main. Maybe that was my problem. I noticed that james t kennedy's timers were also a local scope in main. Maybe that's what caused issues. Anyhow, I also found an example of scutime with an interrupt handler, so that helps as well... Problem solved!

james t kennedy's picture
james t kennedy
Junior(0)
tmrctr works

scutimer may be prefereable. i used tmrctr because i used it 4 years ago in a microblaze app.
btw, although i did not post my listing, my instance WAS local to main or to the therad function under FreeRTOS, but remember i did not have an issur, the xtmrctr WORKED in my app.
Interrupts are useful but in this case we were framing PL and PS based functions to get acceleration times.
The IP could interrupt and predicate a reading of the timer. this would be effective.

Gayathri's picture
Gayathri
Junior(0)
Another method