One of eleven tasks running for a while and stopped in version 7.6

huzhiping wrote on Monday, May 05, 2014:

I used FreeRTOS 7.6 in My project and it uses 11 tasks, priorities are from 2, 3,…8, and all tasks are non-preemptive task. Most of the time the priority task 3 running for about 20~ 30 times, then stopped, but other tasks still running and no problem. Few times, priority task 7 stopped but priority task 3 and the rest of the tasks run fine. I used “#define configCHECK_FOR_STACK_OVERFLOW 2” and it never hit the stack overflow hook function. so it seems not a stack issue.

Does anyone meet the same issue before? I am trying to debug the issue, not successfully yet.

Since the OS schedule runs fine, how can this is possible? Although each task is a “for ever loop”, but when I debug it, it never went into the task that stopped.

Does anyone know which list in the source is for all the tasks? I also used “pxCurrentTCB” watch the current task running.

Thanks for your help in advance!

Albert

rtel wrote on Monday, May 05, 2014:

I’m afraid your question is too general in its nature to be able to offer more than a guess. Especially as you are the only person with the application code in front of you, and presumably the problem lies somewhere within the application, or the configuration of the kernel.

Which chip are you using (I really wish people would not leave out this vital information when posting: http://www.freertos.org/FAQ-how-to-use-the-FreeRTOS-support-forum.html)
Have you read through the points here: http://www.freertos.org/FAQHelp.html

Regards.

huzhiping wrote on Monday, May 05, 2014:

Sorry for the information missing.

I am using v850 and GreenHills compiler.

I just want to get some suggestion to get the direction to debug. I knew somehting must be wrong, and hope it is in application.

some questions are that:

  1. if the configuration of the kernel is wrong, the rest of the tasks will not run good. Stack also didn’t go to overflow.
  2. if the RTOS is good, how can this task will stop after running for a while? even the low priority task can still be running. but it never hit the breakpoint of this task when it stopped.
  3. this task didn’t purposely set to be deleted and suspended, and it sometimes still runs fine. if the application code has issue, it possibly make the memory or stack leaking and then cause reset, but seems it is not in this case. Can something cause this task to be suspended?

I attached the “FreeRTOSConfig.h”. And hope to get some suggestions.

Thanks.

Albert

rtel wrote on Monday, May 05, 2014:

Well there is no official V850 port for the Green Hills compiler, so I cannot vouch that the code kernel code is correct or not, or offer advice on how to configure it.

Can you cut down the code in the offending task to the absolute minimum that still exhibits this behaviour, then post the code here. When doing so please use the following link to convert the code into tidy html code as this forum software is (ironically) absolutely atrocious at displaying source code: http://hilite.me/

Regards.

huzhiping wrote on Monday, May 05, 2014:

I think my porting code has issue. When I change the OS tasks to preemptive (by setting “#define configUSE_PREEMPTION 1” in FreeRTOSConfig.h), all the tasks works fine, if changed back to non-preemptive, then the issue occurred.
the following is my porting code for v850 and using GHS compiler.

/********************************************************************************
#include <df3580_IRQ.h>
#include “FreeRTOSConfig.h”


– Functions used by scheduler

.extern _vTaskSwitchContex
.extern _xTaskIncrementTick

– Variables used by scheduler

.extern _pxCurrentTCB
.extern _usCriticalNesting

– Functions implemented in this file

.global _vPortYield
.global _vPortStart


------------- Basic Initialisation of the controller
------------- User modifiable section

.weak ___lowinit
.text
_RESET:
– Initialisation of the global pointer
movhi hi(___ghsbegin_sdabase),zero,gp
movea lo(___ghsbegin_sdabase),gp,gp

– Initialisation of the text pointer
movhi hi(___ghsbegin_robase),zero,tp
movea lo(___ghsbegin_robase),tp,tp

– Initialisation of the stack pointer
movhi hi(___ghsend_stack-4),zero,sp
movea lo(___ghsend_stack-4),sp,sp
mov -4,r1
and r1,sp

– Jump to the HW Initialisation function
jarl ___lowinit, lp
– Jump to the Initialisation functions of the library,
– from there to main()
jr __start


------------- Interrupt service routine of unused interrupts
.global __unused_isr
__unused_isr:
br __unused_isr


– portSAVE_CONTEXT MACRO
– Saves the context of the remaining general purpose registers
– and the usCriticalNesting Value of the active Task onto the task stack
– saves stack pointer to the TCB

.macro portSAVE_CONTEXT
prepare {r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30},19,sp – save general purpose registers
st.w r19,72[ep]
st.w r18,68[ep]
st.w r17,64[ep]
st.w r16,60[ep]
st.w r15,56[ep]
st.w r14,52[ep]
st.w r13,48[ep]
st.w r12,44[ep]
st.w r11,40[ep]
st.w r10,36[ep]
st.w r9,32[ep]
st.w r8,28[ep]
st.w r7,24[ep]
st.w r6,20[ep]
st.w r5,16[ep]
st.w r4,12[ep]
st.w r2,8[ep]
st.w r1,4[ep]
movhi hi(_usCriticalNesting),r0,r1 – save usCriticalNesting value to stack
ld.w lo(_usCriticalNesting)[r1],r2
sst.w r2,0[ep]
movhi hi(_pxCurrentTCB),r0,r1 – save SP to top of current TCB
ld.w lo(_pxCurrentTCB)[r1],r2
st.w sp,0[r2]
.endm


– portRESTORE_CONTEXT MACRO
– Gets stack pointer from the current TCB
– Restores the context of the usCriticalNesting value and general purpose
– registers of the selected task from the task stack

.macro portRESTORE_CONTEXT
movhi hi(_pxCurrentTCB),r0,r1 – get Stackpointer address
ld.w lo(_pxCurrentTCB)[r1],sp
mov sp,r1
ld.w 0[r1],sp – load stackpointer
mov sp,ep – set stack pointer to element pointer
sld.w 0[ep],r1 – load usCriticalNesting value from stack
movhi hi(_usCriticalNesting),r0,r2
st.w r1,lo(_usCriticalNesting)[r2]
ld.w 4[ep],r1 – restore general purpose registers
ld.w 8[ep],r2
ld.w 12[ep],r4
ld.w 16[ep],r5
ld.w 20[ep],r6
ld.w 24[ep],r7
ld.w 28[ep],r8
ld.w 32[ep],r9
ld.w 36[ep],r10
ld.w 40[ep],r11
ld.w 44[ep],r12
ld.w 48[ep],r13
ld.w 52[ep],r14
ld.w 56[ep],r15
ld.w 60[ep],r16
ld.w 64[ep],r17
ld.w 68[ep],r18
ld.w 72[ep],r19

dispose 19,{r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30}

.endm


– Restore the context of the first task that is going to run.

– Input: NONE

– Call: CALL vPortStart

– Output: NONE

_vPortStart:
portRESTORE_CONTEXT – Restore the context of whichever task the …
ld.w 0[sp],lp
ldsr lp,5 – restore PSW
di
ld.w 4[sp],lp – restore LP
ld.w 8[sp],lp – restore LP
add 0x0C,sp – set SP to right position
ei
jmp [lp]


– Port Yield function to check for a Task switch in the cooperative and
– preemptive mode

– Input: NONE

– Call: CALL vPortYield

– Output: NONE

_vPortYield:

add     -0x0C,sp                        -- prepare stack to save necessary values
st.w    lp,8[sp]                        -- store LP to stack
stsr    0,r31
st.w    lp,4[sp]                        -- store EIPC to stack
stsr    1,lp
st.w    lp,0[sp]                        -- store EIPSW to stack
portSAVE_CONTEXT		            -- Save the context of the current task.
jarl    _vTaskSwitchContext,lp           -- Call the scheduler.
portRESTORE_CONTEXT		       -- Restore the context of whichever task the ...
            		            -- ... scheduler decided should run.
ld.w    0[sp],lp                        -- restore EIPSW from stack
ldsr    lp,1
ld.w    4[sp],lp                        -- restore EIPC from stack
ldsr    lp,0
ld.w    8[sp],lp                        -- restore LP from stack
add     0x0C,sp                         -- set SP to right position

reti


– Perform the necessary steps of the Tick Count Increment and Task Switch
– depending on the chosen kernel configuration

– Input: NONE

– Call: ISR

– Output: NONE

#if configUSE_PREEMPTION == 1 /* use preemptive kernel mode*/

_INTOSTM0:

add     -0x0C,sp                        -- prepare stack to save necessary values
st.w    lp,8[sp]                        -- store LP to stack
stsr    0,r31
st.w    lp,4[sp]                        -- store EIPC to stack
stsr    1,lp
st.w    lp,0[sp]                        -- store EIPSW to stack
portSAVE_CONTEXT		            -- Save the context of the current task.
jarl    _xTaskIncrementTick,lp           -- Call the timer tick function.
jarl    _vTaskSwitchContext,lp           -- Call the scheduler.
portRESTORE_CONTEXT		      -- Restore the context of whichever task the ...
            		            -- ... scheduler decided should run.
ld.w    0[sp],lp                        -- restore EIPSW from stack
ldsr    lp,1
ld.w    4[sp],lp                        -- restore EIPC from stack
ldsr    lp,0
ld.w    8[sp],lp                        -- restore LP from stack
add     0x0C,sp                         -- set SP to right position

reti

#else /* use cooperative kernel mode*/

_INTOSTM0:

prepare {lp,ep},8,sp
sst.w   r1,4[ep]
sst.w   r5,0[ep]
jarl    _xTaskIncrementTick,lp           -- Call the timer tick function.
sld.w   0[ep],r5
sld.w   4[ep],r1
dispose 8,{lp,ep}

reti

#endif /* configUSE_PREEMPTION */

/*****************************************************************************

my FreeRTOSConfig.h as follows:

/*****************************************************************************
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* only include in C files /
//#ifdef IAR_SYSTEMS_ICC
// #pragma language=extended
// #pragma system_include
// #include <intrinsics.h>
//#endif /
IAR_SYSTEMS_ICC */

/* V850ES/Fx3 Memory Model

  • 1 = Tiny data model
  • 0 = Small/Large data model
    */
    #define configDATA_MODE 0

/*

  • Application specific definitions.
  • These definitions should be adjusted for your particular hardware and
  • application requirements.
  • THESE PARAMETERS ARE DESCRIBED WITHIN THE ‘CONFIGURATION’ SECTION OF THE
  • FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
    */

#define configUSE_PREEMPTION 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 0
#define configCPU_CLOCK_HZ 20000000
#define configTICK_RATE_HZ 1000
#define configMAX_PRIORITIES 9
#define configMINIMAL_STACK_SIZE 75
#define configTOTAL_HEAP_SIZE 10240
#define configMAX_TASK_NAME_LEN 22
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
#define configQUEUE_REGISTRY_SIZE 0
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0

/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 0

/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 0

/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 0

/* Software timer related definitions. /
/
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/
/
Interrupt nesting behaviour configuration. */
//#define configKERNEL_INTERRUPT_PRIORITY 1
//#define configMAX_SYSCALL_INTERRUPT_PRIORITY 3
//#define configMAX_API_CALL_INTERRUPT_PRIORITY 7

/* Define to trap errors during development. */
//#define configASSERT (( x )) if(( x )== 0) vAssertCalled( FILE, LINE )

/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0

/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 0

#define INCLUDE_uxTaskGetStackHighWaterMark 0

#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0

/* A header file that defines trace macro can be included here. */

#endif /* FREERTOS_CONFIG_H */

The difference between preemptive and non-preemptive is that in preemptive, each os tick, it call the OS scheduler, but non-preemptive not.

in my task application code as follows:

/**************************************************************************
void vTask_SYS_EEPROM(void *pvParameters)
{
for(;:wink:
{
EE_WriteManager();

#ifndef RELEASE
/* Get the not used stack size of this task */
EEPROMFreeStack = (unsigned portSHORT)uxTaskGetStackHighWaterMark( NULL );
EEPROMFreeStackPercent = StackPercentage(EEPROMSTACK, EEPROMFreeStack);
#endif

	/* relative 10 ms cycle time of this task */
	vTaskDelay(TASKTIME_10MS / portTICK_RATE_MS);

}

}

/**********************************************************************************

I doubt the function “vTaskDelay(10ms)” do something make the task lost.
I have to use all my tasks to be non-preemptive.

In function “vTaskDelay(xx)” has the following code:



xAlreadyYielded = xTaskResumeAll();
}

	/* Force a reschedule if xTaskResumeAll has not already done so, we may
	have put ourselves to sleep. */
	if( xAlreadyYielded == pdFALSE )
	{
		portYIELD_WITHIN_API();
	}

Theoretically when calling “portYIELD_WITHIN_API()”, it will call “_vPortYield()” in the upper porting code and do OS reschedule (“trap0” is link to “_vPortYield”), but it looks like not always occurred, or maybe “xAlreadyYielded != pdFALSE” in non-preemptive kernel mode.

Any suggestions?

Thanks a lot!

Albert