Home/Support/Support Forum/Bug when using OS_TASK_OPT_STK_CLR with OSTaskCreateExt()
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

Bug when using OS_TASK_OPT_STK_CLR with OSTaskCreateExt()

0 votes
I recently wrapped up an investigation of strange behavior in a customer’s program on a Rabbit 3000 product. It took some time to track it down to using the OS_TASK_OPT_STK_CLR option with OSTaskCreateExt(). Both Dynamic C 9 and 10 were erasing the wrong memory area.

In the case of Dynamic C 9, it was inefficiently using 16-bit writes and ultimately erasing one byte beyond the end of the stack allocated for the task. In this customer’s situation, a stack ending at 0x6FFFF would end up erasing the byte at 0x60000 due to usage of the LDP opcode.

In Dynamic C 10, it calculated the incorrect starting address for the stack, and would erase one byte before the stack and leave the last byte untouched.

Due to licensing issues, Digi International wasn’t able to include the uC/OS-II source code in the GitHub repository when they released Dynamic C libraries and samples as Open Source. This change will be a part of the Dynamic C 10.72E installer whenever we release it. I intend to include it as a patch on GitHub for both Dynamic C 9 and 10.

Here’s the patch for Dynamic C 9:
Code:
--- a/Lib/UCOS2/OS_TASK.C +++ b/Lib/UCOS2/OS_TASK.C @@ -439,8 +439,6 @@ auto INT8U err; auto INT16U i; auto INT16U pbos; - auto INT8U upper_nibble; - auto INT16U lower_16; auto INT16U stk_size; auto INT32U PhysAddr; @@ -460,25 +458,9 @@ if (opt & OS_TASK_OPT_STK_CHK) { // See if stack checking has been enabled if (opt & OS_TASK_OPT_STK_CLR) { // See if stack needs to be cleared // Yes, fill the stack with zeros - lower_16 = (INT16U)PhysAddr; - upper_nibble = (INT8U)(PhysAddr >> 16); - for (i = stk_size; i > 0; i--) { - #asm - ld hl,@sp+upper_nibble - add hl,sp - ld a,(hl) ;a gets high nibble - ld hl,@sp+lower_16 - add hl,sp - ld hl,(hl) ;hl has lower 16 bits - push ix - ld ix,hl ;a:ix 20-bit phys addr for stack - bool hl - ld l,h ;zero hl - ldp (ix),hl ;write zero into stack - pop ix - #endasm - lower_16--; - } + // PhysAddr is the last address of the stack (e.g., ...FF), so it's + // necessary to add 1 to get to the starting address of the stack. + xmemset(PhysAddr - stk_size + 1, 0, stk_size); } }

And for Dynamic C 10:
Code:
--- a/Lib/Rabbit4000/UCOS2/OS_TASK.C +++ b/Lib/Rabbit4000/UCOS2/OS_TASK.C @@ -479,7 +479,9 @@ if (opt & OS_TASK_OPT_STK_CHK) { // See if stack checking has been enabled if (opt & OS_TASK_OPT_STK_CLR) { // See if stack needs to be cleared // Yes, fill the stack with zeros - _f_memset((void __far *)(PhysAddr - stk_size), 0, stk_size); + // PhysAddr is the last address of the stack (e.g., ...FF), so it's + // necessary to add 1 to get to the starting address of the stack. + _f_memset((void __far *)(PhysAddr - stk_size + 1), 0, stk_size); } }

Please let me know if you have any questions about the original bug, or the patches.
asked Jun 14 in Rabbit Software by TomCollins Veteran of the Digi Community (1,362 points)

Please log in or register to answer this question.

1 Answer

0 votes
 
Best answer
Patches to resolve this bug are provided in the question above.
answered Jun 24 by TomCollins Veteran of the Digi Community (1,362 points)
...