AVR10008 - FreeRTOS
AVR10008 - FreeRTOS
AVR10008 - FreeRTOS
Table of Contents
1. API overview ........................................................................................ 3 1.1 Initializing .......................................................................................................... 3 1.1.1 Initialization functions .......................................................................... 3 1.2 freertos_peripheral_options_t ........................................................................... 3 1.2.2 Examples ............................................................................................ 5 1.3 Transmitting ...................................................................................................... 8 1.3.1 Transmit functions .............................................................................. 8 1.3.2 Standard transmit functions ................................................................ 9 1.3.3 Fully asynchronous transmit functions. ............................................. 11 1.4 Receiving ........................................................................................................ 13 1.5 Receive functions for SPI and TWI ................................................................. 14 1.5.1 Standard receive functions for SPI and TWI ..................................... 14 1.5.2 Fully asynchronous receive functions for SPI and TWI peripherals .. 16 1.6 Receive functions for USART ......................................................................... 19 2. Revision History ................................................................................. 21
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
1.
API overview
FreeRTOS ASF functions are provided to manage the efficient transmission and reception of serial data. At the time of writing, the TWI, I2C and USART peripherals are supported. A uniquely named function is provided for each supported peripheral to initialize the FreeRTOS driver for that peripheral, write bytes to that peripheral, and read bytes from that peripheral. The source files that implement the FreeRTOS ASF functions for SAM3 and SAM4 parts are contained in the ASF/common/services/freertos/sam directory of the ASF distribution. The tasks that demonstrate how to use the FreeRTOS ASF functions are contained in the ASF/thirdparty/freertos/demo/peripheral_control directory, and subdirectories.
1.1
1.1.1
Initializing
Initialization functions
Initialization functions are shown in Listing 1.
Listing 1. FreeRTOS ASF driver initialization functions.
Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes. In all cases, the first parameter is a pointer to the peripheral, and uses the standard ASF defined type. sam_uart_options_t is also a standard ASF type. sam_uart_options_t is used to define the USART operation parameters, such as baud rate and parity. freertos_peripheral_options_t is a FreeRTOS ASF specific type that is described in the next sub-section. Source code that demonstrates the use of each initialization function is provided at the end of this section.
1.2
freertos_peripheral_options_t
freertos_peripheral_options_t is the structure shown in Listing 2. The structure members are described in Table 1.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Listing 2.
Table 1.
Description A pointer to a buffer into which the PDC will write received data. This parameter is (at the time of writing) only required by the USART driver, and is ignored by drivers provided for other peripherals. The size, in bytes, of the buffer pointed to by the receive_buffer structure member. This parameter is (at the time of writing) only required by the USART driver, and is ignored by drivers provided for other peripherals.
receive_buffer_size
interrupt_priority
Sets the priority of the interrupt generated by the PDC. PDC interrupts are configured and processed by the FreeRTOS ASF drivers. The application writer does not need to concern themselves with installing or handling interrupts. It is essential that the interrupt priority is not set above configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is defined in FreeRTOSConfig.h. Invalid priority values are trapped by an assert() in the driver code if configASSERT() is defined in FreeRTOSConfig.h. http://www.freertos.org/RTOS-Cortex-M3-M4.html provides additional information for readers who are not familiar with interrupt priority assignment on Cortex-M3 and Cortex-M4 microcontrollers, or with FreeRTOS configuration.
operation_mode
operation_mode is included to allow future versions of the FreeRTOS ASF drivers to support multiple modes of operation on a single peripheral. Valid values are documented in Table 2. At the time of writing, there is only one valid value for each supported peripheral. Individual bits in the options_flags value configure an aspect of the drivers behavior. Bit definitions are documented in Table 3. Bit definitions can be ORed together.
options_flags
Table 2.
Valid values for the operation_mode parameter of the freertos_peripheral_options_t structure. At the time of writing, only a single value is supported for each peripheral.
Effect Configures the USART peripheral as an RS232 port. Configures the SPI peripheral as an SPI master. Configures the TWI peripheral as an I2C master.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Table 3.
Valid bit value definitions for the options_flag member of the freertos_peripheral_options_t structure.
Bit Definition
USE_TX_ACCESS_MUTEX USE_RX_ACCESS_MUTEX WAIT_TX_COMPLETE
Effect
This bit makes the transmit functionality of the peripheral driver thread aware. Set this bit if the application code writes to the peripheral from more than one RTOS task. This bit makes the receive functionality of the peripheral driver thread aware. Set this bit if the application code reads from the peripheral from more than one RTOS task. The FreeRTOS ASF drivers provide both standard (blocking) and fully asynchronous transmit functions. The transmit functions are described later in this application note. The WAIT_TX_COMPLETE bit must be set to use the standard transmit function, and must be clear to use the fully asynchronous transmit function. If this bit is set, then an RTOS task that starts a transmission will wait for the transmission to complete before executing any further code. Other RTOS tasks will execute while the transmission is in progress, ensuring no processing time is wasted. Refer to the section in this application note that describes the transmit functions for more information.
WAIT_RX_COMPETE
The FreeRTOS ASF drivers provide both standard (blocking) and fully asynchronous receive functions. The receive functions are described later in this application note. The WAIT_RX_COMPETE bit must be set to use the standard receive function, and must be clear to use the fully asynchronous receive function. If this bit is set, then an RTOS task that starts a receive operation will wait for the receive operation to complete (or time out) before exiting the receive function. Other RTOS tasks will execute while the reception is in progress, ensuring no processing time is wasted. Refer to the application note section that describes the receive functions for more information.
1.2.2
Examples
Listing 3 is a code snippet that demonstrates how to use freertos_spi_master_init(). Listing 4 is a code snippet that demonstrates how to use freertos_twi_master_init(). Listing 5 is a code snipped that demonstrates how to uses freertos_usart_serial_init().
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Listing 3.
freertos_spi_ifprepare_spi_port(Spi*spi_base){ /*HandleusedtoaccesstheinitializedportbyotherFreeRTOSASFfunctions.*/ freertos_spi_iffreertos_spi; /*Configurationstructure.*/ constfreertos_peripheral_options_tdriver_options={ /*Thisperipheraldoesnotneedareceivebuffer,sothereceive_buffer valueisjustsettoNULL.*/ NULL, /*Thereisnoreceivebuffer,soreceive_buffer_sizeisnotusedandcan takeanyvalue.*/ 0, /*Theinterrupt_priorityvalue.*/ 0x0f, /*Theoperation_modevalue.*/ SPI_MASTER, /*Alltheavailableoptions_flagsbitsareset.*/ (USE_TX_ACCESS_MUTEX|USE_RX_ACCESS_MUTEX|WAIT_TX_COMPLETE|WAIT_RX_COMPLETE) }; /*CalltheSPIspecificFreeRTOSASFdriverinitializationfunction.*/ freertos_spi=freertos_spi_master_init(spi_base,&driver_options); if(freertos_spi!=NULL){ /*Callingfreertos_spi_master_init()willenabletheperipheralclock, andsettheSPIintomastermode.OtherASFconfigurationfunctions, suchasspi_set_clock_polarity(),andspi_set_baudrate_div()canthenbe calledhere.*/ } returnfreertos_spi; }
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Listing 4.
freertos_twi_ifprepare_twi_port(Twi*twi_base){ /*HandleusedtoaccesstheinitializedportbyotherFreeRTOSASFfunctions.*/ freertos_twi_iffreertos_twi; /*Configurationstructure.*/ freertos_peripheral_options_tdriver_options={ /*Thisperipheraldoesnotneedareceivebuffer,sothereceive_buffer valueisjustsettoNULL.*/ NULL, /*Thereisnoreceivebuffer,soreceive_buffer_sizeisnotusedandcan takeanyvalue.*/ 0, /*Theinterrupt_priorityvalue.*/ 0x0f, /*Theoperation_modevalue.*/ TWI_I2C_MASTER, /*Alltheavailableoptionsflagsareusedfordemonstrationpurposes.*/ (USE_TX_ACCESS_MUTEX|USE_RX_ACCESS_MUTEX|WAIT_TX_COMPLETE|WAIT_RX_COMPLETE) }; /*CalltheTWIspecificFreeRTOSASFdriverinitializationfunction.*/ freertos_twi=freertos_twi_master_init(twi_base,&driver_options); if(freertos_twi!=NULL){ /*Callingfreertos_twi_master_init()willenabletheperipheralclock, andsettheTWIintoI2Cmastermode.OtherASFconfigurationfunctions, suchastwi_set_speed(),canthenbecalledhere.*/ } returnfreertos_twi; }
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Listing 5.
freertos_usart_ifprepare_usart_port(Usart*usart_base, uint8_t*receive_buffer, uint32_treceive_buffer_size_in_bytes){ /*HandleusedtoaccesstheinitializedportbyotherFreeRTOSASFfunctions.*/ freertos_usart_iffreertos_usart; /*Configurationstructure.*/ freertos_peripheral_options_tdriver_options={ /*Thisperipheralhasfullduplexasynchronousoperation,sothe receive_buffervalueissettoavalidbufferlocation.*/ receive_buffer, /*receive_buffer_sizeissettothesize,inbytes,ofthebufferpointed tobythereceive_bufferstructuremember(receive_bufferabove).*/ receive_buffer_size_in_bytes, /*Theinterrupt_priorityvalue.*/ 0x0e, /*Theoperation_modevalue.*/ USART_RS232, /*Alltheavailableoptionsflagsareusedfordemonstrationpurposes.*/ (USE_TX_ACCESS_MUTEX|USE_RX_ACCESS_MUTEX|WAIT_TX_COMPLETE|WAIT_RX_COMPLETE) }; /*TheRS232configuration.Thisstructure,andthevaluesusedinitssetting, arefromthestandardASFUSARTdriver.*/ constsam_usart_opt_tusart_settings= { USART_BAUD_RATE, US_MR_CHRL_8_BIT, US_MR_PAR_NO, US_MR_NBSTOP_1_BIT, US_MR_CHMODE_NORMAL, 0/*OnlyusedinIrDAmode,soallvaluesareignored.*/ }; /*CalltheUSARTspecificFreeRTOSASFdriverinitializationfunction.*/ freertos_usart=freertos_usart_serial_init(usart_base,&usart_settings,&driver_options); returnfreertos_usart; }
1.3
1.3.1
Transmitting
Transmit functions
FreeRTOS ASF functions use the PDC to transfer data from a buffer to a peripheral for transmission. It should be noted, due to hardware restrictions, the buffer must be located in RAM. The microcontroller continues executing application code while the data is being transmitted. Data can be transmitted using either a standard (blocking) function call, or a fully asynchronous function call. The next two sub-sections describe the options.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
Note:
In an RTOS application, blocking does not mean polling or spinning, or in fact, using any processing time at all. If the executing task (thread of execution) enters the Blocked state, the RTOS will ensure no processing time is wasted by immediately starting to execute a different task.
1.3.2
status_code_tfreertos_spi_write_packet(freertos_spi_ifp_spi,constuint8_t*data, size_tlen,portTickTypeblock_time_ticks); status_code_tfreertos_twi_write_packet(freertos_twi_ifp_twi,twi_packet_t*p_packet, portTickTypeblock_time_ticks); status_code_tfreertos_usart_write_packet(freertos_usart_ifp_usart, constuint8_t*data,size_tlen,portTickTypeblock_time_ticks); Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes. In all cases, the first parameter is the handle of a peripheral that was opened using a FreeRTOS ASF initialization function (see Listing 1). Standard (as opposed to fully asynchronous) transmit functions can only be used if the freertos_driver_parameters.options_flags parameter passed into the initialization function had the WAIT_TX_COMPLETE bit set. The behavior of standard transmit functions is defined in Figure 1-1. The task that calls the transmit function does not exit the transmit function until all the data has been completely sent, or the time specified by the block_time_ticks parameter has expired. Block times are specified in RTOS tick counts. The portTickType type is defined by FreeRTOS. To specify a block time in milliseconds, divide the millisecond value by portTICK_RATE_HZ, and pass the result in the block_time_ticks parameter. portTICK_RATE_HZ is a constant defined by FreeRTOS.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
No
Yes
Wait for PDC transfer to complete (other tasks will execute during this wait) No. Return time out
Listing 7 is a code snippet that demonstrates how to use a standard transmit function.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
10
Listing 7.
status_code_twrite_two_strings(freertos_usart_iffreertos_usart){ uint8_twrite_buffer[5]; status_code_tresult; /*SendastringtotheUSART.ThestringmustbeinRAM,socopyitintoanarray.*/ strcpy(write_buffer,"one"); /*Usingablocktimeof10/portTICK_RATE_MSmeansdontblockanylongerthan 10ms.*/ result=freertos_usart_write_packet(freertos_usart,write_buffer,strlen("one"), 10/portTICK_RATE_MS); if(result==STATUS_OK){ /*freertos_usart_write_packet()doesnotreturnuntiltransmissionofthestringhas completed,meaningthewrite_bufferarraycanbereusedimmediatelywithoutanyrisk ofcorruptingtheoriginaltransmission.*/ strcpy(write_buffer,"two"); result=freertos_usart_write_packet(freertos_usart,write_buffer,strlen("two"), 10/portTICK_RATE_MS); } /*freertos_usart_write_packet()doesnotreturnuntiltransmissionofthestringhas completed,meaningthefunctioncanexiteventhoughthebufferbeingtransmittedis declaredonthefunctionsstack.*/ returnresult; }
1.3.3
status_code_tfreertos_spi_write_packet_async(freertos_spi_ifp_spi,constuint8_t*data, size_tlen,portTickTypeblock_time_ticks, xSemaphoreHandlenotification_semaphore); status_code_tfreertos_twi_write_packet_async(freertos_twi_ifp_twi,twi_packet_t*p_packet, portTickTypeblock_time_ticks,xSemaphoreHandlenotification_semaphore); status_code_tfreertos_usart_write_packet_async(freertos_usart_ifp_usart, constuint8_t*data,size_tlen,portTickTypeblock_time_ticks, xSemaphoreHandlenotification_semaphore); Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
11
In all cases, the first parameter is the handle of a peripheral that was opened using a FreeRTOS ASF initialization function (see Listing 1). Fully asynchronous transmit functions can only be used if the freertos_driver_parameters.options_flags parameter passed into the initialization function had the WAIT_TX_COMPLETE bit clear. The behavior of standard transmit functions is defined in Figure 1-2. The task that calls the transmit function exits the transmit function as soon as the transmission starts, and uses the notification_semaphore to know when the transmission has ended. The buffer being transmitted must exist, and cannot be modified, until the transmission has ended. Block times are specified in RTOS tick counts. portTickType is a type defined by FreeRTOS. To specify a block time in milliseconds, divide the millisecond value by portTICK_RATE_HZ, and pass the result in the block_time_ticks parameter. portTICK_RATE_HZ is a constant defined by FreeRTOS.
Figure 1-2. The behavior of fully asynchronous transmit functions.
Listing 9 is a code snippet that demonstrates how to use a fully asynchronous transmit function.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
12
Listing 9.
/*xSemaphoreHandleisaFreeRTOStypeusedtostoreahandletoasemaphore.Inthisexample, thesemaphorehasalreadybeencreatedusingacalltotheFreeRTOSvSemaphoreCreateBinary()API function,andisbeingpassedinasafunctionparameter.*/ status_code_twrite_two_strings(freertos_usart_iffreertos_usart, xSemaphoreHandlenotification_semaphore){ uint8_twrite_buffer[5]; status_code_tresult; /*SendastringtotheUSART.ThestringmustbeinRAM,socopyitintoanarray.The arraymustexistfortheentiretimetakentotransmitthestring.Thiscanbeensured bymakingitglobal,static,orbyallocatingitonthestackandthenensuringthestack framedoesnotchangeuntilthetransmissioniscomplete.*/ strcpy(write_buffer,"one"); /*notification_semaphore,passedintothefunction,isusedbytheFreeRTOSASFdriver tosignalthatthetransmissionhasfinished.Usingablocktimeof 100/portTICK_RATE_MSmeansdontblockanylongerthan100ms.*/ result=freertos_usart_write_packet_async(freertos_usart,write_buffer,strlen("one"), 100/portTICK_RATE_MS,notification_semaphore); if(result==STATUS_OK){ /*Transmissionofthestringwasstartedsuccessfully.*/ } /*..otherprocessingcanbeperformedhere,whilethestringisbeingtransmitted..*/ /*Anotherstringisgoingtobesent,butthewrite_bufferarraymustnotbealtered untiltheoriginaltransmissioniscomplete.Ifthenotificationsemaphoreisavailable, thenthetransmissioniscompleteandthefollowingfunctioncallwillreturn immediately.Ifthenotificationsemaphoreisnotavailable,thenthefollowingfunction callwillplacethistaskintotheBlockedstateforamaximumof200mstowaitforitto becomeavailable(othertaskswillexecuteduringthewait).*/ xSemaphoreTake(notification_semaphore,200/portTICK_RATE_MS); strcpy(write_buffer,"two"); result=freertos_usart_write_packet_async(freertos_usart,write_buffer,strlen("two"), 100/portTICK_RATE_MS,notification_semaphore); /*..otherprocessingcanbeperformedhere,whilethestringisbeingtransmitted..*/ /*Inthisexample,thearraybeingtransmittedisdeclaredonthestack.Ifthis functionexits,thearraywillnolongerexist,andifitwasstillbeingtransmitted, thetransmitteddatacanbecorrupted.Therefore,xSemaphoreTake()isusedagainto ensurethetransmissionhascompletelyfinishedbeforeallowingthefunctionto return.*/ xSemaphoreTake(notification_semaphore,200/portTICK_RATE_MS); returnresult; }
1.4
Receiving
On synchronous peripherals, such as the TWI and SPI, data reception timing is controlled by the bus master. On these peripherals, data is only received by the master when the master calls a receive function, the master controls the amount of data being received, and the received data is placed directly into the buffer specified in a parameter to the receive function.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
13
On asynchronous full duplex peripherals, such as the USART, data can be received at any time, not just when a receive function is called. On these peripherals, to ensure data is not lost, the FreeRTOS ASF drivers are configured to place all received data into a dma buffer, no matter when the data arrives. The dma buffer used is that specified by the freertos_driver_parameters.receive_buffer parameter to the function used to initialized the peripheral (see Listing 5). When a receive function is called, the data already in the dma buffer is copied into the user buffer specified in a parameter to the receive function. The receive function returns the number of bytes copied into the user buffer. Available but unread data remains in the dma buffer, ready for the next receive function call.
1.5
Note:
In an RTOS application, Blocking does not mean polling or spinning, or in fact, using any processing time at all. If the executing task (thread of execution) enters the Blocked state, the RTOS will ensure no processing time is wasted by immediately starting to execute a different task.
1.5.1
status_code_tfreertos_spi_read_packet(freertos_spi_ifp_spi,uint8_t*data,uint32_tlen, portTickTypeblock_time_ticks); status_code_tfreertos_twi_read_packet(freertos_twi_ifp_twi,twi_packet_t*p_packet, portTickTypeblock_time_ticks); Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes. In all cases, the first parameter is the handle of a peripheral that was opened using a FreeRTOS ASF initialization function (see Listing 1). Standard (as opposed to fully asynchronous) receive functions can only be used if the freertos_driver_parameters.options_flags parameter passed into the initialization function had the WAIT_RX_COMPLETE bit set. The behavior of standard receive functions is defined in Figure 1-3. The task that calls the receive function does not exit the receive function until all the requested data has been completely received, or the time specified by the block_time_ticks parameter has expired. Block times are specified in RTOS tick counts. portTickType is a type defined by FreeRTOS. To specify a block time in milliseconds, divide the millisecond value by portTICK_RATE_HZ, and pass the result in the block_time_ticks parameter. portTICK_RATE_HZ is constant defined by FreeRTOS.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
14
Figure 1-3. The behavior of standard receive functions for SPI and TWI peripherals.
Receive is thread aware if the USE_RX_ACCESS_MUTEX options flag bit was set when the peripheral was initialized Waiting for exclusive access to the peripheral (other tasks will execute during this wait) Yes Receive is thread aware?
No
Yes
Wait for PDC transfer to complete (other tasks will execute during this wait) No. Return time out
Listing 11 is a code snippet that demonstrates how to use a standard receive function.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
15
Listing 11.
voida_function(freertos_spi_iffreertos_spi) { /*Thereceivebufferisdeclaredstatictoensureitdoesnotoverflowthetaskstack.*/ staticuint8_treceive_buffer[50]; constmax_block_time_50ms=50/portTICK_RATE_MS; /*Looparound,readingandthenprocessing20bytesfromfreertos_spioneachiteration.*/ for(;;) { /*Receive20bytesfromfreertos_spiintoreceive_buffer.*/ if(freertos_spi_read_packet(freertos_spi,receive_buffer,20, max_block_time_50ms)==STATUS_OK){ /*freertos_spi_read_packet()doesnotreturnuntilalltherequestedbyteshave beenreceived,soitisknownthatthedatainreceive_bufferisalreadycomplete, andcanbeprocessedimmediately.*/ /*...Processreceiveddatahere...*/ do_something(receive_buffer); } } }
1.5.2
status_code_tfreertos_spi_read_packet_async(freertos_spi_ifp_spi,uint8_t*data, uint32_tlen,portTickTypeblock_time_ticks, xSemaphoreHandlenotification_semaphore); status_code_tfreertos_twi_read_packet_async(freertos_twi_ifp_twi,twi_packet_t*p_packet, portTickTypeblock_time_ticks,xSemaphoreHandlenotification_semaphore); Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes. In all cases, the first parameter is the handle of a peripheral that was opened using a FreeRTOS ASF initialization function (see Listing 1). Fully asynchronous receive functions can only be used if the freertos_driver_parameters.options_flags parameter passed into the initialization function had the WAIT_RX_COMPLETE bit clear. The behavior of standard receive functions is defined in Figure 1-4. The task that calls the receive function exits the receive function as soon as the reception starts, and uses the notification_semaphore to know when the reception has ended. Block times are specified in RTOS tick counts. portTickType is a type defined by FreeRTOS. To specify a block time in milliseconds, divide the millisecond value by portTICK_RATE_HZ, and pass the result in the block_time_ticks parameter. portTICK_RATE_HZ is a constant defined by FreeRTOS.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
16
Figure 1-4. The behavior of fully asynchronous receive functions for the SPI and TWI peripherals.
Listing 13 is a code snippet that demonstrates how to use a fully asynchronous receive function with a synchronous master peripheral.
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
17
Listing 13.
/*Thisexampledemonstrateshowasingletaskcanprocessdatawhileadditionaldataisbeing receivedontheSPIbus.Errorcheckingisomittedtosimplifytheexample.*/ voida_function(freertos_spi_iffreertos_spi) { /*Thebuffersintowhichthedataisplacedaretoolargetobedeclaredonthetaskstack,so areinsteaddeclaredstatic(makingthisfunctionnonreentrantmeaningitcanonlybecalled byasingletaskatatime,otherwisemultipletaskswouldusethesamebuffers).*/ staticuint8_tfirst_receive_buffer[BUFFER_SIZE],second_receive_buffer[BUFFER_SIZE]; xSemaphoreHandlefirst_notification_semaphore=NULL,second_notification_semaphore=NULL; constmax_block_time_500ms=500/portTICK_RATE_MS; /*Createthenotificationsemaphores,oneperbuffer.vSemaphoreCreateBinary()isa FreeRTOSAPIfunction.*/ vSemaphoreCreateBinary(first_notification_semaphore); vSemaphoreCreateBinary(second_notification_semaphore); /*NothinghasbeenreadovertheSPIbusyet,somakesurebothsemaphoresareempty.*/ xSemaphoreTake(first_notification_semaphore,0); xSemaphoreTake(second_notification_semaphore,0); /*Startanasynchronousreadtofillthefirstbuffer.Thefunctionwillbeableto accesstheportimmediatelybecausenothingelsehasaccessedityetallowingthe block_time_ticksvaluetobesetto0.*/ freertos_spi_read_packet_async(freertos_spi,first_receive_buffer,BUFFER_SIZE,0, first_notification_semaphore); for(;;) { /*Waituntilthefirstbufferisfull.Othertaskswillrunduringthewait.*/ xSemaphoreTake(first_notification_semaphore,max_block_time_500ms); /*Startanasynchronousreadtofillthesecondbuffer.Againblock_time_ticks issettozeroasitisknownthatthereadoperationthatwasfillingthefirst bufferhascompletedleavingtheSPIportavailable.*/ freertos_spi_read_packet_async(freertos_spi,second_receive_buffer,BUFFER_SIZE,0, second_notification_semaphore); /*Processthedatainthefirstreceivebufferwhilethesecondreceivebufferis beingrefreshed.*/ process_received_data(first_receive_buffer); /*Waituntilthesecondbufferisfull.Othertaskswillrunduringthewait.*/ xSemaphoreTake(second_receive_buffer,max_block_time_500ms); /*Startanasynchronousreadtofillthefirstbufferagain.*/ freertos_spi_read_packet_async(freertos_spi,second_receive_buffer,BUFFER_SIZE,0, second_notification_semaphore); /*Processthedatainthesecondreceivebufferwhilethefirstreceivebuffer isbeingrefreshed.*/ process_received_data(second_receive_buffer); } }
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
18
1.6
uint32_tfreertos_usart_serial_read_packet(freertos_usart_ifp_usart,uint8_t*data, uint32_tlen,portTickTypeblock_time_ticks); Parameters, and return values, are fully described in the ASF API documentation, and in source file comments directly above the respective function prototypes. The FreeRTOS ASF USART driver uses the PDC to transfer data from a peripheral to a circular buffer (the DMA buffer). Reception happens in the background, while the microcontroller is executing application code. freertos_usart_serial_read_packet() copies bytes from the DMA buffer into the buffer passed as a freertos_usart_serial_read_packet() parameter. The behavior of freertos_usart_serial_read_packet() is defined by Figure 1-5.
Figure 1-5. The behavior of the USART receive function.
Receive is thread aware if the USE_RX_ACCESS_MUTEX options flag bit was set when the peripheral was initialized Waiting for exclusive Rx access to the peripheral (other tasks will execute during this wait) Yes Receive is thread aware?
No
Yes
No
Yes. Return number of bytes read, which will equal the requested number of bytes
Yes
In this case the number of bytes read is less than the number of bytes requested
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
19
Listing 15.
voida_function(freertos_usart_iffreertos_usart) { uint8_treceive_buffer[20]; uint32_tbytes_received; portTickTypemax_wait_20ms=20/portTICK_RATE_MS; /*Attempttoread20bytesfromfreertos_usart.Iffewerthan20bytesareavailable,then waitamaximumof20msfortheresttoarrive.*/ bytes_received=freertos_usart_serial_read_packet(freertos_usart,receive_buffer,20, max_wait_20ms); if(bytes_received==20) { /*Allthebyteswerereceived.TheRTOStaskcallingthisfunction*may*havebeen placedintotheBlockedstatetowaitforallthebytestobeavailable.Othertasks willexecutewhilethistaskisintheBlockedstate.*/ } else { /*Fewerthantherequestednumberofbyteshavebeenreceived,sotheRTOStask callingthisfunctiondidentertheblockedstateforthefull20milliseconds.*/ } }
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
20
2.
Revision History
Doc. Rev. 42049A Date 11/2012 Comments Initial document release
Atmel AVR10008: ASF Specific FreeRTOS Functionality for Peripheral Control [APPLICATION NOTE]
42049AAVR/ARM11/2012
21
Atmel Corporation 2325 Orchard Parkway San Jose, CA 95131 USA Tel: (+1)(408) 441-0311 Fax: (+1)(408) 487-2600 www.atmel.com
Atmel Asia Limited Unit 01-5 & 16, 19F BEA Tower, Millennium City 5 418 Kwun Tong Road Kwun Tong, Kowloon HONG KONG Tel: (+852) 2245-6100 Fax: (+852) 2722-1369
Atmel Munich GmbH Business Campus Parkring 4 D-85748 Garching b. Munich GERMANY Tel: (+49) 89-31970-0 Fax: (+49) 89-3194621
Atmel Japan G.K. 16F Shin-Osaki Kangyo Building 1-6-4 Osaki Shinagawa-ku, Tokyo 141-0032 JAPAN Tel: (+81)(3) 6417-0300 Fax: (+81)(3) 6417-0370
2012 Atmel Corporation. All rights reserved. / Rev.: 42049AAVR/ARM11/2012 Atmel, Atmel logo and combinations thereof, AVR, Enabling Unlimited Possibilities, and others are registered trademarks or trademarks of Atmel Corporation or its subsidiaries. ARM , Cortex and others are registered trademarks or trademarks of ARM Ltd. Other terms and product names may be trademarks of others.
Disclaimer: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN THE ATMEL TERMS AND CONDITIONS OF SALES LOCATED ON THE ATMEL WEBSITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED OR STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS AND PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the accuracy or completeness of the contents of this document and reserves the right to make changes to specifications and products descriptions at any time without notice. Atmel does not make any commitment to update the information contained herein. Unless specifically provided otherwise, Atmel products are not suitable for, and shall not be used in, automotive applications. Atmel products are not intended, authorized, or warranted for use as components in applications intended to support or sustain life.