Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

Debug new port GCC/HCS12

Posted by Jeff Smith on August 3, 2005
I am having trouble debugging my attempt at GCC and HCS12. I'm using the simulator () to avoid trace problems. I have been trying to trace the initialization of tasks, and I'm not very familiar with the internal workings yet.

I see that every xTaskCreate() is updating pxCurrentTCB with the new task. The result is when I start the scheduler, it adds the IdleTask and makes it run first. I thought it was supposed to run the highest priority first, not the lowest or the last one created.

RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 3, 2005
I forgot to say the simulator (http://hc12text.com/)

RE: Debug new port GCC/HCS12

Posted by Richard on August 3, 2005
Before the scheduler has started, when a task is created it is made the current task only if it has a priority higher than the existing current task. When the scheduler is started the current task is then the task that executes first.

Therefore the idle task should be the first task to execute only if all the other tasks in the system were created with the idle priority.

I have just verified this behaviour and it is executing as expected. If you are finding that the idle task is the first to execute, even when tasks of higher priority have already been created then something has gone amiss somewhere, possibly memory corruption within the TCB's.

Regards.

RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 4, 2005
This is in my new port, but I don't see how I could have changed that behavior. It is from FreeRTOS 3.2.0. I'll get some other things working, then send you the code.

I have found a memory corruption in my stack, but only after the first Yield (swi). I will fix that problem the best I can, although I don't see any way to predict how GCC will save tmp soft regs depending on compiler options. Anyway, that's not apparently related to this problem.

When I trace, I see the comparison each time where it decides that each new task is the highest priority (but it's not) and updates pxCurrentTCB. Then when it starts, the IdleTask runs first, then yields to the one that really is the highest prio.

int main ( void )
{

xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
xTaskCreate( vTest2, "t2", configMINIMAL_STACK_SIZE, NULL, 1, NULL );

/* All the tasks have been created - start the scheduler. */
vTaskStartScheduler();

/* Should not reach here! */
for( ;; );
}


--My config:
#define configUSE_PREEMPTION0
#define configUSE_IDLE_HOOK0
#define configTICK_RATE_HZ( ( portTickType ) 1042 )
#define configMAX_PRIORITIES( ( unsigned portBASE_TYPE ) 1 )
#define configMINIMAL_STACK_SIZE( ( unsigned portSHORT ) 80 )
#define configTOTAL_HEAP_SIZE( ( size_t ) ( 10240 ) )
#define configMAX_TASK_NAME_LEN( 1 )
#define configUSE_TRACE_FACILITY0
#define configUSE_16_BIT_TICKS1
#define configIDLE_SHOULD_YIELD1

/* This parameter is normally required in order to set the RTOS tick timer.
*/

#define configCPU_CLOCK_HZ( ( unsigned portLONG ) 24000000 )


/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet1
#define INCLUDE_uxTaskPriorityGet1
#define INCLUDE_vTaskDelete1
#define INCLUDE_vTaskCleanUpResources0
#define INCLUDE_vTaskSuspend1
#define INCLUDE_vTaskDelayUntil1
#define INCLUDE_vTaskDelay1

RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 4, 2005
I beleive it the problem in xTaskCreate() is that it is storing uxPriority in the wrong position... A compiler bug. Not unlikely in this new release, GCC-m68hc1x 3.0.1.

RE: Debug new port GCC/HCS12

Posted by Nobody/Anonymous on August 4, 2005
>When I trace, I see the comparison each time where
>it decides that each new task is the highest priority
>(but it's not) and updates pxCurrentTCB. Then when
>it starts, the IdleTask runs first, then yields to the one
>that really is the highest prio.

Could this be an optimisation issue making the trace confusing? Can you inspect the variable values on the line

if( pxCurrentTCB->uxPriority <= uxPriority )



RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 4, 2005
So far, it appears to be a compiler error.

It is getting 0 for pxCurrentTCB->uxPriority for all my tasks, when the two I added should be 1. Maybe mixing up with the frame-pointer optimization. I compile with -fomit-frame-pointer, so I should try it with the frame pointer.

Some segments where the error is:

signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask )
{
4385:1b 9b leas-5,SP
4387:18 01 ae 12 movw121a <_.d1>, 2,-SP
438b:1a
438c:6c 82 std2,SP
438e:18 05 8b 12 movw11,SP, 121a <_.d1>
4392:1a

00004393 <.LM2>:
signed portBASE_TYPE xReturn;
tskTCB * pxNewTCB;
static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */

/* Allocate the memory required by the TCB and stack for the new task.
checking that the allocation was successful. */
pxNewTCB = prvAllocateTCBAndStack( usStackDepth );
4393:fc 12 1a ldd121a <_.d1>
4396:16 4b 7c jsr4b7c <prvAllocateTCBAndStack>
4399:6c 84 std4,SP

0000439b <.LM3>:

if( pxNewTCB != NULL )
439b:18 27 00 b8 lbeq4457 <.LM22>

0000439f <.LM4>:
{
portSTACK_TYPE *pxTopOfStack;

/* Setup the newly allocated TCB with the initial state of the task. */
prvInitialiseTCBVariables( pxNewTCB, usStackDepth, pcName, uxPriority );
439f:e6 f0 10 ldab16,SP

000043a2 <.LBB3>:
43a2:37 pshb
43a3:1b 9f des
43a5:18 02 8b ae movw11,SP, 2,-SP
43a9:18 01 ae 12 movw121a <_.d1>, 2,-SP
43ad:1a
43ae:ec 8a ldd10,SP
43b0:16 4a 8c jsr4a8c <prvInitialiseTCBVariables>

====

static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )
{
4a8c:1b 9a leas-6,SP
4a8e:6c 80 std0,SP

00004a90 <.LM213>:
pxTCB->usStackDepth = usStackDepth;
4a90:ec 88 ldd8,SP
4a92:ee 80 ldx0,SP
4a94:6c e0 1b std27,X

====

RE: Debug new port GCC/HCS12

Posted by Nobody/Anonymous on August 5, 2005
If You want to configure Your tasks to have a priority of "1" You should set configMAX_PRIORITIES to 2!

The two functions prvInitialiseTCBVariables() and vTaskPrioritySet() limit the priority automatically to (configMAX_PRIORITIES - 1), which is "0" in Your case, before copying it into the task's control block.

/* This is used as an array index so must ensure it's not too large. */
if( uxPriority >= configMAX_PRIORITIES )
{
uxPriority = configMAX_PRIORITIES - 1;
}
pxTCB->uxPriority = uxPriority;

Maybe a future version of FreeRTOS will call an ErrorHook function to inform the user about this :)


You also configured configTICK_RATE_HZ to 1042 Hz. Doesn't matter, but it is very uncommon.

#define configTICK_RATE_HZ ( ( portTickType ) 1042 )


Are You still using the MC9S12C32 as out said in an earlier thread? If yes, configTOTAL_HEAP_SIZE is also wrong. You can't assign 10K of RAM to the heap manager while the MC9S12C32 only has 2K. I suggest using just 1K and spending the rest on globals and the main stack.

#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1024 ) )

Regards,

Sven

RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 5, 2005
Thanks Sven,

I found that before reading your post, but good to confirm. It didn't realy make sense using the word MAX. If I say "the max is 255", I don't mean the maximum value is 254. I guess it means max number of priority levels counting 0? It should be named differently. Never mind though, I'll just try to remember :) Good thing for source code, because the documentation just doesn't do it.

My current port does not even use configTICK_RATE_HZ yet, but is using RTI divider, which does not get any closer to 1000 Hz with 16MHz xtal.

I plan to get it working on a DP256B, then cut down mem sz to run on the C32.

RE: Debug new port GCC/HCS12

Posted by Nobody/Anonymous on August 6, 2005
Just one remark on the RTI-timer: I run FreeRTOS on a DG256C (16 MHz XTAL) and also use the RTI for the system timer. Using the configuration below I get a tick duration of 1.024ms (977Hz). That should be the closest possible setting to 1ms.

#define RTI_PRESC_11 (2)
#define RTI_MODULUS_8 (7)

// prescaler value for RTI
#define RTI_PRESC RTI_PRESC_11
// modulus value for RTI
#define RTI_MODULUS RTI_MODULUS_8

// prescaler value for RTI register RTICTL
#define RTI_Prescaler() ((RTI_PRESC << 4) | RTI_MODULUS)

// set RTI prescaler
RTICTL = RTI_Prescaler();


In order to achieve a higher accuracy with the RTI, I wrote some macros to convert ms -> ticks and vice versa. There are versions for each combination of the system timer width (16/32 bits) and the timer duration (1024us (RTI) and 1000us (MDC or one of the TOCs)). Maybe You find them useful.

// task cycle - init in [ms]
portTickType xTaskCycle = MS2OSTICKS (100);

// wait
vTaskDelayUntil (&xLastWakeTime, xTaskCycle);


// FreeRTOSConfig.h
// tick duration in micro seconds
#define configTICK_RATE_US 1024

/* task timing macros */

#if ( configUSE_16_BIT_TICKS == 1 )

#if ( configTICK_RATE_US == 1024 )
#define MS2OSTICKS(t) ( (portTickType)((((uint32)(t) * 1000UL) + 512UL) / 1024UL))
#define OSTICKS2MS(t) ((unsigned portSHORT)((((uint32)(t) * 1024UL) + 500UL) / 1000UL))
#elif ( configTICK_RATE_US == 1000 )
#define MS2OSTICKS(t) ( (portTickType)(t))
#define OSTICKS2MS(t) ((unsigned portSHORT)(t))
#else
#error "No valid configuration for current setting of configTICK_RATE_US!"
#endif

#else

#if ( configTICK_RATE_US == 1024 )
#define MS2OSTICKS(t) ( (portTickType)((((uint32)(t) * 1000UL) + 512UL) / 1024UL))
#define OSTICKS2MS(t) ((unsigned portLONG)((((uint32)(t) * 1024UL) + 500UL) / 1000UL))
#elif ( configTICK_RATE_US == 1000 )
#define MS2OSTICKS(t) ( (portTickType)(t))
#define OSTICKS2MS(t) ((unsigned portLONG)(t))
#else
#error "No valid configuration for current setting of configTICK_RATE_US!"
#endif

#endif

Regards,
Sven

RE: Debug new port GCC/HCS12

Posted by Jeff Smith on August 8, 2005
Something I thought strange in S12CRGV2/D V02.07, Table 3-2 "RTI Frequency Divide Rates"

I find that many of these divide rates come out the same as one in another row. For example, RTR value 0010001 (2*2^10) is the same as RTR value 0100000 (2^11).

As a result, I threw out 48 of the values as redundant. In your case, you chose 01110010 (8*2^11), or div by 16384. So just say 2^14, which is 7 and 0 (1010000) for your values. Thanks for pointing out the value better than the one I found.

For accuracy, I decided it would be worth using a timer compare (maybe TC0) for the RTOS tick.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner