This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to change FreeRTOS initial tick count ?

Hello,

I am using the NRF52840 with FreeRTOS and I would like to start the FreeRTOS tick count at a high value for testing purpose.

I have modified the  configINITIAL_TICK_COUNT value in the FreeRTOS.h file with a high value : 0xffffffff  - 0x1e000 = 0xfffe1fff

(0xffffffff correspond to the maximal tick count, TickType_t beeing a uint32_t value)

(0x1e000 = 2*60*1024 is for 2 minuts, configTICK_TATE_HZ value beeing at 1024)

It should start FreeRTOS tick count at 0xfffe1fff and go back to the zero value after 2 minuts (acctually this is what I want to test), but I have an unexpected result when I use the xTaskGetTickCount() function to see the tick count value (now is the value returned by the xTaskGetTickCount function) :

(FreeTROS.h) #define configINITIAL_TICK_COUNT 0

(LOG) now=4000 (4000 = 3*1024 = 3 sec)

--

(FreeTROS.h) #define configINITIAL_TICK_COUNT 0xfffe1fff

now=3119

I wonld expect the now value to be mutch higer than 4000 (about 0xfffe1fff = 4294844415)

Does anyone know where my problem comes frone ?

Thanks a lot,

Clément

  • This is purely FreeRTOS initialization code. The value you mentioned in configINITIAL_TICK_COUNT  is directly initialized to below in task.c

    PRIVILEGED_DATA static volatile TickType_t xTickCount 				= ( TickType_t ) configINITIAL_TICK_COUNT;

    The device specific port changes never resets xTickCount, so i am not sure why you are seeing this behavior. 

    It would be interesting to know where exactly you are printing these logs? and the code snippets on how you print them.

  • Thank you for your answer,

    I am printing these logs in a thread called after the vTaskStartScheduler(). I was logging my 32bits TickType_t with a %d instead of a %ld, it may resolve a part of the probleme but I am still in trouble:

    I am trying to reproduce this error in a simple environment : I am using the NRF52840 dev board and I took the ble_app_hrs_freertos example code from the nrf SDK. I just added my log in a periodically called function:

    static void heart_rate_meas_timeout_handler(TimerHandle_t xTimer)
    {
    TickType_t val;
    val = xTaskGetTickCount();
    NRF_LOG_INFO("Tick Count : %ld", val);

    And I changed the FreeRTOS.h file from the SDK :

    #define configINITIAL_TICK_COUNT 0xff000000

    I am using CoolTerm (mac) to print my logs and I have the folowing result:

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1289

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1290

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (196).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (197).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (198).[0m

    <info> app: Tick Count : 1291

    .[1;31mLogs dropped (197).[0m

    <info> app: Tick Count : 1292

    .[1;31mLogs dropped (197).[0m

    <info> app: Tick Count : 1911

    <info> app: Tick Count : 2784

    <info> app: Tick Count : 3796

    <info> app: Tick Count : 4793

    <info> app: Tick Count : 5784

    It seems that the tick count restarts after a while. Do you have an idea of what is happening ?

  •  you seems to have found a bug in freertos kernel.

    in tasks.c-> vTaskStartScheduler() -> TickCount is uncondictionally initiallized to 0 even though it is already initialized correctly to configINITIAL_TICK_COUNT   when created.

    So comment out the below line in in tasks.c-> vTaskStartScheduler()

    xNextTaskUnblockTime = portMAX_DELAY;
    xSchedulerRunning = pdTRUE;


    //xTickCount = ( TickType_t ) 0U;   

    /* If configGENERATE_RUN_TIME_STATS is defined then the following
    macro must be defined to configure the timer/counter used to generate
    the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS
    is set to 0 and the following line fails to build then ensure you do not
    have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your
    FreeRTOSConfig.h file. */
    portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();

    And everything works as you expect.

  • also note that RTC1 counter are 24bit registers, your value does not fit in the counter register 

    You calculation must be as below

    0x00FFFFFF - 0x1e000 = 0xFE1FFF 

    This will fit the 24 bit RTC1 counter register

    so set 

    (FreeTROS.h) #define configINITIAL_TICK_COUNT 0xfe1fff (and not 0xfffe1fff )

    if you are testing for the highest possible tick count then i guess your way of testing will not help you much as tick count is 32 bit and RTC1 counter is 24 bit.

  • I tried to comment the line //xTickCount = ( TickType_t ) 0U;   on task.c, I changed the value of configINITIAL_TICK_COUNT in FreeRTOS.h to a given value and I have the following result:

    when configINITIAL_TICK_COUNT=0x0, 0x1, 0x2, ..., 0x7 : the logs works well and the first xTaskGetTickCount gives a value from 3E8 to 3EF.

    when configINITIAL_TICK_COUNT=0x8 or higer : there are dropped logs and the xTaskGetTickCount gives a strange value (examples: configINITIAL_TICK_COUNT=0x8 -> xTaskGetTickCount=1005CF0, configINITIAL_TICK_COUNT=0x8000 -> xTaskGetTickCount=0x1005C00, configINITIAL_TICK_COUNT=0x80000 -> xTaskGetTickCount=0x1005A20)

    I am still using the NRF52840 dev board and I took the ble_app_hrs_freertos example code from the nrf SDK with the following changes :

    main.c

    I added a xTeskGetTickCount in a function called periodically:

    static void heart_rate_meas_timeout_handler(TimerHandle_t xTimer)
    {
    TickType_t val;
    val = xTaskGetTickCount();
    int_to_hex(val);

    I added a function to print the xTeskGetTickCount result in hexadecimal:

    void int_to_hex(TickType_t decimal){
    long long quotient, remainder;
    int i, j = 0;
    char hexadecimal[100];

    quotient = decimal;

    while (quotient != 0)
    {
    remainder = quotient % 16; //step 1
    if (remainder < 10)
    hexadecimal[j++] = 48 + remainder; //step 2
    else
    hexadecimal[j++] = 55 + remainder; //step 3
    quotient = quotient / 16; //step 4
    }
    //step 6
    for (i = j; i >= 0; i--)
    NRF_LOG_INFO("%c", hexadecimal[i]);
    }

    Do you have any idear of what is happening ? Thanks a lot!

Related