Sat 20 Feb 2010 12:03:34 PM UTC, comment #3:
> Now, just one more little request: When I pass the pointer to
> a task function to the FreeRTOS task creation routine, gcc passes
> passes a 16-bit pointer, as I expect. Unfortunately, there is
> not a direct "function pointer" reference to the task function,
> so the linker has no need to put the task into the trampoline
> (or, more to the point, it has no need to keep it there).
The point the trampoline is generated and used is where the linker tries to assign an address bigger than 16 bit to a 16 bit symbol. It doesn't matter what type this symbol had in the C code.
Example:
void SomeFunc (void) {
}
...
uint16_t adr = (uint16_t)SomeFunc;
If SomeFunc is located above 128k, then there will be a trampoline for it and adr will contain the word address of that trampoline.
|
Fri 19 Feb 2010 10:12:47 PM UTC, comment #2:
Wow, I am humbled. The option that Joerg suggested has been in my Make file for years now but I have insisted that all function pointer targets must reside in flash < 128KiB. After recompiling without my little hack to force function pointer targets to < 128K (and verified in the map that more than a few targets are indeed above the 128K boundary), my application appears to be working fine.
Now, just one more little request: When I pass the pointer to a task function to the FreeRTOS task creation routine, gcc passes a 16-bit pointer, as I expect. Unfortunately, there is not a direct "function pointer" reference to the task function, so the linker has no need to put the task into the trampoline (or, more to the point, it has no need to keep it there).
Example:
typedef void (pdTASK_CODE)( void );
portBASE_TYPE xTaskCreate(
pdTASK_CODE pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pvCreatedTask
);
/* The focus servo task. */
void vFocusTask( void* pvParameters );
void
vStartFocus( uint8_t uxPriority )
{
. . .
xTaskCreate( vFocusTask, (signed portCHAR) taskName , FOCUS_STACK_SIZE, NULL, uxPriority, ( xTaskHandle ) NULL );
. . .
Is there some way to force the linker to keep some names in the trampoline even though the -Wl,--relax is specified in LDFLAGS? For now, I will leave my "put the function in lower 128K" hack in place for the task functions.
Stu Bell
|
Fri 19 Feb 2010 09:36:17 PM UTC, comment #1:
After some ongoing discussion about this in the (German)
mikrocontroller.net forum, it turns out that adding
-mrelax (or -Wl,--relax) appears to fix this. So linker
relaxations are probably mandatory when working with function
pointers and flash sizes >= 128 KiB.
This should probably be checked again, and then added to the
FAQ. (Just keeping this bug entry open as a reminder.)
|
Wed 17 Feb 2010 12:40:21 PM UTC, original submission:
Pointer to function works not correct with flash > 128k.
A pointer to a function is 16 bit. This is not enough in AVR's with more than 128k flash.
this is a part of the listfile (*.lss)
00020440 <vSend_Debug_Data>:
*/
//*****************************************************************************
void vSend_Debug_Data (void)
{
...
...
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);
204c0: 80 e0 ldi r24, 0x00 ; 0
204c2: 90 e0 ldi r25, 0x00 ; 0
204c4: 6a ef ldi r22, 0xFA ; 250
204c6: 70 e0 ldi r23, 0x00 ; 0
204c8: 0e 94 6e ec call 0x1d8dc ; 0x1d8dc <u8Add_Time_Task>
}
greetings Steffen Graap
|