ASCLIN_Shell_UART example code for TC297 causes Data Address Alignment Trap?

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

cross mob
User19424
Level 3
Level 3
First solution authored First like received
Hello,
I was trying Infineon's example code since I need to send via Serial to the computer a printed message.

After Integrating the example and making sure all needed "#includes" are actually included (and the whole thing compiled successfully) I tried to run the code and it got to this part:


/* Print info to the console */
printInfo(&g_ascStandardInterface);

//That called this function:

void printInfo(IfxStdIf_DPipe *io)
{
IfxStdIf_DPipe_print(io, ENDLINE);
IfxStdIf_DPipe_print(io, "******************************************************************************"ENDLINE);
IfxStdIf_DPipe_print(io, "This is an example that shows how to use the Infineon Shell from iLLDs. "ENDLINE);
IfxStdIf_DPipe_print(io, "In order to toggle the LEDs enter the command '" COMMAND_TOGGLE "' followed by one of the "ENDLINE);
IfxStdIf_DPipe_print(io, "following parameters: "ENDLINE);
IfxStdIf_DPipe_print(io, " - '0': turns on all the LEDs on the board "ENDLINE);
IfxStdIf_DPipe_print(io, " - '1': toggles the LED D107 "ENDLINE);
IfxStdIf_DPipe_print(io, " - '2': toggles the LED D108 "ENDLINE);
IfxStdIf_DPipe_print(io, " - '3': toggles the LED D109 "ENDLINE);
IfxStdIf_DPipe_print(io, " - '4': toggles the LED D110 "ENDLINE);
IfxStdIf_DPipe_print(io, "Any other parameter turns off all the LEDs and reports a Shell command error. "ENDLINE);
IfxStdIf_DPipe_print(io, "******************************************************************************"ENDLINE);
}




The code then caused a trap running IfxStdIf_Dpipe_print. From debugging I saw that this is what caused it:

Ifx_SizeT Ifx_Fifo_write(Ifx_Fifo *fifo, const void *data, Ifx_SizeT count, Ifx_TickTime timeout)


and specifically line 338 : buffer.base = fifo->buffer;

Does anyone have any clue as to why this would happen?
In case it will help, here is what "io" contains (The Standard interface object):
4680.attach

I would very appreciate any sort of help understanding this 🙂
0 Likes
8 Replies
teoBits
Employee
Employee
5 sign-ins 100 replies posted 50 replies posted
Hello,

If you just need to send via serial to the computer a message, the ASCLIN_Shell_UART_1 example is not the best one that can be exploited.
Instead, you can try the UART_VCOM_1 example, which should be easier and straightforward: UART_VCOM_1_KIT_TC297_TFT code and tutorial.

Anyway, to help you with your project, we need some more information: which kind of trap are you getting? (If you don't know how to recognize it, this training can be helpful: CPU_Trap_Recognition_1 tutorial)
Would it be possible to see the whole project that is causing the trap?

Best regards,
teoBits
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
teoBits wrote:
Hello,

If you just need to send via serial to the computer a message, the ASCLIN_Shell_UART_1 example is not the best one that can be exploited.
Instead, you can try the UART_VCOM_1 example, which should be easier and straightforward: UART_VCOM_1_KIT_TC297_TFT code and tutorial.

Anyway, to help you with your project, we need some more information: which kind of trap are you getting? (If you don't know how to recognize it, this training can be helpful: CPU_Trap_Recognition_1 tutorial)
Would it be possible to see the whole project that is causing the trap?

Best regards,
teoBits


Hello, Thanks for the answer!
The Trap is "Data Address Alignment"
Trap Class 2 TIN 4

I took a look at the example you referenced, and it does seem simpler, but it still used the same function that crashes in my case (IfxAsclin_Asc_write(), which calls the problematic Ifx_Fifo_write()) 😞

Unfortunately I cannot provide the project as a whole.
But I'll try to explain more what the issue is:

A structure named "fifo" is filled with a value "buffer" here (This function is called by IfxAsclin_Asc_initModule())

Ifx_Fifo *Ifx_Fifo_init(void *buffer, Ifx_SizeT size, Ifx_SizeT elementSize)
{
Ifx_Fifo *fifo = NULL_PTR;

size = Ifx_AlignOn32(size); /* data transfer is optimised for 32 bit access */
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, elementSize <= size);
/* Check size over maximum FIFO size */
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (size <= IFX_SIZET_MAX));

{
fifo = (Ifx_Fifo *)buffer;
fifo->eventReader = FALSE;
fifo->eventWriter = TRUE;
fifo->buffer = (uint8 *)Ifx_AlignOn64(((uint32)fifo) + sizeof(Ifx_Fifo));
fifo->shared.count = 0;
fifo->shared.maxcount = 0;
fifo->shared.readerWaitx = fifo->shared.writerWaitx = 0;
fifo->startIndex = fifo->endIndex = 0;
fifo->size = size;
fifo->elementSize = elementSize;
}

return fifo;
}


More functions are run, and then the trap occurs here:

Ifx_SizeT Ifx_Fifo_write(Ifx_Fifo *fifo, const void *data, Ifx_SizeT count, Ifx_TickTime timeout)
{
Ifx_TickTime DeadLine;
Ifx_SizeT blockSize;
Ifx_CircularBuffer buffer;
boolean Stop = FALSE;

IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, fifo != NULL_PTR);
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, data != NULL_PTR);

if (count != 0)
{
buffer.base = fifo->buffer; // **********TRAP IS HERE*************
buffer.length = (uint16)fifo->size; /* size always fit into 16 bit */
buffer.index = (uint16)fifo->endIndex; /* startIndex always fit into size */
DeadLine = getDeadLine(timeout);




Here are some memory snapshots of each value:
You can see the line causing the trap, and then a snap of each value and it's memory representation. Also attached is the Registry state
4671.attach
4672.attach
4673.attach
4675.attach
4676.attach


Again Thank you for the answer and I would appreciate any help understanding this error
0 Likes
ScottW
Employee
Employee
10 sign-ins First solution authored First like received
Hi BEC,

Can you show the declaration of the variable you're passing as the void *buffer parameter, and the call to Ifx_Fifo_init(...)?
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
Scott Winder wrote:
Hi BEC,

Can you show the declaration of the variable you're passing as the void *buffer parameter, and the call to Ifx_Fifo_init(...)?


Hi thank you for your help 🙂
Sure thing:

This is the call, it is called from IfxAsclin_Asc_initModule() at line 295 of "Ifx_Asclin_Asc.c"
4660.attach

And the variable:

4681.attach

Also Just in case this helps debug, here are the rest of the variables passed:

4679.attach


Again many thanks!
0 Likes
ScottW
Employee
Employee
10 sign-ins First solution authored First like received
Edited to remove the verbiage suggesting that the 32-bit alignment is unnecessary.

config->txBuffer is not 32-bit aligned but fifo->buffer is 64-bit aligned and that was the most obvious candidate for the cause of the trap.

Are you allocating config->txBuffer yourself, or letting IfxAsclin_Asc_initModule(...) do it?

Are you able to run the serial demos without modification?


0 Likes
User19424
Level 3
Level 3
First solution authored First like received
Scott Winder wrote:
I don't see anything wrong with the alignment here. config->txBuffer is not 32-bit aligned (it doesn't need to be) but fifo->buffer is 64-bit aligned and that was the most obvious candidate for the cause of the trap.

Are you allocating config->txBuffer yourself, or letting IfxAsclin_Asc_initModule(...) do it?

Are you able to run the serial demos without modification?


The allocation occurs in iniSerialInterface(), part of ASCLIN_shell_UART.c :

/* FIFO buffers configuration */
ascConf.txBuffer = g_uartTxBuffer; /* Set the transmission buffer */
ascConf.txBufferSize = ASC_TX_BUFFER_SIZE; /* Set the transmission buffer size */
ascConf.rxBuffer = g_uartRxBuffer; /* Set the receiving buffer */
ascConf.rxBufferSize = ASC_RX_BUFFER_SIZE; /* Set the receiving buffer size */

/*
*
*
*/
IfxAsclin_Asc_initModule(&g_asclin, &ascConf);


Here are the definitions:



#define ASC_TX_BUFFER_SIZE 64 /* Define the TX buffer size in byte */
#define ASC_RX_BUFFER_SIZE 64 /* Define the RX buffer size in byte */

/* The transfer buffers allocate memory for the data itself and for FIFO runtime variables.
* 8 more bytes have to be added to ensure a proper circular buffer handling independent from
* the address to which the buffers have been located.
*/
uint8 g_uartTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
uint8 g_uartRxBuffer[ASC_RX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
Hello Again Infineon Community,

I managed to solve the issue and would like to share how it case this issue comes up again:

Turns out the fifo struct was indeed misaligned. It's address was like I've shown before, 0x70012416, which caused the trap.
I manually changed the address to 0x70012414 just to see what happens, and no trap occurred.

The fix I found that works is the following:

In the ASCLIN_shell_UART.c file, the following declaration exists:

uint8 g_uartTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];


This is what causes the issue. Luckily the fix is simple:

uint8 g_uartTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8] __attribute__ ((__align(32)));


The same issue occurs in UART_VCOM.c example and the fix is the same.

Take into consideration this is the Tasking compiler fix. Other compilers will have a different alignment syntax.

Good day 🙂
0 Likes
ScottW
Employee
Employee
10 sign-ins First solution authored First like received
Thank you for the update with the solution!
0 Likes