Hello, Ulf!
You wrote on Tue, 17 Jun 2008 06:19:43 +0200:
US> Looks like a Linker problem to me.
US> The program is linked to one place, but you are executing in another
US> place, so position independent code will execute, but data (the string)
US> is read from another location.
I'm pretty sure the linker script is correct. And I burn the second image at
the precisely same address, as defined by linker (I also double checked that
with utility "J-Flash ARM" shipped by Segger along with their JTAG toolkit).
Regarding disabling interrupts before passing control to the second
application: is it mandatory to do, or depends on requirements? And the same
question about resetting: I heard that it's recommended to reset CPU before
another code takes on control, for example in bootloader environments. What
can you say about it?
US> You can test the following:
[skip]
I compiled the code and investigated assembly output. I'm not ARM assembly
expert though, but as I understood characters are loaded as constants:
...
mov r3, #84 ; 0x54 code of 'T'
strb r3, [fp, #-45]
ldrb r3, [fp, #-45]
and r3, r3, #255 ; 0xff
strb r3, [fp, #-44]
mov r3, #104 ; 0x68 code of 'h'
...
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
Reply by Ulf Samuelsson●June 17, 20082008-06-17
Roman Mashak wrote:
> Hello,
>
> MCU - at91sam7s64
> toolchain - Yagarto (based on gcc-4.2.1)
>
> I have two distinct applications residing in the internal flash. The
> first one located at 0x100000, prints string and transfers control to
> the second application located at 0x104000, which lights the LED and
> prints a string.
> The 1st application is compiled with vectors placed in ROM, while in
> the 2nd application vectors are placed in RAM and it also does
> remapping, configures timer and timer's interrupt handler (where LED
> blinking occurs and where I also print a string out DBGU).
>
> Before transferring control, I also disable all interrupts in the
> first application:
>
> AT91C_BASE_AIC->AIC_IDCR = ~0;
> AT91C_BASE_AIC->AIC_ICCR = ~0;
>
> for (i = 0; i < 8; ++i) {
> AT91C_BASE_AIC->AIC_EOICR = 0;
> }
>
> The 2nd code, upon receiving control, enables IRQ and FIQ.
>
> The whole thing doesn't work as I expected. First application prints,
> then runs second application, which lights LED on but instead of
> printing string it outputs some garbage on a DBGU port.
>
> The interesting thing is that that string from timer service routine
> is ALWAYS printed properly, while the first AT91F_DBGU_Printk() is
> clumsy. May be after enabling interrupts and before issuing the first
> 'printk' some timeout should pass or there is a special peripheral
> reset procedure that I need to accomplish before passing control to
> another application?
> Looking forward to getting any useful advices. Thanks in advance.
>
Looks like a Linker problem to me.
The program is linked to one place, but you are executing in another
place, so position independent code will execute, but data (the string)
is read from another location.
You can test the following:
unsigned char string[32]
volatile unsigned char c;
c='T';
string[0] = c;
c='h';
string[1] = c;
c='i';
string[2] = c;
c='s';
string[3] = c;
c=' ';
string[4] = c;
c='i';
string[5] = c;
c='s';
string[6] = c;
c='a';
string[7] = c;
c='t';
string[8] = c;
c='e';
string[9] = c;
c='s';
string[10] = c;
c='t';
string[11] = c;
c='!';
string[12] = c;
c='\n';
string[13] = c;
c='\0';
string[14] = c;
printf(string);
Check the assmbler code that the characters are loaded as constants
and are not loaded with PC relative load instructions.
If that is the case, run the program.
> Best regards, Roman Mashak.
--
Best Regards,
Ulf Samuelsson
This is intended to be my personal opinion which may,
or may not be shared by my employer Atmel Nordic AB
Reply by Roman Mashak●June 16, 20082008-06-16
Hello,
MCU - at91sam7s64
toolchain - Yagarto (based on gcc-4.2.1)
I have two distinct applications residing in the internal flash. The first
one located at 0x100000, prints string and transfers control to the second
application located at 0x104000, which lights the LED and prints a string.
The 1st application is compiled with vectors placed in ROM, while in the 2nd
application vectors are placed in RAM and it also does remapping, configures
timer and timer's interrupt handler (where LED blinking occurs and where I
also print a string out DBGU).
Before transferring control, I also disable all interrupts in the first
application:
AT91C_BASE_AIC->AIC_IDCR = ~0;
AT91C_BASE_AIC->AIC_ICCR = ~0;
for (i = 0; i < 8; ++i) {
AT91C_BASE_AIC->AIC_EOICR = 0;
}
The 2nd code, upon receiving control, enables IRQ and FIQ.
The whole thing doesn't work as I expected. First application prints, then
runs second application, which lights LED on but instead of printing string
it outputs some garbage on a DBGU port.
The interesting thing is that that string from timer service routine is
ALWAYS printed properly, while the first AT91F_DBGU_Printk() is clumsy. May
be after enabling interrupts and before issuing the first 'printk' some
timeout should pass or there is a special peripheral reset procedure that I
need to accomplish before passing control to another application?
Looking forward to getting any useful advices. Thanks in advance.
Best regards, Roman Mashak.