Other Parts Discussed in Thread: SYSBIOS,
Tool/software: Code Composer Studio
Hello,
Environment:
- Hardware: AM65x EVM board
- Software: minimal example code with SYS/BIOS w/ modification (the code is attached below)
We have conducted a experiment measuring the interrupt jitter on the R5F which runs TI-RTOS. We ran the measurement for over 15 hours and the results shows the jitter is around 3.83us. We are wondering if this number is reasonable? Or is there any way to lower the jitter?
The following are the code and cfg :
/*
* ======== main.c ========
*/
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Timestamp.h>
#include <xdc/runtime/Types.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/hal/Hwi.h>
Int myHookSetId1, myHookSetId2;
volatile Bool myEnd2Flag = FALSE;
extern Timer_Handle myTimer;
volatile unsigned int *CTRLMMR_PADCONFIG192 = (volatile unsigned int *)0x11C300;
volatile unsigned int *CTRLMMR_LOCK7_KICK0 = (volatile unsigned int *)0x11D008;
volatile unsigned int *CTRLMMR_LOCK7_KICK1 = (volatile unsigned int *)0x11D00C;
volatile unsigned int *GPIO_DIR45 = (volatile unsigned int *)0x601060;
volatile unsigned int *GPIO_OUT_DATA45 = (volatile unsigned int *)0x601064;
volatile unsigned int *GPIO_SET_DATA45 = (volatile unsigned int *)0x601068;
volatile unsigned int *GPIO_CLR_DATA45 = (volatile unsigned int *)0x60106C;
#if 0
Void myRegister1(Int hookSetId)
{
System_printf("myRegister1: assigned hookSet Id = %d\n", hookSetId);
myHookSetId1 = hookSetId;
}
/* ======== myCreate1 ========
* invoked during Hwi module startup before main()
* for statically created Hwis */
Void myCreate1(Hwi_Handle hwi, Error_Block *eb)
{
Ptr pEnv;
pEnv = Hwi_getHookContext(hwi, myHookSetId1);
/* pEnv should be 0 at this point. If not, there's a bug. */
System_printf("myCreate1: pEnv = 0x%x, time = %d\n", pEnv,
Timestamp_get32());
Hwi_setHookContext(hwi, myHookSetId1, (Ptr) 0xdead1);
}
/* ======== myBegin1 ========
* invoked before Timer Hwi func */
Void myBegin1(Hwi_Handle hwi)
{
//Ptr pEnv;
//pEnv = Hwi_getHookContext(hwi, myHookSetId1);
System_printf("myBegin1: time = %d\n", Timestamp_get32());
//Hwi_setHookContext(hwi, myHookSetId1, (Ptr) 0xbeef1);
}
/* ======== myEnd1 ========
* invoked after Timer Hwi func */
Void myEnd1(Hwi_Handle hwi)
{
//Ptr pEnv;
//pEnv = Hwi_getHookContext(hwi, myHookSetId1);
System_printf("myEnd1: time = %d\n", Timestamp_get32());
//Hwi_setHookContext(hwi, myHookSetId1, (Ptr) 0xc0de1);
}
#endif
unsigned int last = 0, now = 0;
unsigned int mindelta = 0xFFFFFFFF;
unsigned int maxdelta = 0;
unsigned int avgdelta = 0;
unsigned int delta = 0;
unsigned long long count = 0;
unsigned long long overcount = 0;
unsigned long long overcount_ts = 0;
unsigned long long undercount = 0;
unsigned long long undercount_ts = 0;
unsigned int firstdelta = 0;
//volatile unsigned int *buffer = (volatile unsigned int*);
Void myTimerFunc(UArg arg)
{
//System_printf("Entering myTimerHwi at %d\n", Timestamp_get32());
if (0 == last)
{
last = Timestamp_get32();
}
else
{
now = Timestamp_get32();
delta = now - last;
last = now;
if (delta > maxdelta)
{
if (count != 0)
maxdelta = delta;
}
if (delta < mindelta)
mindelta = delta;
avgdelta = (avgdelta * count + delta) / (count+1);
if (delta > 50400)
{
if (count == 0)
{
firstdelta = delta;
}
else
{
overcount++;
overcount_ts = count;
}
}
if (delta < 49600)
{
undercount++;
undercount_ts = count;
}
count++;
*CTRLMMR_LOCK7_KICK0 = 0x68EF3490;
*CTRLMMR_LOCK7_KICK1 = 0xD172BC5A;
*CTRLMMR_PADCONFIG192 = 0x8000007;
*GPIO_DIR45 = 0xFEFFFFFF;
if (*GPIO_OUT_DATA45 == 0)
*GPIO_SET_DATA45 = 0x1000000;
else
*GPIO_CLR_DATA45 = 0x1000000;
}
}
double aaa = 0.1;
double bbb = 0.2;
double ccc = 0.3;
double ddd = 0.4;
/*
* ======== taskFxn ========
*/
Void taskFxn(UArg a0, UArg a1)
{
System_printf("enter taskFxn()\n");
Timer_start(myTimer);
while (1)
{
//Task_sleep(100);
aaa = aaa + bbb * ccc / ddd;
}
//Task_sleep(10);
System_printf("exit taskFxn()\n");
}
Void taskFxn1(UArg a0, UArg a1)
{
System_printf("enter taskFxn1()\n");
while (!myEnd2Flag) ;
System_printf("exit taskFxn1()\n");
}
/*
* ======== main ========
*/
Int main()
{
/*
* use ROV->SysMin to view the characters in the circular buffer
*/
System_printf("enter main()\n");
BIOS_start(); /* does not return */
return(0);
}
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Main = xdc.useModule('xdc.runtime.Main');
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var Task = xdc.useModule('ti.sysbios.knl.Task');
/*
* Uncomment this line to globally disable Asserts.
* All modules inherit the default from the 'Defaults' module. You
* can override these defaults on a per-module basis using Module.common$.
* Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
*/
/*
* Uncomment this line to keep module names from being loaded on the target.
* The module name strings are placed in the .const section. Setting this
* parameter to false will save space in the .const section. Error and
* Assert messages will contain an "unknown module" prefix instead
* of the actual module name.
*/
Defaults.common$.namedModule = false;
/*
* Minimize exit handler array in System. The System module includes
* an array of functions that are registered with System_atexit() to be
* called by System_exit().
*/
System.maxAtexitHandlers = 4;
/*
* Uncomment this line to disable the Error print function.
* We lose error information when this is disabled since the errors are
* not printed. Disabling the raiseHook will save some code space if
* your app is not using System_printf() since the Error_print() function
* calls System_printf().
Error.raiseHook = null;
*/
/*
* Uncomment this line to keep Error, Assert, and Log strings from being
* loaded on the target. These strings are placed in the .const section.
* Setting this parameter to false will save space in the .const section.
* Error, Assert and Log message will print raw ids and args instead of
* a formatted message.
*/
Text.isLoaded = false;
/*
* Uncomment this line to disable the output of characters by SysMin
* when the program exits. SysMin writes characters to a circular buffer.
* This buffer can be viewed using the SysMin Output view in ROV.
*/
SysMin.flushAtExit = false;
/*
* The BIOS module will create the default heap for the system.
* Specify the size of this default heap.
*/
BIOS.heapSize = 0x0;
/* System stack size (used by ISRs and Swis) */
Program.stack = 0x400;
/* Circular buffer size for System_printf() */
SysMin.bufSize = 128;
/*
* Create and install logger for the whole system
*/
var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 4;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;
System.SupportProxy = SysMin;
/*
* Build a custom BIOS library. The custom library will be smaller than the
* pre-built "instrumented" (default) and "non-instrumented" libraries.
*
* The BIOS.logsEnabled parameter specifies whether the Logging is enabled
* within BIOS for this custom build. These logs are used by the RTA and
* UIA analysis tools.
*
* The BIOS.assertsEnabled parameter specifies whether BIOS code will
* include Assert() checks. Setting this parameter to 'false' will generate
* smaller and faster code, but having asserts enabled is recommended for
* early development as the Assert() checks will catch lots of programming
* errors (invalid parameters, etc.)
*/
BIOS.libType = BIOS.LibType_Custom;
BIOS.logsEnabled = false;
BIOS.assertsEnabled = true;
/*
* Create a task. The 'taskFxn' function can be found in main.c.
*/
var task0Params = new Task.Params();
var task0 = Task.create("&taskFxn", task0Params);
//var task1Params = new Task.Params();
//var task1 = Task.create("&taskFxn1", task1Params);
xdc.loadCapsule("r5_mpu.xs");
var Timer = xdc.useModule('ti.sysbios.hal.Timer');
var timerParams = new Timer.Params();
timerParams.startMode = Timer.StartMode_USER;
timerParams.runMode = Timer.RunMode_CONTINUOUS; //Timer.RunMode_ONESHOT;
timerParams.period = 125; // 1ms
Program.global.myTimer = Timer.create(Timer.ANY, "&myTimerFunc", timerParams);
BIOS.clockEnabled = false;
/* Hook Set 1 */
Hwi.addHookSet({
registerFxn: '&myRegister1',
createFxn: '&myCreate1',
beginFxn: '&myBegin1',
endFxn: '&myEnd1',
});
