Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on December 29, 2013

Hello,

I am working on a project where i am using the FreeRTOS port provided in Atmel ASF. I run multiple tasks that uses different peripherals.

My plan was to use both TWI peripherals provided on the sam3x processor at the same time. The busses would be used from the same task and the transmissions started right after each other with only the slight delay of setting up the PDC controller between the start of the transmissions. Each of the buses communicates with two identical (except off course for the chip address) ESC units.

That was the background, now to my problem: When i do what i have described above, it only works for a few transmissions and then one of the buses stop working. I used my logic level analyzer to observe the bus behavior, and i can see that the two TWI buses do transmit a few messages simultaneously only to stop working after a short while. If i change the code so that I wait for each transfer to complete before initializing a TWI transfer on the other bus, then everything works well. This, however, requires twice the amount of time to complete all transfers.

I am currently using the following code to initiate a transfer(I am looping through all motors):

portBASE_TYPE twi_ans;
twi_ans = freertos_twi_write_packet_async(motors->motor[i].twi,
    &motors->motor[i].twi_data,
    motors->motor[i].xtransmit_block_time,
    motors->motor[i].twi_notification_semaphore);

if (twi_ans != STATUS_OK)
{
    //for (;;)
    {
        //Error! 
        toggle_pin(8);
    }

}

// TODO fix TWI so this is not needed! xSemaphoreTake(motors->motor[i].twinotificationsemaphore, motors->motor[i].xtransmitblocktime);

Here I am waiting for the transmission to complete before doing anything else. I would rather wait for the semaphore associated with the peripheral before trying to start the peripheral again.

This is only a problem since i have a very fast application (500-1000Hz) and i would like to use both buses to reduce communication time.

Has anyone else encountered this problem? Has this anything to do with freeRTOS or the FreeRTOS peripheral drivers provided in ASF or is this a hardware limitation/problem?

Also, I think that there is a problem with the configureinterruptcontroller function in the ASF verstion of FreeRTOS, I think that it is not configured to work with Cortex-M3/Coretx-M4 priority systems. I had to make a change to allow numerically higher values than configMAXSYSCALLINTERRUPT_PRIORITY, wich if i have understood things correctly, is a lower priority for these types of processors. Can anyone confirm this?

Regards Martin Lundh


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by rtel on December 30, 2013

I think the two channels should be completely independent as each has its own PDC registers, so I'm not sure why it would stop. I would have to re-visit the code to see for sure. To be honest I'm not sure if I have ever run two channels at once myself.

I presume you are using different semaphores for the two channels (rather than maybe accidentally using the same semaphore for both)?

configureinterruptcontroller

I just had a look at this function and it seems to just pass through whichever interrupt priority you set in "interruptpriority" member of the "freertosdriverparameters" parameter you pass into freertostwimasterinit(). It uses the CMSIS NVIC_SetPriority() function, so expects a value from 0 (highest priority) to 0x0f (lowest priority).

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on January 1, 2014

Thank you for the fast response!

I thought that the two channels would be completely independent too, so I am a bit confused by the behavior i am seeing. It seems like i have similar problems when using other peripherals via PDC too, if i have a task sending data rapidly on a USART channel, sometimes the TWI stops. I have to do some more tests before i can say with any certainty that the two are related.

Do you think that it could be a problem accessing the PDC control from multiple threads simultaneously? It was a thought i had when i first started looking in to the problem, but after reading the datasheet for the processor, and checking the code, it seems less and less likely...

I just double checked, and I am using different semaphore for each channel, so i do not think that is the problem.

Regarding the configureinterruptcontroller, i saw that there is the following code in the ASF version I have: configASSERT(interruptpriority <= configLIBRARYMAXSYSCALLINTERRUPTPRIORITY); After that it just uses the CMSIS NVICSetPriority() function as you say.

Regards Martin Lundh


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by rtel on January 1, 2014

Are you using the same interrupt priority for both TWI channels? If that makes a difference it will give a clue as to where to look in the code.

Also, are you using FreeRTOS V7.6.0 with configASSERT() defined? That will help trap any interrupt priority setting problems.

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on January 4, 2014

I have now tried to use both equal and different priories and it does not make a difference.

Just to make sure: The peripheral drivers should have a priority lower than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY (higher number, for example: configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 4)?

I am using FreeRTOS V7.3.0 (from ASF) with ConfigASSERT() defined. But i am not sure the assertion in configureinterruptcontroller is correct for use with Cortex M3 processors... it stops execution if the priority is numerically higher than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY.

I have disabled the assertion and tried priories both higher and lower than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY, and surprisingly, it all gives the same result, even if the drivers are given the highest priority(i know this is wrong to do, but i wanted to try) numerically value 0.

If I instead change the order at which i write to the channels(starting transfer on channel 1 and then on channel 2 instead of the other way around) i get a different timing behavior, the same channel does fail after a while though.

Regards Martin


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by rtel on January 4, 2014

I have created the demo project that comes in the ASF and can look through the code. So far everything I have seen looks as expected - each channel has its own PDC channel and its own semaphores.

Please post the freertosperipheraloptionst structure definition you are passing into each freertostwimasterinit() call (the definition of the second parameter passed into the freertostwimaster_init() function) so I can check your specific scenario.

Just to make sure: The peripheral drivers should have a priority lower than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY (higher number, for example: configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 4)?

Almost - the peripheral drivers should have a priority lower than or equal to configLIBRARYMAXSYSCALLINTERRUPTPRIORITY. Yes, higher numbers are lower priorities so configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 4 is ok provided (configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 4) is less than 15, because 15 is the very lowest valid priority.

I am using FreeRTOS V7.3.0 (from ASF) with ConfigASSERT() defined.

You can drop in the FreeRTOS V7.6.0 files to make better use of the configASSERT() macro. Additional error checks were put in since V7.3.0 to assist users as the interrupt model on Cortex-M parts is understandably confusion.

it stops execution if the priority is numerically higher than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY.

Really? That does not seem right. Looking at the code I see the following line:

	configASSERT(interrupt_priority <=
			configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);

which would seem to pass if the interrupt priority was equal to or numerically lower than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY, and therefore fail if the interrupt priority was numerically higher than configMAXSYSCALLINTERRUPT_PRIORITY - so I'm guessing that is the line you are referring to. I think it should be >=

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by rtel on January 4, 2014

Have a look at http://asf.atmel.com/bugzilla/show_bug.cgi?id=3233

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on January 10, 2014

Hi,

First of all, thanks for all the help!

I read the bug report and made some changes to the freeRTOS TWI handler and it seems to work much better now. I have checked the timing of the different interrupts, and it looks alright.

I do still have the occasional glitch on the bus, but I think that is a hardware problem rather than anything else.

The freertosperipheraloptions_t structure I am using is posted below. It should be OK I think after the conversation in this thread, and the fact that it does seem to work now.

freertos_peripheral_options_t async_driver_options = {
    NULL,											                        /* This peripheral does not need a receive buffer, so this parameter is just set to NULL. */
    0,												                        /* There is no Rx buffer, so the rx buffer size is not used. */
    (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1),	                        /* The priority used by the TWI interrupts. It is essential that the priority does not have a numerically lower value than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY*/
    TWI_I2C_MASTER,									                        /* TWI is configured as an I2C master. */
    0,																		/* The asynchronous driver is used, so WAIT_TX_COMPLETE and WAIT_RX_COMPLETE are not set. */
};

I consider my problem solved (remaining problem has most likely no relation to freeRTOS at all). Thank you for your support, and for a great software!

Regards Martin


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by rtel on January 10, 2014

Glad that solved the problem. I would be grateful if you could post the edited driver file here so I can ensure it gets updated in the driver library too.

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on January 12, 2014

Sure! As soon as I have removed some debugging code I used, I will be happy to post it. This will hopefully not take to long!

Regards.


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by apsolar on January 28, 2014

Hello Martin,

Would you be willing to share your solution? I noticed you are not setting any option flags. I am struggling to get the TWI implementation working reliably on a Sam3N4B. The read works sometimes and doesn't most of the time. I think that the issue is related to what is mentioned here.

To simplify things, all I am doing is single byte reads and I notice that the interrupt is never triggered.

regards Ankit


FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by mlundh on February 8, 2014

Hi,

I am sorry it has taken me some time to get back to this problem, I was away on businesses. I have, since i came back, tested the code, and it seems to work well for me. I believe that my remaining problems are hardware related. I would be grateful if someone could test the code and provide feedback.

I have found that if there is an error on the bus(for whatever reason), it sometimes takes too long before it becomes operational again. I think better error handling might be needed, but om not sure how to implement this. This could also be hardware dependent, I am not sure yet, I will keep on working though!

In the attached file i have made the changes discussed above. Note that I have also changed the driver to only use one transactioncompletesemaphore just as only one mutex is used. Since the bus is half duplex, there is no need for a second semaphore. The second semaphore also created some problems since the code now uses the TXCOMP interrupt.

Also, feel free to remove/change any comments i made in the code, they are only there to remind me what changed I made.

In freertosperipheralcontrol.c I made the following changes:

void configure_interrupt_controller(const enum IRQn peripheral_irq,
		uint32_t interrupt_priority)
{
	configASSERT(interrupt_priority >=
			configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);

	NVIC_ClearPendingIRQ(peripheral_irq);
	NVIC_SetPriority(peripheral_irq, interrupt_priority);
	NVIC_EnableIRQ(peripheral_irq);
}

and:

void freertos_start_pdc_transfer(
		freertos_dma_event_control_t *dma_event_control,
		const uint8_t *data, size_t len, void *pdc_base_address,
		xSemaphoreHandle notification_semaphore, bool is_transmitting)
{

(removed * from the semaphore handle)

I think that should be all, if there is anything missing or if I made any mistakes please let me know.

Regards Martin

Attachments

freertos_twi_master.c (25627 bytes)

FreeRTOS in atmel studio 6, PDC problem. Arduino Due Board. TWI problem.

Posted by apsolar on February 14, 2014

Thank you Martin,

I had made similar changes but there are still some differences when I compare to your code.

I will try your changes and respond in a few days.

regards Ankit


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS