a bit of a mystery to me.
main() has completed,
and no other routines seem to be running, at the bottom of my swi
routine I have
the [pseudo] code:
while (1) {
fprintf( something1);
fprintf( something2);
TSK_sleep(any non-zero positive value);
}//while
when I run I get
something1
something2
and then nothing else.
if I comment out the TSK_sleep I get
something1
something2
something1
something2
something1
something2
...
as I should.
Any ideas?
thanks
Jon
TSK_sleep called from a SWI routine never returns.
Started by ●November 13, 2007
Reply by ●November 13, 20072007-11-13
jleslie48 wrote:> a bit of a mystery to me. > > main() has completed, > and no other routines seem to be running, at the bottom of my swi > routine I have > the [pseudo] code: > > while (1) { > fprintf( something1); > fprintf( something2); > > TSK_sleep(any non-zero positive value); > > }//while > > when I run I get > something1 > something2 > > and then nothing else. > > if I comment out the TSK_sleep I get > > something1 > something2 > something1 > something2 > something1 > something2 > ... > > as I should. > > Any ideas?I'm not so much annoyed as I am discouraged. Do you think that the rest of the world can read your mind? What processor are you using? What does TSK_sleep do? Check a timer? Wait for an interrupt? Device-independent ideas: If you wait out a timer (as seems likely), is it running? If you wait for an interrupt, is it enabled? Does one arrive? Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●November 13, 20072007-11-13
On Nov 13, 10:40 am, Jerry Avins <j...@ieee.org> wrote:> jleslie48 wrote: > > a bit of a mystery to me. > > > main() has completed, > > and no other routines seem to be running, at the bottom of my swi > > routine I have > > the [pseudo] code: > > > while (1) { > > fprintf( something1); > > fprintf( something2); > > > TSK_sleep(any non-zero positive value); > > > }//while > > > when I run I get > > something1 > > something2 > > > and then nothing else. > > > if I comment out the TSK_sleep I get > > > something1 > > something2 > > something1 > > something2 > > something1 > > something2 > > ... > > > as I should. > > > Any ideas? > > I'm not so much annoyed as I am discouraged. Do you think that the rest > of the world can read your mind? > > What processor are you using? > What does TSK_sleep do? Check a timer? Wait for an interrupt? > > Device-independent ideas: > If you wait out a timer (as seems likely), is it running? If you wait > for an interrupt, is it enabled? Does one arrive? > > Jerry > -- > Engineering is the art of making what you want from things you can get. > =AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF==AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF= =AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF=AF ooops sorry. its a c6713, I'm using code composer 3.3, in a windows xp environment. I thought TSK_sleep was a standard call that everybody would know. here's the doc on TSK_Sleep: TSK_sleep Delay execution of the current task C Interface Syntax TSK_sleep(nticks); Parameters Uns nticks; /* number of system clock ticks to sleep */ Return Value Void Assembly Interface none Description TSK_sleep changes the current task=EDs mode from TSK_RUNNING to TSK_BLOCKED, and delays its execution for nticks increments of the system clock. The actual time delayed can be up to 1 system clock tick less than timeout due to granularity in system timekeeping. After the specified period of time has elapsed, the task reverts to the TSK_READY mode and is scheduled for execution. A task switch always occurs when calling TSK_sleep if nticks > 0. Constraints and ? TSK_sleep cannot be called from a SWI or HWI, or within a Calling Context TSK_disable / TSK_enable block. ? TSK_sleep cannot be called from the program=EDs main function. ? TSK_sleep should not be called from within an IDL function. Doing so prevents analysis tools from gathering run-time information. ? nticks cannot be SYS_FOREVER. It does state that it can't be used in a SWI (this is my first SWI I'm using) but it also states that it can't be used in a HWI, and I'm pretty sure I've used them in HWI before.
Reply by ●November 13, 20072007-11-13
jleslie48 wrote:> a bit of a mystery to me. > > and no other routines seem to be running, at the bottom of my swi > routine I have[Assuming some sort of TI DSP with DSP/BIOS, ignore this otherwise] It's no mystery. The docs (in spru403) for TSK_sleep state: TSK_sleep cannot be called from a SWI or HWI... Don't do it. Also, an infinite loop in a SWI handler is a serious no-no. There's something wrong with your design! Cheers mark-r --
Reply by ●November 13, 20072007-11-13
jleslie48 wrote:> On Nov 13, 10:40 am, Jerry Avins <j...@ieee.org> wrote: >> jleslie48 wrote: >>> a bit of a mystery to me. >>> main() has completed, >>> and no other routines seem to be running, at the bottom of my swi >>> routine I have >>> the [pseudo] code: >>> while (1) { >>> fprintf( something1); >>> fprintf( something2); >>> TSK_sleep(any non-zero positive value); >>> }//while >>> when I run I get >>> something1 >>> something2 >>> and then nothing else. >>> if I comment out the TSK_sleep I get >>> something1 >>> something2 >>> something1 >>> something2 >>> something1 >>> something2 >>> ... >>> as I should. >>> Any ideas? >> I'm not so much annoyed as I am discouraged. Do you think that the rest >> of the world can read your mind? >> >> What processor are you using? >> What does TSK_sleep do? Check a timer? Wait for an interrupt? >> >> Device-independent ideas: >> If you wait out a timer (as seems likely), is it running? If you wait >> for an interrupt, is it enabled? Does one arrive? >> >> Jerry >> -- >> Engineering is the art of making what you want from things you can get. >> ����������������������������������������������������������������������� > > ooops sorry. its a c6713, I'm using code composer 3.3, in a windows > xp environment. > I thought TSK_sleep was a standard call that everybody would know. > here's the doc on > TSK_Sleep: > > TSK_sleep > Delay execution of the current task > C Interface > Syntax TSK_sleep(nticks); > Parameters Uns nticks; /* number of system clock ticks to sleep */ > Return Value Void > Assembly Interface none > Description TSK_sleep changes the current task�s mode from TSK_RUNNING > to > TSK_BLOCKED, and delays its execution for nticks increments of the > system clock. The actual time delayed can be up to 1 system clock tick > less than timeout due to granularity in system timekeeping. > After the specified period of time has elapsed, the task reverts to > the > TSK_READY mode and is scheduled for execution. > A task switch always occurs when calling TSK_sleep if nticks > 0. > Constraints and ? TSK_sleep cannot be called from a SWI or HWI, or > within a > Calling Context TSK_disable / TSK_enable block. > ? TSK_sleep cannot be called from the program�s main function. > ? TSK_sleep should not be called from within an IDL function. Doing so > prevents analysis tools from gathering run-time information. > ? nticks cannot be SYS_FOREVER. > > It does state that it can't be used in a SWI (this is my first SWI I'm > using) > but it also states that it can't be used in a HWI, and I'm pretty sure > I've used them > in HWI before.TSK_sleep may be a standard call on some compilers, but I'll wager not on most. It seems to me to be an operating-system call. What operating system? Is there a way to count and report ticks? Can you confirm that the ticks clock is alive and well some other way? Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●November 13, 20072007-11-13
On Nov 13, 12:23 pm, Mark Robinson <m...@simsol.co.uk> wrote:> jleslie48 wrote: > > a bit of a mystery to me. > > > and no other routines seem to be running, at the bottom of my swi > > routine I have > > [Assuming some sort of TI DSP with DSP/BIOS, ignore this otherwise] > > It's no mystery. The docs (in spru403) for TSK_sleep state: > > TSK_sleep cannot be called from a SWI or HWI... > > Don't do it. > > Also, an infinite loop in a SWI handler is a serious no-no. There's > something wrong with your design! > > Cheers > > mark-r > > --"Also, an infinite loop in a SWI handler is a serious no-no." NO question. it was a demo program and the code was this when I first got it: while(1); I was shocked to see that. That's why I figured I'd at least set the routine to sleep and release the cpu with a Tsk_sleep, But then I noticed my routine would respond when I tried to halt the program with the shift(F5) command. I still have to try jerry's test on adding another task to see if the clock is still running. working on it...
Reply by ●November 13, 20072007-11-13
jleslie48 wrote:> NO question. it was a demo program and the code was this when I first > got it: > > while(1); >That is really bad. SWIs run at a higher priority than any TSK, so there'd be no way out of this except a HWI. I can't see any reason why anyone would want to do this (except, perhaps, to deliberately stall the program so that a watchdog timer reset the CPU). Was there any explanation for this code?> I was shocked to see that. That's why I figured I'd at least set the > routine to sleep and release > the cpu with a Tsk_sleep,That's not going to work because the TSK scheduler uses a kernel SWI at priority 0 (the lowest) to schedule tasks, so the kernel SWI won't be able to preempt your SWI resulting in deadlock. The warning not to use TSK_sleep in a SWI is genuine.> I still have to try jerry's test on adding another task to see if the > clock is still running. working on it...If you have a CLK handler installed, it will be called because CLK is a HWI, but any PRD module functions will only be called if PRD_swi (the SWI automatically installed by the PRD manager) is a a higher priority than your SWI. If you can post some more of your code it might help to understand the original programmer's reasoning. Cheers mark-r --
Reply by ●November 13, 20072007-11-13
On Nov 13, 2:04 pm, Mark Robinson <m...@simsol.co.uk> wrote:> jleslie48 wrote: > > NO question. it was a demo program and the code was this when I first > > got it: > > > while(1); > > That is really bad. SWIs run at a higher priority than any TSK, so > there'd be no way out of this except a HWI. I can't see any reason > why anyone would want to do this (except, perhaps, to deliberately > stall the program so that a watchdog timer reset the CPU). Was there > any explanation for this code? > > > I was shocked to see that. That's why I figured I'd at least set the > > routine to sleep and release > > the cpu with a Tsk_sleep, > > That's not going to work because the TSK scheduler uses a kernel > SWI at priority 0 (the lowest) to schedule tasks, so the kernel SWI > won't be able to preempt your SWI resulting in deadlock. The warning > not to use TSK_sleep in a SWI is genuine. > > > I still have to try jerry's test on adding another task to see if the > > clock is still running. working on it... > > If you have a CLK handler installed, it will be called because CLK is > a HWI, but any PRD module functions will only be called if PRD_swi (the > SWI automatically installed by the PRD manager) is a a higher priority > than your SWI. > > If you can post some more of your code it might help to understand the > original programmer's reasoning. > > Cheers > > mark-r > > --It was/is a simple demo to show that the firewire reader/writer is working. here's the source, oh shoot, I mis-stated the situation. the swi is not the issue, thie issue is with the tsk, StorageDemoTSK, you'll see the while(forever); loop at the bottom of it. now the TSK_sleep should definitely return, its in the TSK Task Manager slot. below the source is the TCF file: void main(void) { *(int *)EMIF_GCTL = 0x00003060; /* EMIF global control register */ *(int *)EMIF_CE1 = 0x21224412; /* CE1 - 16 Bit flash */ *(int *)EMIF_CE2 = 0x5675D923; /* CE2 - async 32 bit */ *(int *)EMIF_CE3 = 0x5675D913; /* CE3 - async 16 bit */ *(int *)EMIF_CE0 = 0xFFFFFF30; /* CE0 - SDRAM */ CSL_init(); cslCfgInit(); if (*(unsigned char*)0x90110000 & 0x80)/* read hardware config register */ { /* 64MByte SDRAM */ *(int *)EMIF_SDRAMEXT = 0x0004B4A8; *(int *)EMIF_SDRAMTIM = 0x000002BE; *(int *)EMIF_SDRAMCTL = 0x63116000; } else { /* 32MByte SDRAM */ *(int *)EMIF_SDRAMEXT = 0x000534A8; *(int *)EMIF_SDRAMTIM = 0x0000057D; *(int *)EMIF_SDRAMCTL = 0x53116000; } SWI_post(&STORAGE_DEMO_SWI); } and here's the swi routine: void StorageDemoSWI(void) { int iError; /* initialize the stdio interface to use on-board UART */ StdioifInit(); /* open UART device for debug output and input */ fid_write = fopen("UART:DummyName", "w"); fid_read = fopen("UART:DummyName", "r"); /* Display startup message */ fprintf(fid_write, "\r\n\r\n%s\r\n\r\n", acStorageDemoVersion); fprintf (fid_write, "Build: "__DATE__" "__TIME__" \n"); fprintf(fid_write, "Uart demo and Flash write with bios.\r\n"); fflush(fid_write); StdioifFlush(); /* FPGA initialization */ /* Note: future Flash File System version (> V3.1) may already have */ /* loaded the FPGA, so this step is only necessary for FFS V3.1 */ /* We load the FPGA with the full data stream, including the 28 byte*/ /* header. The FPGA skips this header. */ // iError = FpgaLoad(fpga_data, fpga_data_size + 28); // if( iError != FPGA_OK ) // { // fprintf(fid_write, "\r\nCan't load FPGA!%i\r\n",iError); // fflush(fid_write); // StdioifFlush(); // SYS_exit(-1); // } // fprintf(fid_write, "\r\nFPGA loaded successfully.\r\n"); fprintf(fid_write, "\r\nFPGA not loaded successfully.\r\n"); fflush(fid_write); StdioifFlush(); /* We can only initialize the IEEE1394 Embedded API if the FPGA has */ /* been loaded with the micro-line Busmaster BSP or variant thereof. */ if( (iError = IEEE1394Init()) != SUCCESS) { fprintf(fid_write, "IEEE1394 Embedded API initialization failed. (Error 0x%X)\r\n", iError); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } else { fprintf(fid_write, "IEEE1394 Embedded API initialization succeeded.\r\n"); fflush(fid_write); StdioifFlush(); } SBP2Host = (SBP2_HOST_HANDLE *) malloc( sizeof(SBP2_HOST_HANDLE) ); if ( SBP2Host == NULL ) { fprintf(fid_write, "SBP2 host handle memory allocation failed.\r\n"); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } /* Scan the FireWire bus topology */ RefreshTopology( g_asNodeData ); /* Initialize the SBP2 host */ if ( (iError = SBP2Initialize(&SBP2Host)) != SUCCESS ){ fprintf(fid_write, "SBP2 host initialization failed. (Error 0x%X)\r\n", iError); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } else { fprintf(fid_write, "SBP2 host initialization succeeded. \r\n"); fflush(fid_write); StdioifFlush(); } } void StorageDemoTSK(void) { int iDeviceNumber; volatile int iError; FAT32_FILE_NAME sFileName; ULONG j; memset(acReceivedData, 0, LARGE_SAMPLE); iDeviceNumber = DisplayMenu(); /* Connect to the chosen device. */ if( ( iError = SBP2InitDevice(g_asNodeData[iDeviceNumber].hNodeHandle, SBP2Host) ) != SUCCESS ) { fprintf(fid_write, "SBP2 device initialization failed. (Error 0x%X).", iError); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } else { fprintf(fid_write, "SBP2 device initialization succeeded.\r\n"); fflush(fid_write); StdioifFlush(); } /* Check whether device is formatted for FAT32 */ psPD = (FAT32_PARTITION_DETAILS *) malloc( sizeof(FAT32_PARTITION_DETAILS) ); fprintf(fid_write, "Checking device %i for FAT32 file system...", iDeviceNumber); fflush(fid_write); StdioifFlush(); if( (iError = FAT32Discover(SBP2Host, psPD)) != SUCCESS ) { fprintf(fid_write, "failed (Error 0x%X)", iError); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } else { fprintf(fid_write, "succeeded.\r\n"); fflush(fid_write); StdioifFlush(); } psFAT32Host = (FAT32_HOST *) malloc( sizeof(FAT32_HOST) ); if( psFAT32Host == NULL ) { fprintf(fid_write, "FAT32 host handle memory allocation failed.\r\n"); fflush(fid_write); StdioifFlush(); SYS_exit(-1); } /* Choose the partition to access */ if( psPD->sPartitionInfo[0].bIsValidPartition ) { fprintf(fid_write, "Initializing the FAT32 host..."); fflush(fid_write); StdioifFlush(); iError = FAT32Initialize( SBP2Host, psPD->sPartitionInfo[0], psFAT32Host );} if(iError != SUCCESS) { fprintf(fid_write, "failed (Error 0x%X)", iError); fflush(fid_write); StdioifFlush(); SYS_exit(iError); } else { fprintf(fid_write, "succeeded.\r\n"); fflush(fid_write); StdioifFlush(); } /* Generate some sample data to write to the file system */ { char ac[28] = "_-* StorageDemo String *`'\r \n"; for(j=0; j < LARGE_SAMPLE-1; j++) { acSampleData[j] = ac[j % 28]; } acSampleData[LARGE_SAMPLE-1] = '?'; acSampleData[LARGE_SAMPLE-20]= '+'; } fprintf(fid_write, "Starting file I/O test.\r\n"); fflush(fid_write); StdioifFlush(); for(j = 0; j < TEST_ITERATIONS; j++ ) { static int iErrorPrev = SUCCESS; char ac2[5]; sprintf(ac2, "%i", j); iError = FAT32CreateFileName(ac2,"txt", &sFileName); iError = FAT32WriteFile( psFAT32Host, &sFileName, LARGE_SAMPLE, &acSampleData ); if( iError != SUCCESS ) { if( iErrorPrev != iError) fprintf(fid_write, "\r\n(%i) !!!!! Finished 1 FAT32WriteFile (0x%X)\r\n", j, iError); else fprintf(fid_write, "\r(%i) !!!!! Finished 2 FAT32WriteFile (0x%X)\r\n", j, iError); fflush(fid_write); StdioifFlush(); iErrorPrev = iError; if(iError == SBP2_INVALID_HANDLE) SYS_exit(-1); if(iError == FAT32_INSUFFICIENT_DISK_SPACE) SYS_exit(-2); } else { if( iErrorPrev != SUCCESS ) fprintf(fid_write, "\r\n(%i) Finished 3 FAT32WriteFile (0x%X) \r\n", j, iError); else fprintf(fid_write, "\r(%i) Finished 4 FAT32WriteFile (0x%X)\r \n", j, iError); fflush(fid_write); StdioifFlush(); iErrorPrev = SUCCESS; iError = FAT32ReadFile( psFAT32Host, &sFileName, LARGE_SAMPLE, &acReceivedData ); if( iError != SUCCESS ) fprintf(fid_write, "\r\n(%i) ***** Finished 1 FAT32ReadFile (0x%X)\r\n", j, iError); else fprintf(fid_write, "\r(%i) Finished 2 FAT32ReadFile (0x %X)\r\n", j, iError); fflush(fid_write); StdioifFlush(); } } fprintf(fid_write, "\r\n\r\nFinished file I/O test.\r\n"); fflush(fid_write); StdioifFlush(); FAT32Terminate(psFAT32Host); SBP2LogoutDevice(SBP2Host->sSCSI); SBP2CleanupDevice(SBP2Host->sSCSI); IEEE1394Terminate(); while(1) #ifdef comment_out7 { fprintf(fid, "\r Finished storage demo tsk \r\n" ); fflush(fid); StdioifFlush(); fprintf(fid, "\r Finished storage demo tsk 2\r\n" ); fflush(fid); StdioifFlush(); fprintf(fid, "\r Finished storage demo tsk 3\r\n" ); fflush(fid); StdioifFlush(); // TSK_sleep(1); this line kills the routine, and sh-f5 } #endif //comment_out7 ; } *******************************************************************************tcf file ************************* /* loading the generic platform */ var params = {}; params.clockRate = 300.000000; params.deviceName = "6713"; params.catalogName = "ti.catalog.c6000"; params.regs = {}; params.regs.l2Mode = "SRAM"; utils.loadPlatform("ti.platforms.generic", params); /* enabling DSP/BIOS components */ bios.GBL.ENABLEINST = true; bios.MEM.NOMEMORYHEAPS = false; bios.RTDX.ENABLERTDX = true; bios.HST.HOSTLINKTYPE = "RTDX"; bios.TSK.ENABLETSK = true; bios.GBL.ENABLEALLTRC = true; bios.GBL.ENDIANMODE = "little"; bios.GBL.C621XCONFIGUREL2 = false; /* applying user changes */ bios.ERAM = bios.MEM.create("ERAM"); bios.ERAM.comment = "External SDRAM"; bios.ERAM.base = 0x80000000; bios.ERAM.len = 0x2000000; bios.ERAM.heapSize = 0x80000; bios.ERAM.space = "code/data"; bios.STORAGE_DEMO_SWI = bios.SWI.create("STORAGE_DEMO_SWI"); bios.STORAGE_DEMO_TSK = bios.TSK.create("STORAGE_DEMO_TSK"); bios.WriteDataCompleted = bios.SEM.create("WriteDataCompleted"); bios.WriteData = bios.SEM.create("WriteData"); bios.IRAM.len = 0x30000; bios.IRAM.createHeap = 1; bios.IRAM.heapSize = 0x1000; bios.MEM.BIOSOBJSEG = prog.get("IRAM"); bios.MEM.MALLOCSEG = prog.get("ERAM"); bios.MEM.TEXTSEG = prog.get("ERAM"); bios.MEM.SWITCHSEG = prog.get("ERAM"); bios.MEM.BSSSEG = prog.get("ERAM"); bios.MEM.FARSEG = prog.get("ERAM"); bios.MEM.CINITSEG = prog.get("ERAM"); bios.MEM.PINITSEG = prog.get("ERAM"); bios.MEM.CONSTSEG = prog.get("ERAM"); bios.MEM.DATASEG = prog.get("ERAM"); bios.MEM.CIOSEG = prog.get("ERAM"); bios.MEM.SYSMEMSEG = prog.get("ERAM"); bios.GBL.ENABLEALLTRC = 0; bios.GBL.C621XCONFIGUREL2 = 1; bios.GBL.ENABLEINST = 0; bios.GBL.CALLUSERINITFXN = 1; bios.GBL.BOARDNAME = "C6713Compact (StorageDemo v1.2)"; bios.TSK.STACKSEG = prog.get("IRAM"); bios.STORAGE_DEMO_TSK.fxn = prog.extern("StorageDemoTSK"); bios.STORAGE_DEMO_TSK.stackMemSeg = prog.get("IRAM"); bios.STORAGE_DEMO_TSK.priority = 0x2; bios.STORAGE_DEMO_TSK.exitFlag = 0; bios.GBL.C621XMAR = 0xf; bios.PRD_clock.order = 1; bios.HWI_INT6.fxn = prog.extern("LynxHALNodeISR"); bios.STORAGE_DEMO_SWI.fxn = prog.extern("StorageDemoSWI"); bios.STORAGE_DEMO_SWI.priority = 0x3; bios.HWI.instance("HWI_INT7").fxn = prog.extern("HWI_SoftUARTT2IncomingChar"); bios.HWI.instance("HWI_INT7").fxn = prog.extern("HWI_unused", "asm"); bios.HWI.instance("HWI_INT7").fxn = prog.extern("HWI_SoftUARTT2IncomingChar", "asm"); bios.HWI.instance("HWI_INT7").useDispatcher = 1; bios.HWI.instance("HWI_INT7").fxn = prog.extern("HWI_SoftUARTT2IncomingChar"); bios.HWI.instance("HWI_INT7").useDispatcher = 0; bios.HWI.instance("HWI_INT7").useDispatcher = 1; // !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT! if (config.hasReportedError == false) { prog.gen(); }
Reply by ●November 14, 20072007-11-14
jleslie48 wrote:> It was/is a simple demo to show that the firewire reader/writer is > working. >[code snipped]. You're violating two major restrictions on where functions can be called: - SWI_post must not be called from main() - (Almost) no C runtime library functions (printf, sprintf, malloc, fopen, etc) can be called from a SWI or HWI. The reason for these restrictions is usually because the restricted function uses LCK_pend, which is not permitted outside of a TSK context. The result of breaking the rules is undefined, but, IME, is usually bad and weird in equal measure. The usual way to implement this kind of thing is to have 2 tasks, say StorageDemoTSK like you have now, plus one called say SWIHandlerTSK. StorageDemoTSK would do all of the initialisation stuff and then, if necessary, call SWI_post to kick start the application. Then it would go into a loop like you have now, doing monitoring, housekeeping, sleeping, whatever. The second task, SWIHandlerTSK, would always be in an infinite loop, but at the top of the loop it would wait on a semaphore (using SEM_pend). Your SWI handler function would do only the absolute minimum amount of time critical stuff and then post the semaphore (SEM_post) to wake your handler task. SWIHandlerTSK would be at a higher priority than StorageDemoTSK so it would wake immediately and do whatever is required to service the SWI. The advantage of this is that almost all of your code executes in the TSK context, so there's no restrictions on the functions that you can call. Cheers mark-r --
Reply by ●November 14, 20072007-11-14
On Nov 14, 9:01 am, Mark Robinson <m...@simsol.co.uk> wrote:> jleslie48 wrote: > > It was/is a simple demo to show that the firewire reader/writer is > > working. > > [code snipped]. > > You're violating two major restrictions on where functions can be > called: > > - SWI_post must not be called from main() > - (Almost) no C runtime library functions (printf, sprintf, > malloc, fopen, etc) can be called from a SWI or HWI. > > The reason for these restrictions is usually because the restricted > function uses LCK_pend, which is not permitted outside of a TSK context. > The result of breaking the rules is undefined, but, IME, is usually bad > and weird in equal measure. > > The usual way to implement this kind of thing is to have 2 tasks, say > StorageDemoTSK like you have now, plus one called say SWIHandlerTSK. > StorageDemoTSK would do all of the initialisation stuff and then, if > necessary, call SWI_post to kick start the application. Then it > would go into a loop like you have now, doing monitoring, housekeeping, > sleeping, whatever. > > The second task, SWIHandlerTSK, would always be in an infinite loop, but > at the top of the loop it would wait on a semaphore (using SEM_pend). > Your SWI handler function would do only the absolute minimum amount of > time critical stuff and then post the semaphore (SEM_post) to wake your > handler task. SWIHandlerTSK would be at a higher priority than > StorageDemoTSK so it would wake immediately and do whatever is required > to service the SWI. > > The advantage of this is that almost all of your code executes in the > TSK context, so there's no restrictions on the functions that you can > call. > > Cheers > > mark-r > > --Well now ain't that a kick in the pants. Thanks, BTW, could you recommend a documentation source for these grammar rules (eg, no library functions in SWI?) "(Almost) no C runtime library functions (printf, sprintf,malloc, fopen, etc) can be called from a SWI or HWI." Ok so my routine StorageDemoSWI has to be be pruned of all printf statements. I also cant use a memcpy or strcpy statement to copy all those diagnositic messages to to a global buffer for later printing from within the TSK. I can't even use strlen to do a character by character copy of a message to a buffer: { char error_message[] = "you can't do this in a swi\n"; for (int i=0; i< strlen(error_message); i++) { global_buffer[global_buffer_index++] = error_message[i]; } } //push error message into a log buffer this processor is really tying my hands now isn't it? Well that is all do-able. I'm a bit confused about the routine you think I should make, the SWIHandlerTSK, and where I should put the SWI_post(&STORAGE_DEMO_SWI); command. I don't know why I need SWIHandlerTSK can't I put the SWI_post(&STORAGE_DEMO_SWI); command as the first line of the StorageDemoTSK, and then have the StorageDemoTSK sit on a SEM_pend for the completion of STORAGE_DEMO_SWI? ( the last statement of STORAGE_DEMO_SWI being the SEM_post?) Please don't tell me I can't to a SEM_post from within a SWI.... I also find it strange that the SWI as it is seems to work just fine with the printf's, and its the routine StorageDemoTSK that is dying. Anyway Mark, thanks for your advise and help. Sincerely, Jon






