Model based System basis chip(SBC)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Model based System basis chip(SBC)

864 Views
omarelzaafarany
Contributor I

Hello,
I am working on a project to convert the SBC driver that comes with S32 IDE for the MPC5744p board.

I have created a Matlab function at the Simulink model that acts as a function wrapper that calls a main() function of the SBC driver of the demo example that comes with S32 IDE.
However, it appears that SBC initialization stick in the code portion in the osif_baremetal.c
while (*pSem == 0u)
{
uint32_t crt_ticks = osif_GetCurrentTickCount();
uint32_t delta = crt_ticks - start;
if ((timeoutTicks != OSIF_WAIT_FOREVER) && (delta > max))
{
/* Timeout occured, stop waiting and return fail code */
osif_ret_code = STATUS_TIMEOUT;
break;
}
}

0 Kudos
2 Replies

847 Views
mariuslucianand
NXP Employee
NXP Employee

Hello @omarelzaafarany,

The problem you are facing is caused by the generated code architecture. Basically, the code that you have inserted is executed inside an interrupt. This is a method used by the MBDT in order to ensure the step time (I will explain below). Problem is that the Osif waits for the osif_tick_cnt variable to be incremented in the osif_Tick() handler. We are using the MPC, so the SDK uses the PIT_Channel 3 in order to run the osif_Tick() handler that will increment the osif_tick_cnt variable. But because the program you have inserted is called from inside an interrupt particularly the PIT_Channel0, and the PITChannel3 Interrupt has no priority set by the SDK, the MCU will not preempt the PITChannel0 in order to trigger the Channel 3 and to increment that variable. 

mariuslucianand_0-1610479668025.png

The easiest fix for your program to work is to use the following code before executing your custom code.

/* Set priority for PIT Channel 3 ISR */
INT_SYS_SetPriority(PIT_Ch3_IRQn, 8U);

This line will set a higher interrupt for the PIT Channel 3, used by the Osif and will preempt the PIT Channel 0 to increment the value.

In the generated code, MBDT generates 3 functions (based on MathWorks' Embedded coder architecture): Initialize, Step and Terminate.

In Initialize we set the clocks, configure the peripherals and configure the PIT Channel 0 that triggers the Step function every Fixed Step-Size set in the configuration parameters. Simulink is a time-driven environment, so in order to make sure that the model is triggered every Step size, we call it from inside the PIT interrupt. Terminate is not used because the program will loop forever.

Now, I understand what you are trying to do (You are trying to add support for the SBC_fs65 that we do not cover in MBDT using custom code) and you are definitely on the right path!

But the problem with your application is that from inside an interrupt, the code will end up running an entire another application. It will perform again the clocks initialization, while loops, and so on. What you should do is to reuse as much as possible the code generated by the MBDT for example the SPI initialization, and from the custom code, you should call the API from inside the SBC driver. You have here such example https://community.nxp.com/t5/NXP-Model-Based-Design-Tools/How-to-use-your-own-C-code-in-our-Toolbox-... where the program uses the BCC driver to communicate with another chip by inserting the driver functions using custom code. Another example that worth having a look on it, can found here https://community.nxp.com/t5/NXP-Model-Based-Design-Tools/MPC5744P-and-MC33771-Configuration/m-p/107... 

Another suggestion I have is to include in the "inputs" folder only the drivers for the SBC because in the MBDT we already include the drivers from the SDK.

If you have other questions, feel free to share them and we will try to address them.

But with this example, you are on the right path!

Hope this helps,

Marius

 

 

 

815 Views
omarelzaafarany
Contributor I

Thank you very much for your great help.
I have added the line 
/* Set priority for PIT Channel 3 ISR */
INT_SYS_SetPriority(PIT_Ch3_IRQn, 8U);
which configures the priority of Ch3 interrupt. The osif_tick_cnt  variable is incremented successfully.
However, the OSIF_SemaWait function returned with status STATUS_TIMEOUT.  That is because the semaphore is not risen to high so a timeout occurs.  I wonder why the semaphore is not risen to high, I know it is a volatile variable but what will assign it on the hardware level.

 

status_t OSIF_SemaWait(semaphore_t * const pSem,
const uint32_t timeout)
{
DEV_ASSERT(pSem != NULL);

status_t osif_ret_code = STATUS_SUCCESS;

osif_UpdateTickConfig();
if ((timeout == 0u))
{
/* when the timeout is 0 the wait operation is the equivalent of try_wait,
meaning that if the semaphore is 0 return immediately with an error code
*/
if (*pSem == 0u)
{
osif_ret_code = STATUS_TIMEOUT;
}
}
else
{
/* timeout is not 0 */
uint32_t timeoutTicks;
if (timeout == OSIF_WAIT_FOREVER)
{
timeoutTicks = OSIF_WAIT_FOREVER;
}
else
{
/* Convert timeout from milliseconds to ticks. */
timeoutTicks = MSEC_TO_TICK(timeout);
}
uint32_t start = osif_GetCurrentTickCount();
uint32_t end = (uint32_t)(start + timeoutTicks);
uint32_t max = end - start;
while (*pSem == 0u)
{
uint32_t crt_ticks = osif_GetCurrentTickCount();
uint32_t delta = crt_ticks - start;
if ((timeoutTicks != OSIF_WAIT_FOREVER) && (delta > max))
{
/* Timeout occured, stop waiting and return fail code */
osif_ret_code = STATUS_TIMEOUT;
break;
}
}
}

if (osif_ret_code == STATUS_SUCCESS)
{
osif_DisableIrqGlobal();
--(*pSem);
osif_EnableIrqGlobal();
}

return osif_ret_code;
}

0 Kudos