Forums

C6713 C programming environment question and problem with periodic function.

Started by jleslie48 April 9, 2007

I'm have an issue programming my DsP and I'd like to confirm
that my understanding of the runstream is correct, and then
address my current problem.

First I'm using Code Composer v3.3 on Windows_XP.

There are 3 components I'm aware of in this test program I'm working
with,
the Main Program,
a TSK_function01 and
a PRD_function02

The TSK_function01 and the PRD_function02 are not called by the main
function
but rather set up to run via some scheduler environment that I control
via the
DSP/BIOS Config section of the project and stored as a .tcf file.

In the DSP/Bios Config, the tcf file can be clicked on and among other
settings
the SCHEDULING setup controls PRD and TSK functions, it this correct?

The TSK Task manager sets up a function _TSK_function01 (you have to
add an underscore?)
and the
PRD Periodic function manager,  seems to be similiar only it has in
this example has
a reference to a PRD_test with properties that include the function
function _PRD_function02
(again its added an underscore to the beginning of the name?) Now this
PRD_test also seems to
have properties that define it to run every 5000 ticks, and a mode
continuous.  So I'm assuming
that this is a do forever handler that wakes up every 5000 ticks (ms)
aka every 5 seconds and
executes.

The main program seems to house a few init calls, and more importantly
a
fopen to my diagnostic UART:

FILE  *fid;

void main (void)
{


    CSL_init(); cslCfgInit();
    /* initialize CPU and on-board hardware */
    C6xCptInit (&sC6713CptInitRegs);

    /* initialize the stdio interface to use on-board UART */
    StdioifInit ();

  	// open Uart device
	fid = fopen ("UART:DummyName", "w");

	fprintf (fid, "Main done. build:" __DATE__" " __TIME__ "\r\n");
    fflush (fid);
}


Please note that the file variable fid is global to the entire
program.

The main program seems to run and complete without incident, and
TSK_function01 has
in it a do forever loop of echoing an fprintf "I'm alive"  as well.

However, the PRD_function02 only works as long as no fprintf/ fflush
is in it.  the
fflush command seems to hang the system and even suspends the
TSK_function01.
If I comment out the fprintf/fflush out of PRD_function02:

void PRD_function02(void)
{
	static unsigned int i = 0;

	i++;

    fprintf (fid, "PRD_TestFunction() completed. Iteration %d\r\n",
i);
    fflush (fid);

}

all works well.  every 5 seconds  it wakes up and increments i.
however if I leave in the fprintf/ fflush
statement, the fflush never comes back.  I thought at first it was
some collision with the TSK_function01
fprintf's, but if I comment out the fprintf/fflush statements out of
TSK_function01,
PRD_function02 still won't work.

I'm also a bit confused about the main program completing, is this a
normal paradigm for DSP
programming?

TIA,

Jon

jleslie48 wrote:
> > I'm have an issue programming my DsP and I'd like to confirm > that my understanding of the runstream is correct, and then > address my current problem. > > First I'm using Code Composer v3.3 on Windows_XP. > > There are 3 components I'm aware of in this test program I'm working > with, > the Main Program, > a TSK_function01 and > a PRD_function02 > > The TSK_function01 and the PRD_function02 are not called by the main > function > but rather set up to run via some scheduler environment that I control > via the > DSP/BIOS Config section of the project and stored as a .tcf file. > > In the DSP/Bios Config, the tcf file can be clicked on and among other > settings > the SCHEDULING setup controls PRD and TSK functions, it this correct?
Yes, that's correct.
> > The TSK Task manager sets up a function _TSK_function01 (you have to > add an underscore?)
The C compiler takes any variable/function names and when generating the assembly equivalent code all of the assembler symbols have a preceding underscore. So for example, my_function and my_var will have corresponding assembler symbols/labels _my_function and _my_var. In the DSP/BIOS configuration tool you need to give it the assembler label since it could be a C function or an assembly function being invoked.
> and the > PRD Periodic function manager, seems to be similiar only it has in > this example has > a reference to a PRD_test with properties that include the function > function _PRD_function02 > (again its added an underscore to the beginning of the name?) Now this > PRD_test also seems to > have properties that define it to run every 5000 ticks, and a mode > continuous. So I'm assuming > that this is a do forever handler that wakes up every 5000 ticks (ms) > aka every 5 seconds and > executes. >
Sounds right. The "tick" is defined in the CLK Manager Properties and then each PRD would be created in units of "ticks" corresponding to what you setup. One millisecond is a typical value for a tick.
> The main program seems to house a few init calls, and more importantly > a > fopen to my diagnostic UART:
Since the 6713 does not have a UART, how are you doing this? Do you have an external device hooked to the EMIF or are you putting on some wrapper code to use the McBSP as a UART?
> FILE *fid; > > void main (void) > { > > > CSL_init(); cslCfgInit(); > /* initialize CPU and on-board hardware */ > C6xCptInit (&sC6713CptInitRegs); > > /* initialize the stdio interface to use on-board UART */ > StdioifInit (); > > // open Uart device > fid = fopen ("UART:DummyName", "w"); > > fprintf (fid, "Main done. build:" __DATE__" " __TIME__ "\r\n"); > fflush (fid); > } > > > Please note that the file variable fid is global to the entire > program. > > The main program seems to run and complete without incident, and > TSK_function01 has > in it a do forever loop of echoing an fprintf "I'm alive" as well. > > However, the PRD_function02 only works as long as no fprintf/ fflush > is in it. the > fflush command seems to hang the system and even suspends the > TSK_function01. > If I comment out the fprintf/fflush out of PRD_function02: > > void PRD_function02(void) > { > static unsigned int i = 0; > > i++; > > fprintf (fid, "PRD_TestFunction() completed. Iteration %d\r\n", > i); > fflush (fid); > > } > > all works well. every 5 seconds it wakes up and increments i. > however if I leave in the fprintf/ fflush > statement, the fflush never comes back. I thought at first it was > some collision with the TSK_function01 > fprintf's, but if I comment out the fprintf/fflush statements out of > TSK_function01, > PRD_function02 still won't work. >
I would suggest that rather than trying to use fprintf that you instead use LOG_printf from BIOS. You will need to insert a LOG object in your DSP/BIOS configuration file, e.g. trace. Then in your code you can do something like: LOG_printf(&trace, "Iteration %i", i); This information will then be sent IN REAL TIME (i.e. without halting the processor for the transfer) and in far fewer cycles than fprintf. You view this info in CCS by going to DSP/BIOS -> Message Log and then selecting the "trace" message log that you created.
> I'm also a bit confused about the main program completing, is this a > normal paradigm for DSP > programming?
The "normal" paradigm is to have a while(1) loop in main. This is how it gets implemented when using BIOS though. In BIOS main is used for you to put in configuration code. You then return from main such that the BIOS kernel can take over.
> > TIA, > > Jon >
On Apr 9, 7:18 pm, Brad Griffis <bradgrif...@hotmail.com> wrote:
> jleslie48 wrote: > > > I'm have an issue programming my DsP and I'd like to confirm > > that my understanding of the runstream is correct, and then > > address my current problem. > > > First I'm using Code Composer v3.3 on Windows_XP. > > > There are 3 components I'm aware of in this test program I'm working > > with, > > the Main Program, > > a TSK_function01 and > > a PRD_function02 > > > The TSK_function01 and the PRD_function02 are not called by the main > > function > > but rather set up to run via some scheduler environment that I control > > via the > > DSP/BIOS Config section of the project and stored as a .tcf file. > > > In the DSP/Bios Config, the tcf file can be clicked on and among other > > settings > > the SCHEDULING setup controls PRD and TSK functions, it this correct? > > Yes, that's correct. > > > > > The TSK Task manager sets up a function _TSK_function01 (you have to > > add an underscore?) > > The C compiler takes any variable/function names and when generating the > assembly equivalent code all of the assembler symbols have a preceding > underscore. So for example, my_function and my_var will have > corresponding assembler symbols/labels _my_function and _my_var. In the > DSP/BIOS configuration tool you need to give it the assembler label > since it could be a C function or an assembly function being invoked. > > > and the > > PRD Periodic function manager, seems to be similiar only it has in > > this example has > > a reference to a PRD_test with properties that include the function > > function _PRD_function02 > > (again its added an underscore to the beginning of the name?) Now this > > PRD_test also seems to > > have properties that define it to run every 5000 ticks, and a mode > > continuous. So I'm assuming > > that this is a do forever handler that wakes up every 5000 ticks (ms) > > aka every 5 seconds and > > executes. > > Sounds right. The "tick" is defined in the CLK Manager Properties and > then each PRD would be created in units of "ticks" corresponding to what > you setup. One millisecond is a typical value for a tick. > > > The main program seems to house a few init calls, and more importantly > > a > > fopen to my diagnostic UART: > > Since the 6713 does not have a UART, how are you doing this? Do you > have an external device hooked to the EMIF or are you putting on some > wrapper code to use the McBSP as a UART? > > > > > FILE *fid; > > > void main (void) > > { > > > CSL_init(); cslCfgInit(); > > /* initialize CPU and on-board hardware */ > > C6xCptInit (&sC6713CptInitRegs); > > > /* initialize the stdio interface to use on-board UART */ > > StdioifInit (); > > > // open Uart device > > fid = fopen ("UART:DummyName", "w"); > > > fprintf (fid, "Main done. build:" __DATE__" " __TIME__ "\r\n"); > > fflush (fid); > > } > > > Please note that the file variable fid is global to the entire > > program. > > > The main program seems to run and complete without incident, and > > TSK_function01 has > > in it a do forever loop of echoing an fprintf "I'm alive" as well. > > > However, the PRD_function02 only works as long as no fprintf/ fflush > > is in it. the > > fflush command seems to hang the system and even suspends the > > TSK_function01. > > If I comment out the fprintf/fflush out of PRD_function02: > > > void PRD_function02(void) > > { > > static unsigned int i = 0; > > > i++; > > > fprintf (fid, "PRD_TestFunction() completed. Iteration %d\r\n", > > i); > > fflush (fid); > > > } > > > all works well. every 5 seconds it wakes up and increments i. > > however if I leave in the fprintf/ fflush > > statement, the fflush never comes back. I thought at first it was > > some collision with the TSK_function01 > > fprintf's, but if I comment out the fprintf/fflush statements out of > > TSK_function01, > > PRD_function02 still won't work. > > I would suggest that rather than trying to use fprintf that you instead > use LOG_printf from BIOS. You will need to insert a LOG object in your > DSP/BIOS configuration file, e.g. trace. Then in your code you can do > something like: > > LOG_printf(&trace, "Iteration %i", i); > > This information will then be sent IN REAL TIME (i.e. without halting > the processor for the transfer) and in far fewer cycles than fprintf. > You view this info in CCS by going to DSP/BIOS -> Message Log and then > selecting the "trace" message log that you created. > > > I'm also a bit confused about the main program completing, is this a > > normal paradigm for DSP > > programming? > > The "normal" paradigm is to have a while(1) loop in main. This is how > it gets implemented when using BIOS though. In BIOS main is used for > you to put in configuration code. You then return from main such that > the BIOS kernel can take over. > > > > > TIA, > > > Jon
Ahh, Thank you for the confirmation of my conclusions. I wish there was a real beginners guide somewhere. Anyway, the uart is part of the wrapped up DSP solution that was configured/built for this project, in fact I have three uarts, one "hard" UART on the power supply board (thats this one) and two soft ones I'm still waiting for some level shifters to come in to start using. Looking forward to figuring out how they are supposed to work seeing how the fopen doesn't seem to have any reference to the hard UART but just magically works (well at least in main and tsk functions) The sample programs that I started with used the fprintf, so I am just continuing in that fashion, I will see about converting over to LOG_xxx utility. I'm not so much concerned about communicating on the UART's in real time, but I do want to be able to communcate from prd_functions, I can't imagine why the LOG_xxx functions would work better, but then again I don't have a reason the fprintf is not working in the first place. </scratches head...> Your confirmation about the underscore with the PRD and TSK has me thinking that maybe the variable fid, while global in a pure K&R C Unix world is perfectly acceptable, I wondering if some sort of _fid needs to be set up just like the functions, or can I send the file pointer in as a variable? I haven't figured out parameter passing yet. So with the CLK manager I can set the basic time units to microseconds rather than milliseconds? That will be critical for this project. I need finer granularity than milliseconds on some periodic checks and updates. I was shocked when I saw main() end. this is a very foreign environment to me. I don't program with this thinking and I'm trying to apply my experiences to what I'm seeing in the samples supplied and how I'm going to get my project to work. I would of had the do forever (while(1) as you call it) in the main(), and tsks just be functions called by main; I don't see the need for a "TASK" manager at all. Now the PRD function generator is another story. Having a thread just to push out signals or monitor status bits clean and accurately going in real measurable time, is what I bought this beast for. Thanks again, Jon
jleslie48 wrote:
> On Apr 9, 7:18 pm, Brad Griffis <bradgrif...@hotmail.com> wrote: >> jleslie48 wrote: >> >>> I'm have an issue programming my DsP and I'd like to confirm >>> that my understanding of the runstream is correct, and then >>> address my current problem. >>> First I'm using Code Composer v3.3 on Windows_XP. >>> There are 3 components I'm aware of in this test program I'm working >>> with, >>> the Main Program, >>> a TSK_function01 and >>> a PRD_function02 >>> The TSK_function01 and the PRD_function02 are not called by the main >>> function >>> but rather set up to run via some scheduler environment that I control >>> via the >>> DSP/BIOS Config section of the project and stored as a .tcf file. >>> In the DSP/Bios Config, the tcf file can be clicked on and among other >>> settings >>> the SCHEDULING setup controls PRD and TSK functions, it this correct? >> Yes, that's correct. >> >> >> >>> The TSK Task manager sets up a function _TSK_function01 (you have to >>> add an underscore?) >> The C compiler takes any variable/function names and when generating the >> assembly equivalent code all of the assembler symbols have a preceding >> underscore. So for example, my_function and my_var will have >> corresponding assembler symbols/labels _my_function and _my_var. In the >> DSP/BIOS configuration tool you need to give it the assembler label >> since it could be a C function or an assembly function being invoked. >> >>> and the >>> PRD Periodic function manager, seems to be similiar only it has in >>> this example has >>> a reference to a PRD_test with properties that include the function >>> function _PRD_function02 >>> (again its added an underscore to the beginning of the name?) Now this >>> PRD_test also seems to >>> have properties that define it to run every 5000 ticks, and a mode >>> continuous. So I'm assuming >>> that this is a do forever handler that wakes up every 5000 ticks (ms) >>> aka every 5 seconds and >>> executes. >> Sounds right. The "tick" is defined in the CLK Manager Properties and >> then each PRD would be created in units of "ticks" corresponding to what >> you setup. One millisecond is a typical value for a tick. >> >>> The main program seems to house a few init calls, and more importantly >>> a >>> fopen to my diagnostic UART: >> Since the 6713 does not have a UART, how are you doing this? Do you >> have an external device hooked to the EMIF or are you putting on some >> wrapper code to use the McBSP as a UART? >> >> >> >>> FILE *fid; >>> void main (void) >>> { >>> CSL_init(); cslCfgInit(); >>> /* initialize CPU and on-board hardware */ >>> C6xCptInit (&sC6713CptInitRegs); >>> /* initialize the stdio interface to use on-board UART */ >>> StdioifInit (); >>> // open Uart device >>> fid = fopen ("UART:DummyName", "w"); >>> fprintf (fid, "Main done. build:" __DATE__" " __TIME__ "\r\n"); >>> fflush (fid); >>> } >>> Please note that the file variable fid is global to the entire >>> program. >>> The main program seems to run and complete without incident, and >>> TSK_function01 has >>> in it a do forever loop of echoing an fprintf "I'm alive" as well. >>> However, the PRD_function02 only works as long as no fprintf/ fflush >>> is in it. the >>> fflush command seems to hang the system and even suspends the >>> TSK_function01. >>> If I comment out the fprintf/fflush out of PRD_function02: >>> void PRD_function02(void) >>> { >>> static unsigned int i = 0; >>> i++; >>> fprintf (fid, "PRD_TestFunction() completed. Iteration %d\r\n", >>> i); >>> fflush (fid); >>> } >>> all works well. every 5 seconds it wakes up and increments i. >>> however if I leave in the fprintf/ fflush >>> statement, the fflush never comes back. I thought at first it was >>> some collision with the TSK_function01 >>> fprintf's, but if I comment out the fprintf/fflush statements out of >>> TSK_function01, >>> PRD_function02 still won't work. >> I would suggest that rather than trying to use fprintf that you instead >> use LOG_printf from BIOS. You will need to insert a LOG object in your >> DSP/BIOS configuration file, e.g. trace. Then in your code you can do >> something like: >> >> LOG_printf(&trace, "Iteration %i", i); >> >> This information will then be sent IN REAL TIME (i.e. without halting >> the processor for the transfer) and in far fewer cycles than fprintf. >> You view this info in CCS by going to DSP/BIOS -> Message Log and then >> selecting the "trace" message log that you created. >> >>> I'm also a bit confused about the main program completing, is this a >>> normal paradigm for DSP >>> programming? >> The "normal" paradigm is to have a while(1) loop in main. This is how >> it gets implemented when using BIOS though. In BIOS main is used for >> you to put in configuration code. You then return from main such that >> the BIOS kernel can take over. >> >> >> >>> TIA, >>> Jon > > Ahh, > > Thank you for the confirmation of my conclusions. I wish there was a > real beginners guide somewhere. Anyway, the uart is part of the > wrapped up DSP solution that was configured/built for this project, in > fact I have three uarts, one "hard" UART on the power supply board > (thats this one) and two soft ones I'm still waiting for some level > shifters to come in to start using. Looking forward to figuring out > how they are supposed to work seeing how the fopen doesn't seem to > have any reference to the hard UART but just magically works (well at > least in main and tsk functions) > > The sample programs that I started with used the fprintf, so I am just > continuing in that fashion, I will see about converting over to > LOG_xxx utility. I'm not so much concerned about communicating on the > UART's in real time, but I do want to be able to communcate from > prd_functions, I can't imagine why the LOG_xxx functions would work > better, but then again I don't have a reason the fprintf is not > working in the first place. </scratches head...> >
The fprintf can take 1000s of cycles for all the string formatting, etc. and it also will actually cause the processor to momentarily halt to do the data transfer over JTAG. I'm not sure what it does if you're using a UART. I didn't even realize it supported a UART on these DSPs! The LOG_printf takes only 10s of cycles comparatively and the string formatting is done on the host/PC side. Only the arguments get passed. This allows the DSP to focus on real-time computation rather than things like string formatting which are much better suited to PCs. I believe the fprintf functions use some kind of lock. I think these particular functions have some non-reentrant code which requires the use of the lock. That's probably what's hanging the system, i.e. some kind of deadlock condition.
> Your confirmation about the underscore with the PRD and TSK has me > thinking that maybe the variable fid, while global in a pure K&R C > Unix world is perfectly acceptable, I wondering if some sort of _fid > needs to be set up just like the functions, or can I send the file > pointer in as a variable? I haven't figured out parameter passing > yet. > > > So with the CLK manager I can set the basic time units to microseconds > rather than milliseconds?
Yes, you can do this. You want to understand how this works though. DSP/BIOS configures one of the CPU timers to produce a periodic interrupt. This is the "tick" that you configure. If you configure to be a microsecond then that means that every microsecond a hardware interrupt will occur causing pre-emption and the DSP/BIOS kernel to execute. There is some modest overhead involved here so you don't want this to run excessively or it will chew up a lot of CPU cycles. For that reason a millisecond is generally a good choice for the tick. It still gives decent resolution though without too many interrupts occuring at the CPU level.
> > That will be critical for this project. I need finer granularity than > milliseconds on some periodic checks and updates.
Do you need to *time* something with better granularity or do you need interrupts at better granularity? If you're looking to time something you can put a pair of calls to CLK_gethtime() around a piece of code and that find the delta of the two calls. That will give you granularity at the same level as the timer which drives the tick (I believe that's CPU/2).
> > I was shocked when I saw main() end. this is a very foreign > environment to me. I don't program with this thinking and I'm trying > to apply my experiences to what I'm seeing in the samples supplied and > how I'm going to get my project to work. I would of had the do > forever (while(1) as you call it) in the main(), and tsks just be > functions called by main; I don't see the need for a "TASK" manager at > all.
Yes, it is a little bit different looking. To visualize it better imagine that the engineers who wrote DSP/BIOS created a while(1) loop in their code and that their code calls main just before entering into that while(1) loop. That's actually exactly how it works.
> > Now the PRD function generator is another story. Having a thread just > to push out signals or monitor status bits clean and accurately going > in real measurable time, is what I bought this beast for. >
If you're looking for real-time behavior then don't spend 100s or 1000s of cycles in your fprintf. That's generally something in the PC world and not the DSP world. The "embedded" fprintf would be to toggle a specific GPIO pin. The more sophisticated embedded method is to use LOG_printf as that only takes 10s of cycles but gives you readable text on the other end. Note, if you're having issues with this you may want to just go the GPIO route.
> Thanks again, > > Jon >
No problem. Good luck.
On Apr 10, 12:36 am, Brad Griffis <bradgrif...@hotmail.com> wrote:
> jleslie48 wrote: > > On Apr 9, 7:18 pm, Brad Griffis <bradgrif...@hotmail.com> wrote: > >> jleslie48 wrote: > > >>> I'm have an issue programming my DsP and I'd like to confirm > >>> that my understanding of the runstream is correct, and then > >>> address my current problem. > >>> First I'm using Code Composer v3.3 on Windows_XP. > >>> There are 3 components I'm aware of in this test program I'm working > >>> with, > >>> the Main Program, > >>> a TSK_function01 and > >>> a PRD_function02 > >>> The TSK_function01 and the PRD_function02 are not called by the main > >>> function > >>> but rather set up to run via some scheduler environment that I control > >>> via the > >>> DSP/BIOS Config section of the project and stored as a .tcf file. > >>> In the DSP/Bios Config, the tcf file can be clicked on and among other > >>> settings > >>> the SCHEDULING setup controls PRD and TSK functions, it this correct? > >> Yes, that's correct. > > >>> The TSK Task manager sets up a function _TSK_function01 (you have to > >>> add an underscore?) > >> The C compiler takes any variable/function names and when generating the > >> assembly equivalent code all of the assembler symbols have a preceding > >> underscore. So for example, my_function and my_var will have > >> corresponding assembler symbols/labels _my_function and _my_var. In the > >> DSP/BIOS configuration tool you need to give it the assembler label > >> since it could be a C function or an assembly function being invoked. > > >>> and the > >>> PRD Periodic function manager, seems to be similiar only it has in > >>> this example has > >>> a reference to a PRD_test with properties that include the function > >>> function _PRD_function02 > >>> (again its added an underscore to the beginning of the name?) Now this > >>> PRD_test also seems to > >>> have properties that define it to run every 5000 ticks, and a mode > >>> continuous. So I'm assuming > >>> that this is a do forever handler that wakes up every 5000 ticks (ms) > >>> aka every 5 seconds and > >>> executes. > >> Sounds right. The "tick" is defined in the CLK Manager Properties and > >> then each PRD would be created in units of "ticks" corresponding to what > >> you setup. One millisecond is a typical value for a tick. > > >>> The main program seems to house a few init calls, and more importantly > >>> a > >>> fopen to my diagnostic UART: > >> Since the 6713 does not have a UART, how are you doing this? Do you > >> have an external device hooked to the EMIF or are you putting on some > >> wrapper code to use the McBSP as a UART? > > >>> FILE *fid; > >>> void main (void) > >>> { > >>> CSL_init(); cslCfgInit(); > >>> /* initialize CPU and on-board hardware */ > >>> C6xCptInit (&sC6713CptInitRegs); > >>> /* initialize the stdio interface to use on-board UART */ > >>> StdioifInit (); > >>> // open Uart device > >>> fid = fopen ("UART:DummyName", "w"); > >>> fprintf (fid, "Main done. build:" __DATE__" " __TIME__ "\r\n"); > >>> fflush (fid); > >>> } > >>> Please note that the file variable fid is global to the entire > >>> program. > >>> The main program seems to run and complete without incident, and > >>> TSK_function01 has > >>> in it a do forever loop of echoing an fprintf "I'm alive" as well. > >>> However, the PRD_function02 only works as long as no fprintf/ fflush > >>> is in it. the > >>> fflush command seems to hang the system and even suspends the > >>> TSK_function01. > >>> If I comment out the fprintf/fflush out of PRD_function02: > >>> void PRD_function02(void) > >>> { > >>> static unsigned int i = 0; > >>> i++; > >>> fprintf (fid, "PRD_TestFunction() completed. Iteration %d\r\n", > >>> i); > >>> fflush (fid); > >>> } > >>> all works well. every 5 seconds it wakes up and increments i. > >>> however if I leave in the fprintf/ fflush > >>> statement, the fflush never comes back. I thought at first it was > >>> some collision with the TSK_function01 > >>> fprintf's, but if I comment out the fprintf/fflush statements out of > >>> TSK_function01, > >>> PRD_function02 still won't work. > >> I would suggest that rather than trying to use fprintf that you instead > >> use LOG_printf from BIOS. You will need to insert a LOG object in your > >> DSP/BIOS configuration file, e.g. trace. Then in your code you can do > >> something like: > > >> LOG_printf(&trace, "Iteration %i", i); > > >> This information will then be sent IN REAL TIME (i.e. without halting > >> the processor for the transfer) and in far fewer cycles than fprintf. > >> You view this info in CCS by going to DSP/BIOS -> Message Log and then > >> selecting the "trace" message log that you created. > > >>> I'm also a bit confused about the main program completing, is this a > >>> normal paradigm for DSP > >>> programming? > >> The "normal" paradigm is to have a while(1) loop in main. This is how > >> it gets implemented when using BIOS though. In BIOS main is used for > >> you to put in configuration code. You then return from main such that > >> the BIOS kernel can take over. > > >>> TIA, > >>> Jon > > > Ahh, > > > Thank you for the confirmation of my conclusions. I wish there was a > > real beginners guide somewhere. Anyway, the uart is part of the > > wrapped up DSP solution that was configured/built for this project, in > > fact I have three uarts, one "hard" UART on the power supply board > > (thats this one) and two soft ones I'm still waiting for some level > > shifters to come in to start using. Looking forward to figuring out > > how they are supposed to work seeing how the fopen doesn't seem to > > have any reference to the hard UART but just magically works (well at > > least in main and tsk functions) > > > The sample programs that I started with used the fprintf, so I am just > > continuing in that fashion, I will see about converting over to > > LOG_xxx utility. I'm not so much concerned about communicating on the > > UART's in real time, but I do want to be able to communcate from > > prd_functions, I can't imagine why the LOG_xxx functions would work > > better, but then again I don't have a reason the fprintf is not > > working in the first place. </scratches head...> > > The fprintf can take 1000s of cycles for all the string formatting, etc. > and it also will actually cause the processor to momentarily halt to do > the data transfer over JTAG. I'm not sure what it does if you're using > a UART. I didn't even realize it supported a UART on these DSPs! > > The LOG_printf takes only 10s of cycles comparatively and the string > formatting is done on the host/PC side. Only the arguments get passed. > This allows the DSP to focus on real-time computation rather than > things like string formatting which are much better suited to PCs. > > I believe the fprintf functions use some kind of lock. I think these > particular functions have some non-reentrant code which requires the use > of the lock. That's probably what's hanging the system, i.e. some kind > of deadlock condition. > > > Your confirmation about the underscore with the PRD and TSK has me > > thinking that maybe the variable fid, while global in a pure K&R C > > Unix world is perfectly acceptable, I wondering if some sort of _fid > > needs to be set up just like the functions, or can I send the file > > pointer in as a variable? I haven't figured out parameter passing > > yet. > > > So with the CLK manager I can set the basic time units to microseconds > > rather than milliseconds? > > Yes, you can do this. You want to understand how this works though. > DSP/BIOS configures one of the CPU timers to produce a periodic > interrupt. This is the "tick" that you configure. If you configure to > be a microsecond then that means that every microsecond a hardware > interrupt will occur causing pre-emption and the DSP/BIOS kernel to > execute. There is some modest overhead involved here so you don't want > this to run excessively or it will chew up a lot of CPU cycles. For > that reason a millisecond is generally a good choice for the tick. It > still gives decent resolution though without too many interrupts > occuring at the CPU level. > > > > > That will be critical for this project. I need finer granularity than > > milliseconds on some periodic checks and updates. > > Do you need to *time* something with better granularity or do you need > interrupts at better granularity? If you're looking to time something > you can put a pair of calls to CLK_gethtime() around a piece of code and > that find the delta of the two calls. That will give you granularity at > the same level as the timer which drives the tick (I believe that's CPU/2). > > > > > I was shocked when I saw main() end. this is a very foreign > > environment to me. I don't program with this thinking and I'm trying > > to apply my experiences to what I'm seeing in the samples supplied and > > how I'm going to get my project to work. I would of had the do > > forever (while(1) as you call it) in the main(), and tsks just be > > functions called by main; I don't see the need for a "TASK" manager at > > all. > > Yes, it is a little bit different looking. To visualize it better > imagine that the engineers who wrote DSP/BIOS created a while(1) loop in > their code and that their code calls main just before entering into that > while(1) loop. That's actually exactly how it works. > > > > > Now the PRD function generator is another story. Having a thread just > > to push out signals or monitor status bits clean and accurately going > > in real measurable time, is what I bought this beast for. > > If you're looking for real-time behavior then don't spend 100s or 1000s > of cycles in your fprintf. That's generally something in the PC world > and not the DSP world. The "embedded" fprintf would be to toggle a > specific GPIO pin. The more sophisticated embedded method is to use > LOG_printf as that only takes 10s of cycles but gives you readable text > on the other end. Note, if you're having issues with this you may want > to just go the GPIO route. > > > Thanks again, > > > Jon > > No problem. Good luck.
> imagine that the engineers who wrote DSP/BIOS created a while(1) loop in > their code and that their code calls main just before entering into that > while(1) loop. That's actually exactly how it works.
- thats a good working model, I will keep that in mind. I still would of liked them to just keep in the framework of the 35+ year old main() controls your process. Makes finding things a whole lot simplier. Search for main() in your C files and start looking from the there. Now your programs flow is all over the place. I'm going to need a periodic function to send out pulse signals with exact timings. For example say on pin C11 I will want to to send out a 500hz signal where the pulse width is 25microseconds, and I want this signal to last for 5 seconds. I had imagined establishing an array of 2 tuples such as: const int fivehundredhz = [ 2,2000 1,25, 0,1975, ]; where the periodic function now has a defined pulse function using the 3 elements of the array, the first element tells the number of entries followed by the total number of ticks of the loop. each of the elements shows the signal value and then the number of microseconds I want to broadcast for. In the above example I have defined my 500 hz signal, with each pulse being 25 microseconds long. to broadcast for 5 seconds, (5000000 microseconds) I would need a function call such as broadcast ( &addrofC11, fivehundredhz, 5000000/2000); and the periodic function would be looping on 1microsecond time intervals (keeping a counter going modulus fivehundredhz[1] and using that value as a lookup to the whether its in fivehundred[2,4,6,8,...] up to fivehundredhz[0] index. I don't know if I explained that too well. the idea is that the periodic function wakes up every 1 microsecond, increments a counter 1,2,3,4,..., 19981999,2000,1, 2,... if the counter is between 1-25 it sets a 1 to C11, if its 26-2000 it sets a 0 (all normalization for index's starting at 0 mutatis mutandis) as described in the array fivehundredhz. I wouldn't dare use an fprintf or even a LOG_ xxx inside this PRD_ function, however the mere fact that I can't suggests I'm overlooking something or misinterpreting something of the architecture, and I want to know what that is. Also I'm sure I will find a need for some other periodic function that works every 15 minutes or so (diagnostic run for example) that I will want it to post to the uart (or the firewire compact flash I have on the system) that will want to use fprintf/ LOG_xxx functions.