EngineerZone
All Places
Processors and DSP
Software and Development Tools
Linux Distribution for Blackfin
Discussions
Hi Steven,
I had a look but I cannot find the task switch trace support you are speaking about, can you point me to where you saw that?
I've added
configCHECK_FOR_STACK_OVERFLOW in FreeRTOSConfig.h but I've a stupid error at the moment I'm trying to figure out:
StackMacros.h:107: error: expected identifier or ‘(’ before ‘{’ token
thanks
William
Hi Steven,
I've corrected the compilation error and run with configCHECK_FOR_STACK_OVERFLOW = 1. But the stack do not seem to overflow
let me know if you saw more debug options
Thanks,
William
Hi William,
There're some trace option in FreeRTOS.h, like traceTASK_SWITCH_IN, traceTASK_SWITCH_IN, you can enable them, but I'm afraid you should implement them youself by print some currentTCB context info, then you can see the trace log at each task switch.
-steven
Hi Steven,
I did implement the debugging function as you sudgested (thanks) .
there is few more logs that may tell you something but I cannot see to much in it. I've highlighted in red what I find suspicious:
COREB: end setup LED
COREB: handler declared
COREB: Initialise New TCB:NewTCB address: 3d01000
COREB: TopofStask: 0, pxTopOfStack = 3d0263c
COREB: pxTaskCode =3c033a0, pvParameters = 0
COREB: returned pxNewTCB->pxTopOfStack = 3d02588
COREB: task created:
COREB: top of stack: 3d02588
COREB: GenericListItem: 0
COREB: Event ListItem: 9
COREB: Priority: 1
COREB: start of stack: 3d02000
COREB: Task Name: BootTas
COREB: TCB number: 0
COREB: Task Tag: 0
COREB: Add the idle task at the lowest priority
COREB: Initialise New TCB:NewTCB address: 3d03000
COREB: TopofStask: 0, pxTopOfStack = 3d0431c
COREB: pxTaskCode =3c0295c, pvParameters = 0
COREB: returned pxNewTCB->pxTopOfStack = 3d04268
COREB: task created:
COREB: top of stack: 3d04268
COREB: GenericListItem: 0
COREB: Event ListItem: a <--------------- this is not a number, not sure it is normal
COREB: Priority: 0
COREB: start of stack: 3d04000
COREB: Task Name: IDLE
COREB: TCB number: 1
COREB: Task Tag: 0
COREB: end Add the idle task at the lowest priority
COREB: if xReturn == 1, and xReturn = 1
COREB: before disable interupt
COREB: after disable interupt
COREB: before xPortStartScheduler <---------------- below it print this name in the task switch out debug at for the val: pxCurrentTCB->pcTaskName
COREB: start xPortStartScheduler fn before set core timer
COREB: after ContextSwitch interupt flag
COREB: before prvSetupTimerInterrupt
COREB: after prvSetupTimerInterupt
COREB: Task Switch context called
COREB: The scheduler is running
COREB: trace switched out TCB:ff700bf8
COREB: name of switch out task:efore xPortStartScheduler <-------------- there is no name associated, instead it provide a message from one of my coreb_msg not sure why
COREB: before Task first check for stack overflow
COREB: Task first check for stack overflow called
COREB: Task second check for stack overflow called
COREB: before call get owner of next entry
COREB: get owner of next entry:
COREB: current TCB 3d01000
COREB: pxReadyTasksLists[ uxTopReadyPriority ] = 1
COREB: TCB content:
COREB: top of stack: 3d02588
COREB: GenericListItem: 0
COREB: Event ListItem: 9
COREB: Priority: 1
COREB: start of stack: 3d02000
COREB: Task Name: BootTas
COREB: TCB number: 0
COREB: Task Tag: 0
COREB: trace switched in:BootTas <------------------ switch in BottTask as it supose to
COREB: write trace to buffer
COREB: task increment tick: 1
COREB: end of app init
COREB: execption 2b addr ff700be4
COREB: coreb dump stack
COREB: found fp: ff700b64
Best Regards,
William
Hi Steven,
I wish you an happy new year.
it has been a while with the end of the year break. I went back to try to resolve this issue, what do you think of the trace log in the last post?
As well I've noticed that instead to jump to the address pxTaskCode =3c0342c for the vBootTask it jump to app_init() function at address 03c0592c
doing 03c0592c - 3c0342c = 2500
I don't think this number happened by chance, which mean something offset the memory of 0x2500
Do you know what could correspond to that hex amount? is the memory block from icc maloc function is equal to this amount? in decimal, this represent 9472 bytes almost 10Kb
as well I've try to put some debugging in the assembly code as follow:
| .extern _coreb_msg | ; |
| //.section program; |
| /* |
* Manual context switch. The first thing we do is save the registers so we
| * can use a naked attribute. |
*/
/* This function is also the ISR for interrupt 2 */
.section .text
| .align 4 | ; | |
| msg_switch_exit: | .string "before end vContextSwitch\n" ; | |
| msg_vTickISR_exit: .string "before end vTickISR\n" ; |
| .align 8 | ; | |
| .global _vContextSwitch; |
_vContextSwitch:
| _portSAVE_CONTEXT; |
| /* Call the standard scheduler context switch function. */ | ||
| LINK 0x0; | ||
| SP += 12; | ||
| call.X _vTaskSwitchContext; |
| UNLINK; | |||
| LINK 0x0 | ; | ||
| SP += 16 | ; | ||
| r0.l = msg_switch_exit; | |||
| r0.h = msg_switch_exit ; | |||
| call.X _coreb_msg ; //tried with just call as well | |||
| UNLINK | ; |
|
| _portRESTORE_CONTEXT; |
_vContextSwitch.end:
But I get a linking error when I compile a linking error probably due to long call:
/home/william/Development_new/Music_Recognition/code/uCLinux/uclinux-dist/user/blkfin-apps/icc_utils/example/tested_by_AD/Source/portable/ADI_VDSP/Blackfin/bfin_isr.s:44: relocation truncated to fit: R_BFIN_PCREL24 against symbol `coreb_msg' defined in .text section in ../../icc_core/icc
make: *** [test_ad1836_driver] Error 1
Could you tell me what I did wrong as getting the assembler debug working could help debug further
William
Hi Steven,
In addition to the previous post, I found part of the problem which come from a translation from VDSP assembler to bare metal assembler. unfortunatly, excepted few examples in blackfin doc I cannot find a good manual about the assembler used, especially about how to setup interupts.
I'm trying to immitate your file coreb_start.S by replacing the code with
ENTRY(_vContextSwitch):
.....
| RTI | ; |
ENDPROC(_vContextSwitch)
instead of:
_vContextSwitch:
.....
_vContextSwitch.end:
what happened when _vContextSwitch.end: was called, it was not returning from the interupt, instead it did continue to the next assembly function: _vTickISR which if preemption is selected call _vTaskSwitchContext as well which explain why initially it was called twice.
Maybe that 's it but I need to start and end properly the function to test it. For the moment I got errors:
" syntax error. Input text was entry."
Thanks William
Hi Steven,
by separating the 2 interupt in different files I managed to make it run, this time it call few time the switch context before to go bake to the problem of jumping to app_init function
| COREB: end setup LED | |
| COREB: handler declared | |
| COREB: Initialise New TCB:NewTCB address: 3d01000 | |
| COREB: TopofStask: 0, pxTopOfStack = 3d02e0c | |
| COREB: pxTaskCode =3c0343c, pvParameters = 0 | |
| COREB: Start port initialise stack fnc | |
| COREB: pxTopOfStack: 3d02e08 | |
| COREB: pxTopOfStack: 3d02e04 | |
| COREB: pxTopOfStack: 3d02e00 | |
| COREB: pxTopOfStack: 3d02dfc | |
| COREB: pxTopOfStack: 3d02df8 | |
| COREB: pxTopOfStack: 3d02df4 | |
| COREB: pxTopOfStack: 3d02df0 | |
| COREB: pxTopOfStack: 3d02dec | |
| COREB: pxTopOfStack: 3d02de8 | |
| COREB: pxTopOfStack: 3d02de4 | |
| COREB: pxTopOfStack: 3d02de0 | |
| COREB: pxTopOfStack: 3d02ddc | |
| COREB: pxTopOfStack: 3d02dd8 | |
| COREB: pxTopOfStack: 3d02dd4 | |
| COREB: pxTopOfStack: 3d02dd0 | |
| COREB: pxTopOfStack: 3d02dcc | |
| COREB: pxTopOfStack: 3d02dc8 | |
| COREB: pxTopOfStack: 3d02dc4 | |
| COREB: pxTopOfStack: 3d02dc0 | |
| COREB: pxTopOfStack: 3d02dbc | |
| COREB: pxTopOfStack: 3d02db8 | |
| COREB: pxTopOfStack: 3d02db4 | |
| COREB: pxTopOfStack: 3d02db0 | |
| COREB: pxTopOfStack: 3d02dac | |
| COREB: pxTopOfStack: 3d02da8 | |
| COREB: pxTopOfStack: 3d02da4 | |
| COREB: pxTopOfStack: 3d02da0 | |
| COREB: pxTopOfStack: 3d02d9c | |
| COREB: pxTopOfStack: 3d02d98 | |
| COREB: pxTopOfStack: 3d02d94 | |
| COREB: pxTopOfStack: 3d02d90 | |
| COREB: pxTopOfStack: 3d02d8c | |
| COREB: pxTopOfStack: 3d02d88 | |
| COREB: pxTopOfStack: 3d02d84 | |
| COREB: pxTopOfStack: 3d02d80 | |
| COREB: pxTopOfStack: 3d02d7c | |
| COREB: pxTopOfStack: 3d02d78 | |
| COREB: pxTopOfStack: 3d02d74 | |
| COREB: pxTopOfStack: 3d02d70 | |
| COREB: pxTopOfStack: 3d02d6c | |
| COREB: pxTopOfStack: 3d02d68 | |
| COREB: pxTopOfStack: 3d02d64 | |
| COREB: pxTopOfStack: 3d02d60 | |
| COREB: pxTopOfStack: 3d02d5c | |
| COREB: pxTopOfStack: 3d02d58 | |
| COREB: returned pxNewTCB->pxTopOfStack = 3d02d58 | |
| COREB: task created: | |
| COREB: top of stack: 3d02d58 | |
| COREB: GenericListItem: 0 | |
| COREB: Event ListItem: 9 | |
| COREB: Priority: 1 | |
| COREB: start of stack: 3d02000 | |
| COREB: Task Name: BootTas | |
| COREB: TCB number: 0 | |
| COREB: Task Tag: 0 | |
| COREB: Add the idle task at the lowest priority | |
| COREB: Initialise New TCB:NewTCB address: 3d03000 | |
| COREB: TopofStask: 0, pxTopOfStack = 3d0431c | |
| COREB: pxTaskCode =3c029ec, pvParameters = 0 | |
| COREB: Start port initialise stack fnc | |
| COREB: pxTopOfStack: 3d04318 | |
| COREB: pxTopOfStack: 3d04314 | |
| COREB: pxTopOfStack: 3d04310 | |
| COREB: pxTopOfStack: 3d0430c | |
| COREB: pxTopOfStack: 3d04308 | |
| COREB: pxTopOfStack: 3d04304 | |
| COREB: pxTopOfStack: 3d04300 | |
| COREB: pxTopOfStack: 3d042fc | |
| COREB: pxTopOfStack: 3d042f8 | |
| COREB: pxTopOfStack: 3d042f4 | |
| COREB: pxTopOfStack: 3d042f0 | |
| COREB: pxTopOfStack: 3d042ec | |
| COREB: pxTopOfStack: 3d042e8 | |
| COREB: pxTopOfStack: 3d042e4 | |
| COREB: pxTopOfStack: 3d042e0 | |
| COREB: pxTopOfStack: 3d042dc | |
| COREB: pxTopOfStack: 3d042d8 | |
| COREB: pxTopOfStack: 3d042d4 | |
| COREB: pxTopOfStack: 3d042d0 | |
| COREB: pxTopOfStack: 3d042cc | |
| COREB: pxTopOfStack: 3d042c8 | |
| COREB: pxTopOfStack: 3d042c4 | |
| COREB: pxTopOfStack: 3d042c0 | |
| COREB: pxTopOfStack: 3d042bc | |
| COREB: pxTopOfStack: 3d042b8 | |
| COREB: pxTopOfStack: 3d042b4 | |
| COREB: pxTopOfStack: 3d042b0 | |
| COREB: pxTopOfStack: 3d042ac | |
| COREB: pxTopOfStack: 3d042a8 | |
| COREB: pxTopOfStack: 3d042a4 | |
| COREB: pxTopOfStack: 3d042a0 | |
| COREB: pxTopOfStack: 3d0429c | |
| COREB: pxTopOfStack: 3d04298 | |
| COREB: pxTopOfStack: 3d04294 | |
| COREB: pxTopOfStack: 3d04290 | |
| COREB: pxTopOfStack: 3d0428c | |
| COREB: pxTopOfStack: 3d04288 | |
| COREB: pxTopOfStack: 3d04284 | |
| COREB: pxTopOfStack: 3d04280 | |
| COREB: pxTopOfStack: 3d0427c | |
| COREB: pxTopOfStack: 3d04278 | |
| COREB: pxTopOfStack: 3d04274 | |
| COREB: pxTopOfStack: 3d04270 | |
| COREB: pxTopOfStack: 3d0426c | |
| COREB: pxTopOfStack: 3d04268 | |
| COREB: returned pxNewTCB->pxTopOfStack = 3d04268 | |
| COREB: task created: | |
| COREB: top of stack: 3d04268 | |
| COREB: GenericListItem: 0 | |
| COREB: Event ListItem: a | |
| COREB: Priority: 0 | |
| COREB: start of stack: 3d04000 | |
| COREB: Task Name: IDLE | |
| COREB: TCB number: 1 | |
| COREB: Task Tag: 0 | |
| COREB: end Add the idle task at the lowest priority | |
| COREB: if xReturn == 1, and xReturn = 1 | |
| COREB: before disable interupt | |
| COREB: after disable interupt | |
| COREB: before xPortStartScheduler | |
| COREB: start xPortStartScheduler fn before set core timer | |
| COREB: after ContextSwitch interupt flag | |
| COREB: before prvSetupTimerInterrupt | |
| COREB: after prvSetupTimerInterupt | |
| root:/> COREB: Task Switch context called | |
| COREB: The scheduler is running | |
| COREB: trace switched out TCB:ff700bf8 | |
| COREB: name of switch out task:efore xPortStartScheduler | |
| COREB: before Task first check for stack overflow | |
| COREB: Task first check for stack overflow called | |
| COREB: Task second check for stack overflow called | |
| COREB: before call get owner of next entry | |
| COREB: get owner of next entry: | |
| COREB: current TCB 3d01000 | |
| COREB: pxReadyTasksLists[ uxTopReadyPriority ] = 1 | |
| COREB: TCB content: | |
| COREB: top of stack: 3d02d58 | |
| COREB: GenericListItem: 0 | |
| COREB: Event ListItem: 9 | |
| COREB: Priority: 1 | |
| COREB: start of stack: 3d02000 | |
| COREB: Task Name: BootTas | |
| COREB: TCB number: 0 | |
| COREB: Task Tag: 0 | |
| COREB: trace switched in:BootTas | |
| COREB: write trace to buffer | |
| COREB: Task Switch context called | |
| COREB: The scheduler is running | |
| COREB: trace switched out TCB:3d01000 | |
| COREB: name of switch out task:BootTas | |
| COREB: before Task first check for stack overflow | |
| COREB: Task first check for stack overflow called | |
| COREB: Task second check for stack overflow called | |
| COREB: before call get owner of next entry | |
| COREB: get owner of next entry: | |
| COREB: current TCB 3d01000 | |
| COREB: pxReadyTasksLists[ uxTopReadyPriority ] = 1 | |
| COREB: TCB content: | |
| COREB: top of stack: 3d02d58 | |
| COREB: GenericListItem: 0 | |
| COREB: Event ListItem: 9 | |
| COREB: Priority: 1 | |
| COREB: start of stack: 3d02000 | |
| COREB: Task Name: BootTas | |
| COREB: TCB number: 0 | |
| COREB: Task Tag: 0 | |
| COREB: trace switched in:BootTas | |
| COREB: write trace to buffer | |
| COREB: task increment tick: 1 | |
| COREB: Task Switch context called | |
| COREB: The scheduler is running | |
| COREB: trace switched out TCB:3d01000 | |
| COREB: name of switch out task:BootTas | |
| COREB: before Task first check for stack overflow | |
| COREB: Task first check for stack overflow called | |
| COREB: Task second check for stack overflow called | |
| COREB: before call get owner of next entry | |
| COREB: get owner of next entry: | |
| COREB: current TCB 3d01000 | |
| COREB: pxReadyTasksLists[ uxTopReadyPriority ] = 1 | |
| COREB: TCB content: | |
| COREB: top of stack: 3d02d58 | |
| COREB: GenericListItem: 0 | |
| COREB: Event ListItem: 9 | |
| COREB: Priority: 1 | |
| COREB: start of stack: 3d02000 | |
| COREB: Task Name: BootTas | |
| COREB: TCB number: 0 | |
| COREB: Task Tag: 0 | |
| COREB: trace switched in:BootTas | |
| COREB: write trace to buffer |
COREB: end of app init
......
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: end of app init | |
| COREB: @@@bug gen pool full | |
| COREB: coreb dump stack | |
| COREB: found fp: 03d02cac |
Hi Steven,
actually, it is the same, I test it again with the flag pre-emptive off (as it was in previous test to identify the issue) and it is the same as before:
.....
| COREB: start of stack: 3d02000 | |
| COREB: Task Name: BootTas | |
| COREB: TCB number: 0 | |
| COREB: Task Tag: 0 | |
| COREB: trace switched in:BootTas | |
| COREB: write trace to buffer | |
| COREB: task increment tick: 1 | |
| COREB: end of app init |
COREB: execption 26 addr 3d027f4
in fact looking at the dump file I can see that despite I put it in 2 files they follow each other and thus vContextSwitch do not return as before and continue to the next address which is _vTickISR
Hi Steven,
Actually, I found a get around by making those iterupts in C instead of assembler. this resolve the problem of running out from the code but it still not work corectly. There is no crash anymore but the interupt do not seem to react properlly, the new intrupt functions look like:
void __attribute__((interrupt_handler)) vTickISR(void);
void __attribute__((interrupt_handler)) vContextSwitch(void);
void __attribute__((interrupt_handler)) vContextSwitch(void)
{
coreb_msg("start vcontext switch interupt \n");
vTaskSwitchContext();
coreb_msg("end vcontext switch interupt \n");
}
void __attribute__((interrupt_handler)) vTickISR(void)
{
vTaskIncrementTick();
}
do I miss something in it?
their setup are:
void prvSetupTimerInterrupt( void )
{
int scale = 134;
int counter = 100000;
// *pTCNTL = 1; // Turn on timer, TMPWR
*tcntl = 0x01;
// *pTSCALE = scale; // Load scale
*tscale = scale;
| // | *pTCOUNT = counter; | // Load counter | |
| *tcount = counter; |
| // | *pTPERIOD = counter; | // Load counter into p\ |
| eriod as well | ||
| *tperiod = counter; |
| // | register_handler_ex (ik_timer, | // Register Timer ISR \ |
| and enable | ||
| // | (ex_handler_fn )vTickISR, EX_INT_ENABLE); // IVG6 (Tim\ | |
| er) |
| //change it to bare metal method: | |
| bfin_write_EVT6(vTickISR); |
| int i; |
| asm volatile ("cli %0; bitset (%0, 6); sti %0; csync;": "+d"(i)); |
/* Interrupts are disabled when this is called so the timer can be started
here. */
// *pTCNTL = 0x7; // Start Timer and set\
Auto-reload
tcntl = 0x07;
}
and:
portBASE_TYPE xPortStartScheduler( )
{
char tmp[220];
int i;
coreb_msg("start xPortStartScheduler fn before set core timer\n");
/* Setup core timer to generate the RTOS tick. */
//register_handler_ex (ik_ivg14, (ex_handler_fn)vContextSwitch, EX_INT_\
ENABLE);
bfin_write_EVT14(vContextSwitch);
asm volatile ("cli %0; bitset (%0, 14); sti %0; csync;": "+d"(i));
coreb_msg("after ContextSwitch interupt flag\n");
coreb_msg("before prvSetupTimerInterrupt\n");
prvSetupTimerInterrupt();
....
}
is there is something I missed?
Ok finally after all this time, I resolved the issue. Not only the assembler code was falty but in addition the hook function from the context loader was not trigger neither the Tag of the function was indicated. I've added it all up miself in the FreeRTOS code and it finally work
Thank Steven for your support over all that and especially for fixing memory issues.
Best Regards,
William
Hi William,
Congratulations! I was just reading your previous posts, after a long vocation I almost forgot the context. How did you find faulty code in context switch and where is the issue?
-steven
Hi Steven,
well in bfin_isr.s located in Source/portable/ADI_VDSP/Blackfin :
.text
.global _vContextSwitch;
_vContextSwitch:
_portSAVE_CONTEXT;
/* Call the standard scheduler context switch function. */
LINK 0x0;
SP += 12;
call.X _vTaskSwitchContext;
UNLINK;
_portRESTORE_CONTEXT;
_vContextSwitch.end:
with _portRESTORE_CONTEXT which is a MACRO which finish with:
.....
| R0 = R0 | R1; | \ | |||
| /* should jump here by offset */ | \ | |||
| STI R0; | /* restore IMASK */ | \ | ||
| ( R7:0 , P5:0 ) = [ SP ++ ] ; | \ | |||
| /* simulate a return from interrupt (also clears IPEND[4]) */\ | ||||
| RTI |
that you can find in the file
context_sl_asm.asm of the same folder
RTI do not work and the code continue to run to the next assembly function vTickISR then tot he next code in memory which is app_init function.
maybe the compiler does not handle all the conversion of .asm and I should have change the extension to .s or it was a problem with the MACRO.
Hope you had good vacation,
Let me know if you know where exactly it come from just by curiosity.
best regards
William
Hi William,
Thanks! It seems gnu toolchain require only .s or .S suffix, it memtioned on blackfin wiki:
http://docs.blackfin.uclinux.org/doku.php?id=visualdsp:port_assembly_code
-steven
Hi Steven,
maybe, I thought that adding assembler-with-cpp would have done the trick. I did have try to change to .s but didn't remove the flag assembler-with-cpp so maybe it is why.
Thanks
William