Debug new port GCC/HCS12

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.

Debug new port GCC/HCS12

I forgot to say the simulator (http://hc12text.com/)

Debug new port GCC/HCS12

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.

Debug new port GCC/HCS12

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_PREEMPTION        0 #define configUSE_IDLE_HOOK            0 #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_FACILITY    0 #define configUSE_16_BIT_TICKS        1 #define configIDLE_SHOULD_YIELD        1 /* 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_vTaskPrioritySet        1 #define INCLUDE_uxTaskPriorityGet        1 #define INCLUDE_vTaskDelete                1 #define INCLUDE_vTaskCleanUpResources    0 #define INCLUDE_vTaskSuspend            1 #define INCLUDE_vTaskDelayUntil            1 #define INCLUDE_vTaskDelay                1

Debug new port GCC/HCS12

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.

Debug new port GCC/HCS12

>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 )

Debug new port GCC/HCS12

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     movw    121a <_.d1>, 2,-SP     438b:    1a     438c:    6c 82           std    2,SP     438e:    18 05 8b 12     movw    11,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        ldd    121a <_.d1>     4396:    16 4b 7c        jsr    4b7c <prvAllocateTCBAndStack>     4399:    6c 84           std    4,SP 0000439b <.LM3>:     if( pxNewTCB != NULL )     439b:    18 27 00 b8     lbeq    4457 <.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        ldab    16,SP 000043a2 <.LBB3>:     43a2:    37              pshb     43a3:    1b 9f           des     43a5:    18 02 8b ae     movw    11,SP, 2,-SP     43a9:    18 01 ae 12     movw    121a <_.d1>, 2,-SP     43ad:    1a     43ae:    ec 8a           ldd    10,SP     43b0:    16 4a 8c        jsr    4a8c <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           std    0,SP 00004a90 <.LM213>:     pxTCB->usStackDepth = usStackDepth;     4a90:    ec 88           ldd    8,SP     4a92:    ee 80           ldx    0,SP     4a94:    6c e0 1b        std    27,X ====

Debug new port GCC/HCS12

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

Debug new port GCC/HCS12

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.

Debug new port GCC/HCS12

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

Debug new port GCC/HCS12

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.