Not applicable
Sep 08, 2014
12:47 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 08, 2014
12:47 AM
Hi All,
I would like some of my XMC4500 functions to be re-entrant. They will be called from the main program and 2 interrupt levels. Can anyone point me in to some documentation on how to do this please ?
Thank you very much
Best regards
Aaron
I would like some of my XMC4500 functions to be re-entrant. They will be called from the main program and 2 interrupt levels. Can anyone point me in to some documentation on how to do this please ?
Thank you very much
Best regards
Aaron
- Tags:
- IFX
7 Replies
Sep 08, 2014
11:53 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 08, 2014
11:53 AM
So far I've had luck with this approach: Use stack automatic storage for all function local variables to make that function re-entrant. Any non-automatic shared memory accessed by both main loop and ISR callbacks should either be atomic or protected by a synchronization mechanism.
This synchronization mechanism seemed to work for me in an ADC ISR callback. After calling ADC001_GetResult(), I take care to write the conversion results and a timestamp atomically into the structure pointed to by p.
(I'm not using an RTOS here. If I were, I'd use the semaphores and mutexes supplied by the RTOS instead.)
In the ISR:
Code called from the main loop (non-ISR) that atomically gets the conversion and timestamp for export:
This synchronization mechanism seemed to work for me in an ADC ISR callback. After calling ADC001_GetResult(), I take care to write the conversion results and a timestamp atomically into the structure pointed to by p.
(I'm not using an RTOS here. If I were, I'd use the semaphores and mutexes supplied by the RTOS instead.)
typedef struct {
uint32_t time; /**< time of the ADC ISR Callback (Aligned on 32 bit boundary) in milliseconds */
uint16_t rawRd; /**< raw ADC results (Aligned on 32 bit boundary) */
uint8_t semaphore; /**< Lock bit for Cortex M3/M4 LDREX/STREX exclusive access action */
} __attribute__ ((aligned (4))) AD_Results_Type;
In the ISR:
AD_Results_Type * p;
uint8_t * p_lock_bit = &(p->semaphore); // points to semaphore-like synchronization byte
// Cortex-M4 so called 'Exclusive Action':
// If the main thread (or another interrupt?) has already grabbed the semaphore
// then don't alter the conversion data in p->
if(__LDREXB( p_lock_bit)==0) // if lock bit is not claimed
{
if (__STREXB(1,p_lock_bit) == 0) // try to claim it.
{ // If the semaphore was claimed safely then
// access to different fields of p-> can now be done atomically:
p->time = now;
p->rawRd = Result.Result;
*p_lock_bit = 0; // release the semaphore
}
}
Code called from the main loop (non-ISR) that atomically gets the conversion and timestamp for export:
uint8_t * p_lock_bit = &(p->semaphore); // points to semaphore
// Cortex-M4 so called 'Exclusive Action':
if(__LDREXB( p_lock_bit)==0) // if lock bit is not claimed
{
if (__STREXB(1,p_lock_bit) == 0) // try to claim it.
{ // If the semaphore was claimed safely then
// access to different fields of p-> can now be done atomically:
if (ADC_ResultNotAvailable(p))
{
*p_lock_bit = 0; // release the semaphore if we grabbed it
return ADC_NoAvailableReading_Error;
}
if (Counts)
*Counts = p->rawRd;
if (ptime)
*ptime = p->time;
*p_lock_bit = 0; // release the semaphore if we grabbed it
break;
}
}
Not applicable
Sep 09, 2014
12:16 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
12:16 AM
For the XC800 you use the keyword reentrant and the compiler switches to using stack pushing for that function. It's pretty straightforward and simple:
I'd be surprised if there wasn't a similar mechanism for your platform.
void foo() reentrant {
…
}
I'd be surprised if there wasn't a similar mechanism for your platform.
Not applicable
Sep 09, 2014
12:16 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
12:16 AM
Hi Zoompig,
Thank you very much for taking the time to reply and for your examples. Much appreciated.
Best regards
Aaron
Thank you very much for taking the time to reply and for your examples. Much appreciated.
Best regards
Aaron
Not applicable
Sep 09, 2014
12:53 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
12:53 AM
Hi Kamikaze,
Thank you very much for your suggestion. Coming from the Keil 51 arena I was hoping to be able to use the reentrant directive, I will dig a little deeper.
Best regards
Aaron
Thank you very much for your suggestion. Coming from the Keil 51 arena I was hoping to be able to use the reentrant directive, I will dig a little deeper.
Best regards
Aaron
Not applicable
Sep 09, 2014
05:42 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
05:42 AM
Keil supports the XMC 4500 and provides reentrant support: http://www.keil.com/dd/chips/infineon/arm.htm
Not applicable
Sep 09, 2014
05:49 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
05:49 AM
Thanks Kamikaze.
Not applicable
Dec 22, 2015
04:25 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 22, 2015
04:25 AM
Hi everyone,
Can anyone tell me if the DAVE 3 compiler creates reentrant functions by default or do I need to specify my functions as reentrant somehow ?
For example, if I want the following function to be called by Main() and an Interrupt at the same time how do I ensure it's local variables aren't corrupted ?
Thank you very much
Best regards
Aaron
Can anyone tell me if the DAVE 3 compiler creates reentrant functions by default or do I need to specify my functions as reentrant somehow ?
For example, if I want the following function to be called by Main() and an Interrupt at the same time how do I ensure it's local variables aren't corrupted ?
uint8_t Digital_Output(uint8_t OutputNumber, uint8_t NewState)I come from a Keil C51 background which used the 'reentrant' directive at the function definition and I have also noticed the DAVE library functions such as 'ADC001_Init()' in ADC001.h use the 'Reentrant' directive.
{
uint8_t OutputChanged = FALSE;
// Function code....................
return OutputChanged;
}
Thank you very much
Best regards
Aaron