Trust M initialization infinite loop

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MaxMartin
Level 3
Level 3
First like given 25 sign-ins First solution authored

Hi everyone,

Following my previous experience with an Optiga Trust X Evaluation Kit, I started working with an Optiga Trust Mv3.
I am using a ARM Sitara Cortex-A8 AM3352 in bare metal as a host processor in my circuit. I cloned the repository available here to start working with the Trust M: https://github.com/Infineon/optiga-trust-m I saw that there wasn't any Platform Abstraction Layer already available for my processor, so I followed the steps of this guide (https://github.com/Infineon/optiga-trust-m/tree/develop/pal/NEW_PAL_TEMPLATE) to understand what I had to implement in my PAL. After finishing it, I wanted to test it on Infineon's examples, available in the repo at optiga-trust-m/examples/optiga/.

My first experience was to try the example_optiga_init_deinit.c program, to see if I was able to start communications with the Trust M correctly. I changed that code a little bit to adapt it to my needs: I am using the I2C in polling mode for the Cortex-A8, so the WAIT_AND_CHECK_STATUS macro loops on timers to check if their deadline was reached or not, instead of waiting for interrupts. The two main functions called for the initialization of communications between the two processors are optiga_util_create and optiga_util_open_application. I don't have any issue executing these functions, everything seems to perform as expected.

What I understood is that the optiga_util_create function creates an event, later triggered as a callback by a timer reaching its deadline. This mecanism is used 4 times after executing the optiga_util_create function: first callback is optiga_cmd_queue_scheduler, which then calls back optiga_cmd_event_trigger_execute, which then calls back ifx_i2c_init 2 times. I followed every step of that execution, and everything seems fine to me. The i2c bus is initialized and is ready to receive some traffic. I have an oscilloscope and a UART session to debug in case it's needed.
When creating an instance of optiga_util_t with optiga_util_create, a callback function is associated, to give upper layers the state of execution in Infineon's layers. In the example_optiga_init_deinit.c file, that callback changes the state of a variable which is used as a condition in the WAIT_AND_CHECK_STATUS loop.

I noticed that I was never exiting that loop, even though all the previous function executions seemed to be fine.
After a bit of investigation, I understood that I was never leaving that loop because the variable was never changed, meaning that the callback function associated to my instance of optiga_util_t was never called.

My question is the following: When and where is that optiga_util_t associated callback supposed to be triggered ? Is there documentation somewhere detailing all the steps in the init of communications with the Trust M ?
I can't figure out a way of getting out of that loop. It seems to me that the initialization is complete and that's it's just a callback issue, but I might be wrong and there might be a deeper issue that I didn't notice.

Thank you for you answer !

0 Likes
1 Solution

Hi @Karishma_S,

After a little bit more investigation, I saw that I didn't have any callback after reading or writing in my pal_i2c, which is my fault. I forgot to complete that part of the pal because I didn't read the comments well enough.

After completing it and changing my timer system to the single hardware timer with a flag only, I seem to have a working solution. I'll create another thread if I have issues, but I think I am now on the right track. You can close this thread for now.

Sorry for such a stupid mistake !

Regards

View solution in original post

0 Likes
3 Replies
Karishma_S
Moderator
Moderator
Moderator
50 solutions authored First comment on blog 250 sign-ins

Hi @MaxMartin,

The reason why it hangs is mostly the incorrect implementation of pal_os_event, the callback mechanism has to be precise. Can you please check the implementation of pal_os_event?

0 Likes

Hi @Karishma_S,

Thank you for you answer. As a first draft, I am using a hardware timer available on my Cortex-A8, ticking every 1 milliseconds. In that hardware timer interrupt, I just increase the number of milliseconds since startup by 1, and that's all.

In order to manage several timers for callbacks, I created a list of 8 software timers, which are configured as such :

typedef struct timer_sitara {
    uint32_t initial_time;
    uint32_t waiting_time;
    uint8_t to_be_run;
    void (* callback)();
} timer_sitara_t;
 
The initial_time corresponds to the moment when the timer is created. The waiting_times corresponds for the number of milliseconds to wait before triggering the timer. The callback is the function we want to call when the timer reaches its deadline.
 
In the pal_os_event.c file, when we want to create a timer, I just initialize one of the software timer as such:
 
void pal_os_event_register_callback_oneshot(pal_os_event_t * p_pal_os_event,
                                                                             register_callbackcallback, void * callback_args, uint32_t time_us)
{
    p_pal_os_event->callback_registered = callback;
    p_pal_os_event->callback_ctx = callback_args;
    new_sw_timer(time_us, pal_os_event_trigger_registered_callback);
}
 
It shows that I just add the time we want to wait for, and the function pal_os_event_trigger_registered_callback as a callback to handle the function we want to call back.
 
When we wait for that loop, because I don't have interrupt for my software timers, I use a polling method on the software timers:
 
while (optiga_lib_status == OPTIGA_LIB_BUSY)
{
    check_timers();
}
 
That function does the following:
-> checks if initial_time + waiting_time < current_millisecond_time
-> if yes, executes pal_os_event_trigger_registered_callback
-> if not, moves to check another one of the 8 timers
 
With that mecanism, I am able to execute optiga_util_create and optiga_util_open_application and I can see that it works, because I use 4 different timers which trigger 4 different callbacks.
However, it seems that I never have any callback to optiga_lib_callback, which works like this in my main.c:
 
static volatile optiga_lib_status_t optiga_lib_status;
static void optiga_lib_callback(void * context, optiga_lib_status_t return_status)
{
    optiga_lib_status = return_status;
}

void optiga_example(void)
{
    optiga_lib_status_t return_status;
    optiga_util_t * me_util;
    initSWTimers();
    Timer2Start();
    me_util = optiga_util_create(0, optiga_lib_callback, NULL);       
    optiga_lib_status = OPTIGA_LIB_BUSY;
    return_status = optiga_util_open_application(me_util, 0);
    while (optiga_lib_status == OPTIGA_LIB_BUSY)
    {
       check_timers();
    }
}
 
My guess is that, when all the operations are finished, a call to optiga_lib_callback should be triggered by the optiga_util_t instance, but it doesn't seem to be the case. I am doing something wrong somewhere ? Where is that call to optiga_lib_callback done in the code ? I can't seem to find where it is triggered.
 
Regards
0 Likes

Hi @Karishma_S,

After a little bit more investigation, I saw that I didn't have any callback after reading or writing in my pal_i2c, which is my fault. I forgot to complete that part of the pal because I didn't read the comments well enough.

After completing it and changing my timer system to the single hardware timer with a flag only, I seem to have a working solution. I'll create another thread if I have issues, but I think I am now on the right track. You can close this thread for now.

Sorry for such a stupid mistake !

Regards

0 Likes