This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
The text below dot line is an example for one core image for EVM6472. It is written under DSP/BIOS 5. I would like to rewrite it in SYS/BIOS 6 for one core in 6678. I do not understand the function of the HST module. I find in DSP/BIOS 5, only LOG and RTDX needs for LOG_printf. Why is there a HST? Furthermore, I do not know how to translate it to SYS/BIOS 6. There are big changes for HST functions because I find it cannot be processed by DSP/BIOS5 to SYS/BIOS6 migration software.
"RTA_fromHost" and "RTA_toHost" are reserved words?
Please shed your light on my questions.
Thanks.
..................
utils.loadPlatform("ti.platforms.evm6472");
/* The following DSP/BIOS Features are enabled. */
bios.enableRealTimeAnalysis(prog);
bios.enableMemoryHeaps(prog);
bios.enableTskManager(prog);
bios.GBL.C64PLUSMAR0to31 = 0x003f0000;
bios.GBL.C64PLUSMAR224to255 = 0x000000ff;
bios.MEM.instance("LL2RAM").createHeap = 1;
bios.MEM.instance("LL2RAM").heapSize = 0x00000800;
bios.MEM.instance("LL2RAM").enableHeapLabel = 1;
bios.MEM.instance("LL2RAM").heapLabel = prog.extern("HEAP");
bios.MEM.STACKSIZE = 0x1000;
bios.LOG.instance("LOG_system").bufLen = 512;
bios.LOG.create("trace");
bios.LOG.instance("trace").bufLen = 256;
bios.SEM.create("sem");
bios.TSK.create("reader0");
bios.TSK.instance("reader0").order = 1;
bios.TSK.instance("reader0").priority = 2;
bios.TSK.instance("reader0").fxn = prog.extern("reader");
bios.TSK.create("writer0");
bios.TSK.instance("writer0").order = 2;
bios.TSK.instance("writer0").fxn = prog.extern("writer");
bios.TSK.create("writer1");
bios.TSK.instance("writer1").order = 3;
bios.TSK.instance("writer1").fxn = prog.extern("writer");
bios.TSK.instance("writer1").arg0 = 1;
bios.TSK.create("writer2");
bios.TSK.instance("writer2").order = 4;
bios.TSK.instance("writer2").fxn = prog.extern("writer");
bios.TSK.instance("writer2").arg0 = 2;
bios.IDL.create("IDL_cnt");
bios.IDL.instance("IDL_cnt").order = 1;
bios.IDL.instance("IDL_cnt").fxn = prog.extern("IDL_testfunc");
/* allocate memory segments */
bios.MEM.BIOSOBJSEG = prog.get("LL2RAM");
bios.MEM.MALLOCSEG = prog.get("LL2RAM");
bios.MEM.ARGSSEG = prog.get("LL2RAM"); /* BIOS Uninit .args def: LL2 */
bios.MEM.STACKSEG = prog.get("LL2RAM"); /* BIOS Uninit .stack def: LL2 */
bios.MEM.TRCDATASEG = prog.get("LL2RAM"); /* BIOS Uninit .trcdata def: LL2 */
bios.MEM.SYSDATASEG = prog.get("LL2RAM"); /* BIOS Uninit .sysdata def: LL2 */
bios.MEM.OBJSEG = prog.get("LL2RAM"); /* BIOS Uninit .*obj? def: LL2 */
bios.MEM.HWIVECSEG = prog.get("LL2RAM"); /* BIOS Init'd .hwi_vec def: LL2 */
bios.MEM.GBLINITSEG = prog.get("LL2RAM"); /* BIOS Init'd .gblinit def: SL2 */
bios.MEM.BIOSSEG = prog.get("LL2RAM"); /* BIOS Init'd .bios def: SL2 */
bios.MEM.SYSINITSEG = prog.get("LL2RAM"); /* BIOS Init'd .sysinit def: SL2 */
bios.MEM.HWISEG = prog.get("LL2RAM"); /* BIOS Init'd .hwi def: SL2 */
bios.MEM.RTDXTEXTSEG = prog.get("LL2RAM"); /* BIOS Init'd .rtdx_text def: SL2 */
bios.MEM.BSSSEG = prog.get("LL2RAM"); /* Cmpl Uninit .bss def: LL2 */
bios.MEM.FARSEG = prog.get("LL2RAM"); /* Cmpl Uninit .far def: LL2 */
bios.MEM.CIOSEG = prog.get("LL2RAM"); /* Cmpl Uninit .cio def: LL2 */
bios.MEM.TEXTSEG = prog.get("LL2RAM"); /* Cmpl Init'd .text def: SL2 */
bios.MEM.SWITCHSEG = prog.get("LL2RAM"); /* Cmpl Init'd .switch def: SL2 */
bios.MEM.CINITSEG = prog.get("LL2RAM"); /* Cmpl Init'd .cinit def: SL2 */
bios.MEM.PINITSEG = prog.get("LL2RAM"); /* Cmpl Init'd .pinit def: SL2 */
bios.MEM.CONSTSEG = prog.get("LL2RAM"); /* Cmpl Init'd .const/.printf def: SL2 */
bios.MEM.DATASEG = prog.get("LL2RAM"); /* Cmpl Init'd .data def: LL2 */
/* select memory segments for all the objects, def: LL2 */
bios.BUF.OBJMEMSEG = prog.get("LL2RAM");
bios.SYS.TRACESEG = prog.get("LL2RAM");
bios.LOG.OBJMEMSEG = prog.get("LL2RAM");
bios.LOG.instance("LOG_system").bufSeg = prog.get("LL2RAM");
bios.STS.OBJMEMSEG = prog.get("LL2RAM");
bios.CLK.OBJMEMSEG = prog.get("LL2RAM");
bios.PRD.OBJMEMSEG = prog.get("LL2RAM");
bios.SWI.OBJMEMSEG = prog.get("LL2RAM");
bios.TSK.OBJMEMSEG = prog.get("LL2RAM");
bios.TSK.instance("reader0").stackMemSeg = prog.get("LL2RAM");
bios.TSK.instance("TSK_idle").stackMemSeg = prog.get("LL2RAM");
bios.TSK.instance("writer0").stackMemSeg = prog.get("LL2RAM");
bios.IDL.OBJMEMSEG = prog.get("LL2RAM");
bios.SEM.OBJMEMSEG = prog.get("LL2RAM");
bios.MBX.OBJMEMSEG = prog.get("LL2RAM");
bios.QUE.OBJMEMSEG = prog.get("LL2RAM");
bios.LCK.OBJMEMSEG = prog.get("LL2RAM");
bios.DIO.OBJMEMSEG = prog.get("LL2RAM");
bios.DHL.OBJMEMSEG = prog.get("LL2RAM");
bios.RTDX.RTDXDATASEG = prog.get("LL2RAM");
bios.HST.OBJMEMSEG = prog.get("LL2RAM");
bios.HST.instance("RTA_fromHost").bufSeg = prog.get("LL2RAM");
bios.HST.instance("RTA_toHost").bufSeg = prog.get("LL2RAM");
bios.PIP.OBJMEMSEG = prog.get("LL2RAM");
bios.SIO.OBJMEMSEG = prog.get("LL2RAM");
// !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
prog.gen();
.....................
Robert,
Please see the HST description in the API reference guide (http://www.ti.com/lit/ug/spru403r/spru403r.pdf). It was used by DSP/BIOS for streaming of data between the target DSP and the debugger host. For example, when using RTDX to transfer instrumentation data to CCS, underlying HST channels were used (“RTA_toHost” and “RTA_fromHost”).
As described in the migration app note (http://www.ti.com/lit/an/spraas7g/spraas7g.pdf), HST was not ported forward to SYS/BIOS. A new architecture is used in SYS/BIOS for instrumentation; please see chapter 8 in the SYS/BIOS user’s guide (http://www.ti.com/lit/ug/spruex3k/spruex3k.pdf).
Scott
In fact, I have read the stuff you mention. The problem is that does not solve my problem. HST is not supported in SYS/BIOS. Then what can get that function (non PIP) done in SYS/BIOS. For a beginner like me, it is too abstract what to do that a function does not continue in a new BIOS version.
Below is the C function and a short .asm file on top the DSP/BIOS.
Thanks.
...........................
.global _GetDnum
_GetDnum:
BNOP B3, 3
MVC DNUM, B4
MV B4, A4
.....................
#include <c6x.h>
#include "singleimagecfg.h"
#include <clk.h>
/* The references are statically defined in configuration file */
extern Int HEAP;
#define NUMMSGS 3 /* number of messages */
#define NUMWRITERS 3 /* number of writer tasks created with Config Tool */
typedef struct MsgObj {
QUE_Elem elem; /* first field for QUE */
Int id; /* writer task id */
Char val; /* message value */
}
MsgObj, *Msg;
Void reader();
Void writer(Arg id_arg);
Uns
GetDnum( void ); // assembly function to extract Device ID for this core at run-time
/* Define the QUEs used for sending messages between TSKs */
QUE_Obj
msgQueue;
QUE_Obj
freeQueue;
Uns
StartTime, EndTime;
Uns
nWriterCnt = 0;
Uns
nIdlEntries = 0;
void
IDL_testfunc()
{
nIdlEntries++;
}
/*
* ======== main ========
*/
Void main()
{
Int i;
MsgObj *msg;
Uns mask;
StartTime=
CLK_gethtime(); // get start time for benchmarking
LOG_printf(&trace, "Core %d: singleimage example started.\n", GetDnum() );
/* initialize QUE objects */
QUE_new(&msgQueue);
QUE_new(&freeQueue);
mask = TRC_LOGTSK | TRC_LOGSWI | TRC_STSSWI | TRC_LOGCLK;
TRC_enable(TRC_GBLHOST | TRC_GBLTARG | mask);
msg = (
MsgObj *)MEM_alloc(HEAP, NUMMSGS * sizeof(MsgObj), 0);
if (msg == MEM_ILLEGAL) {
SYS_abort("Memory allocation failed!\n");
}
/* Put all messages on freequeue */
for (i = 0; i < NUMMSGS; msg++, i++) {
QUE_put(&freeQueue, msg);
}
}
/*
* ======== reader ========
*/
Void reader()
{
Msg msg;
Int i;
LOG_printf(&trace, "Core %d: reader start.", GetDnum());
LOG_printf(&trace, "Initial passes through IDL loop: %d.", nIdlEntries);
/* initialize time to current time to obtain STS data */
TSK_settime(TSK_self());
for (i = 0; i < NUMMSGS * NUMWRITERS; i++) {
/*
* Wait for semaphore to be posted by writer().
*/
SEM_pend(&sem, SYS_FOREVER);
/* dequeue message */
msg =
QUE_get(&msgQueue);
/* print value */
LOG_printf(&trace, "read '%c' from (%d).", msg->val, msg->id);
/* free msg */
QUE_put(&freeQueue, msg);
/* get task time since made ready to run */
TSK_deltatime(TSK_self());
}
LOG_printf(&trace, "Core %d: reader done.", GetDnum());
}
/*
* ======== writer ========
*/
Void writer(Arg id_arg)
{
Msg msg;
Int i;
Int id = ArgToInt (id_arg);
LOG_printf(&trace, "Core %d: writer (%d) start.", GetDnum(), id);
/* initialize time to current time to obtain STS data */
TSK_settime(TSK_self());
for (i = 0; i < NUMMSGS; i++) {
/*
* Get msg from the free queue. Since reader is higher priority
* and only blocks on sem, this queue will never be empty.
*/
if (QUE_empty(&freeQueue)) {
SYS_abort("Empty free queue!\n");
}
msg =
QUE_get(&freeQueue);
/* fill in value */
msg->
id = id;
msg->
val = (i & 0xf) + 'a';
LOG_printf(&trace, "(%d) writing '%c' ...", id, msg->val);
/* enqueue message */
QUE_put(&msgQueue, msg);
/* post semaphore */
SEM_post(&sem);
/* get task time for this loop */
TSK_deltatime(TSK_self());
}
EndTime=
CLK_gethtime(); // get end time for benchmarking
LOG_printf(&trace, "Core %d: writer (%d) done.", GetDnum(), id);
LOG_printf(&trace, "Total passes through IDL loop: %d.", nIdlEntries);
LOG_printf(&trace, "Core %d: time: %x.", GetDnum(), EndTime-StartTime);
LOG_printf(&trace, "Core %d: avgt: %x.", GetDnum(), (EndTime-StartTime)/(id+1));
}
/*
* singleimage.c
*/
Hi,
I have the specific question here. Does HST relate to LOG_printf() function? If not, what function in the .C file (or .asm file) call HST?
Robert,
In DSP/BIOS the HST module was used to send data (including LOG records) from the DSP to the debugger for display. This was managed automatically for the application, via a “data pump” mechanism that ran in the IDL loop. Neither LOG nor the application would make calls to do this, but it was done by a function (LNK_F_dataPump) automatically inserted into the IDL loop when real-time analysis (RTA) was enabled for the app. This data pump would send the data to the debugger during CPU idle time, so as not to disturb real-time execution.
Applications could use HST to send/received data to/from the debugger for other purposes too, but this was not done very often. Looking at the code you are porting, that was not the case for your app. HST was used only for transporting the records accumulated into LOG buffers over to the debugger.
So... for porting your app to SYS/BIOS you don’t need to do anything to explicitly replace HST for your application. In SYS/BIOS the “RTA Agent” described in the instrumentation chapter replaces the functionality of HST.
Does this make sense?
Scott
Hi,
Your reply is helpful, but I stll have some problems. The .C file has a reader() function, see below dot line please. I do not know how to deal with "&trace" in tools RTA Agent supports. I have tried GUI of .cfg to get a "trace" creation, but it fails. Which function such as "Log_print1" or other function to substitute LOG_printf?
The main() function is also attached below reader(). It has such lines:
mask = TRC_LOGTSK | TRC_LOGSWI | TRC_STSSWI | TRC_LOGCLK;
TRC_enable(TRC_GBLHOST | TRC_GBLTARG | mask);
How do I do in SYS/BIOS 6?
I also created a small project from SYS/BIOS 6's LOG example. Unfortunately it only uses
Log_info2("tsk0 Entering. arg0,1 = %d %d", (Int)arg0, (Int)arg1);
I do see Raw Logs content of the LOG example, but it is different from the question of event logging.
That is, I have not seen any Log event example similar to my question yet. Could you tell me further information at logging data, such as that in reader()?
Thanks again.
..................
Void reader()
{
Msg msg;
Int i;
LOG_printf(&trace, "Core %d: reader start.", GetDnum());
LOG_printf(&trace, "Initial passes through IDL loop: %d.", nIdlEntries);
* initialize time to current time to obtain STS data */
TSK_settime(TSK_self());
for (i = 0; i < NUMMSGS * NUMWRITERS; i++) {
/* * Wait for semaphore to be posted by writer(). */
SEM_pend(&sem, SYS_FOREVER);
/* dequeue message */
msg =QUE_get(&msgQueue);
/* print value */
LOG_printf(&trace, "read '%c' from (%d).", msg->val, msg->id);
/* free msg */
QUE_put(&freeQueue, msg);
/* get task time since made ready to run */
TSK_deltatime(TSK_self());
}
LOG_printf(&trace, "Core %d: reader done.", GetDnum());
}
.....................
Void main()
{
Int i;
MsgObj *msg;
Uns mask;
StartTime=CLK_gethtime();
// get start time for benchmarking
LOG_printf(&trace, "Core %d: singleimage example started.\n", GetDnum() );
/* initialize QUE objects */
QUE_new(&msgQueue);
QUE_new(&freeQueue);
mask = TRC_LOGTSK | TRC_LOGSWI | TRC_STSSWI | TRC_LOGCLK;
TRC_enable(TRC_GBLHOST | TRC_GBLTARG | mask);
msg = (MsgObj *)MEM_alloc(HEAP, NUMMSGS * sizeof(MsgObj), 0);
if (msg == MEM_ILLEGAL) {
SYS_abort("Memory allocation failed!\n");
}
/* Put all messages on freequeue */
for (i = 0; i < NUMMSGS; msg++, i++) {
QUE_put(&freeQueue, msg);
}
}
Robert,
Regarding configuration of "trace": please see section 8.1.3.1 “Converting the Log Configuration Code” in that migration app note.
For controlling the logging from individual modules at runtime: the replacement for the TRC module is the xdc.runtime.Diags module.
There is some description of controlling the Diags mask values at runtime via the RTA control panel in the instrumentation chapter in BIOS_User_Guide.pdf.
None of the SYS/BIOS examples show usage of enabling/disabling the different event types from the target at runtime. But you can see some example snippets (using the Diags_setMask() API) on this page: http://rtsc.eclipse.org/cdoc-tip/xdc/runtime/Diags.html
Also, you can find a very detailed description of the new logging facilities used in SYS/BIOS here: http://rtsc.eclipse.org/docs-tip/Using_xdc.runtime_Logging
Scott