Forums

Micrium UCOS-II

Started by jdauchot September 13, 2007
Hi

This is my next task

So I will let everyone else interested know hen I get there

Regards

Jean-Jacques
--- In l..., "derbaier" wrote:
>
> --- In l..., "jdauchot" wrote:
> >
> > Hi Dave
> >
> > I got the code to work. But this is what I had to do
> >
> > In the start.s file I had to bypass the init data code
> Now it is time to go back and find out why your RAM initialization
> code failed, or you are likely to have some very interesting
problems
> in the future using this start.s file with RAM initialization
> bypassed, if you have less than trivial C code.
>

An Engineer's Guide to the LPC2100 Series

Hi Dave

There is a mix up here

I am still using your code start.s etc not anyone else code

I am still trying to undersand why the init code fails

Regards

Jean-Jacques

--- In l..., David Hawkins wrote:
>
> Hi Jean-jacques,
>
> > I am using your orginal .ld file with the memory linits changed
>
> So you've mixed Richard's linker script, with my example
> startup code. This is the source of your problem.
>
> If you'd read the document associated with my example code
> you should have understood the relationship between the
> linker script symbols and the symbols used in the
> startup file. I deliberately changed the names from
> the ones found in the default linker script and crt0.s
> file so that things were a bit clearer; the document
> was intended as a tutorial after all.
>
> >>> ldr r0, data_source
> >>> ldr r1, data_start
> >>> ldr r2, data_end
> >>> ldr r1, bss_start
> >>> ldr r2, bss_end
>
> All of these symbols come from the linker script. If you
> edit the linker script associated with my example code
> to reflect your specific processor, then things should work.
> Then you can use Richard's linker script, and replace
> my start.s with Richard's crt0.s. Then that should work
> too.
>
> So, although you've struggled a bit, I think you'll
> have learned something.
>
> Cheers,
> Dave
>
OK Dave
This the link file I modified

/* lpc2138_flash.ld
*
* Linker script for Philips LPC2138 ARM microcontroller
* applications that execute from Flash.
*/

/* The LPC2294 has 256kB of Flash, and 16kB SRAM */

MEMORY
{
flash (rx) : org = 0x00000000, len = 0x00040000
sram (rw) : org = 0x40000000, len = 0x00004000
}
SECTIONS
{
/* ------------------------
* .text section (executable code)
* ------------------------
*/
.text :
{
*start.o (.text)
*(.text)
*(.glue_7t) *(.glue_7)
} > flash
. = ALIGN(4);

/* ------------------------
* .rodata section (read-only (const) initialized variables)
* ------------------------
*/
.rodata :
{
*(.rodata)
} > flash
. = ALIGN(4);

/* End-of-text symbols */
_etext = . ;
PROVIDE (etext = .);

/* ------------------------
* .data section (read/write initialized variables)
* ------------------------
*
* The values of the initialized variables are stored
* in Flash, and the startup code copies them to SRAM.
*
* The variables are stored in Flash starting at _etext,
* and are copied to SRAM address _data to _edata.
*/
.data : AT (_etext)
{
_data = . ;
*(.data)
} > sram
. = ALIGN(4);

_edata = . ;
PROVIDE (edata = .);

/* ------------------------
* .bss section (uninitialized variables)
* ------------------------
*
* These symbols define the range of addresses in SRAM that
* need to be zeroed.
*/
.bss :
{
_bss = . ;
*(.bss)
*(COMMON)
} > sram
. = ALIGN(4);
_ebss = . ;

_end = .;
PROVIDE (end = .);
Regards

Jean-jacques

--- In l..., David Hawkins wrote:
>
> Hi Jean-Jacques,
>
> > There is a mix up here
> >
> > I am still using your code start.s etc not anyone else code
> >
> > I am still trying to undersand why the init code fails
>
> Right, but who's linker script? The start.s code goes
> hand-in-hand with the linker script.
>
> Dave
>
I just looked at the linker code and startup.s file in
the ucos/ex1/ folder, and in start.s you'll see the lines:

/* ----------------------------
* 32-bit constants (and storage)
* ----------------------------
*
* These 32-bit constants are used in ldr statements.
*/

/* LPC SRAM starts at 0x40000000, and there is 32Kb = 8000h */
STACK_START: .word 0x40008000
PLLBASE: .word 0xE01FC080
MAMBASE: .word 0xE01FC000

/* Linker symbols */
data_source: .word _etext
data_start: .word _data
data_end: .word _edata
bss_start: .word _bss
bss_end: .word _ebss
Its this code that takes the _xxx linker symbols, and then
creates 32-bit variables that are used in the code.

Sorry, my previous comments implied that the data_start
symbols were from the linker file.

Look into that a little more and see if you find a problem.

Regards,
Dave
Hi Jean-Jacques,

> There is a mix up here
>
> I am still using your code start.s etc not anyone else code
>
> I am still trying to undersand why the init code fails

Right, but who's linker script? The start.s code goes
hand-in-hand with the linker script.

Dave
Hi Jean-Jacques,

> I have now got ten tasks running with this code without
> this init code in the start.s

Sorry, but 'this' you mean:

skipping everything below

/* ----------------------------
* C runtime setup
* ----------------------------
*/

in \ucos\ex1\start.s?

If so, you are skipping the copying of the initialized data
values from Flash into SRAM, and clearing the .bss to zero.

Its quite possible for C code to work skipping these sections.

However, this would not be considered a standard C runtime
environment.

Its possible there is a bug in the start.s code ... I vaguely
recall someone posting a slight modification to this code that
was more robust, but I never got the chance to test it.

Even if there was a bug in the code, the ex1 code definitely
works unchanged ... ah, but that is the problem, you had
to change it to work on your board. So perhaps your changes
re-exposed this same problem.

> if I can get this code to work with yagarto tools chain that
> would be great.
>
> I have manage to to this with other projects

Yeah, I'm sure it'll work with any tool chain.

So, assuming there is a bug in that setup code, go take a
look at Richard's crt0.s code, and use it instead. Likely
you'll need to edit it to reflect the symbols used in the
code starting at:

/* ----------------------------
* 32-bit constants (and storage)
* ----------------------------
*
* These 32-bit constants are used in ldr statements.
*/

Your map file, or objdump should also tell you how big
each of the sections in the elf file are. Perhaps there is
a zero length section, and my tutorial code doesn't handle
that well.

Isn't debugging fun! :)

Cheers,
Dave
--- In l..., "jdauchot" wrote:
>
> Hi Dave
>
> I have now got ten tasks running with this code without this init
> code in the start.s
>
> It would be interesting to find out why this is
>
> I will be happy to send this code to you which is yours to to see
> what is the problem
> if I can get this code to work with yagarto tools chain that would be
> great.
>
> I have manage to to this with other projects
>
> Regards
>
> Jean-Jacques
>
Sorry Jean-Jacques, I probably overstated the case for getting the RAM
initialization to work. If you are not using any pre-initialized
variables, and your C code does not expect an uninitialized variable
to be ZERO then it should probably work OK. That was the purpose of
the assembly code that you bypassed. That RAM initialization should
really be done as a good practice though. It is so small that it
should be fairly easy to debug by setting your debugger at the
beginning of that section and just stepping through it to see what is
wrong. I have something similar in all of my assembly startup code,
and once it is working you will probably never need to look at it again.

--Dave
> /* System mode stack */
> /* msr CPSR_c, #SYS_MODE|IRQ_DISABLE|FIQ_DISABLE */
> msr CPSR_c, #SYS_MODE
> mov sp, r0
>
> bl main <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > main works here

Note that you are branching to main() with interrupts disabled and in
system mode. This is ok because, in system mode, you can change CPSR_c.

>
> /* Leave the processor in system mode */
>
> /* ----------------------------
> * C runtime setup
> * ----------------------------
> */
> runtime_init:
> /* Copy .data */
> ldr r0, data_source
> ldr r1, data_start
> ldr r2, data_end
> copy_data:
> cmp r1, r2
> ldrne r3, [r0], #4
> strne r3, [r1], #4
> bne copy_data
>
> bl main <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Jump to
> main does not work

Are data_source, data_start and data_end defined in your linker
script? Take a look at the .elf file and see what values are passed
by the linker. Do this by creating a .lss file with your makefile:

OBJDUMP=arm-elf-objdump
ODFLAGS = -h -S -t

list : ${TARGET}.elf
${OBJDUMP} ${ODFLAGS} ${TARGET}.elf > ${TARGET}.lss

or from the command line like:

arm-elf-objdump -h -S -t .elf > .lss

Wander down the list until you find the dissassembly code for the
startup section.

>
> /* Clear .bss */
> ldr r0, =0
> ldr r1, bss_start
> ldr r2, bss_end
> clear_bss:
> cmp r1, r2
> strne r0, [r1], #4
> bne clear_bss
>
> /* Jump to main */
> bl main <<<<<<<<<<<<<<<<<<<<<<<<<<<<< does not work passed here
>

Same problem: are bss_start and bss_end defined by the linker script?

Not being able to initialize .data and .bss for a C program is a
serious problem. C depends on initial values.

Richard
> /* LPC SRAM starts at 0x40000000, and there is 32Kb = 8000h */
> STACK_START: .word 0x40008000

If your processor has less SRAM, then you'd better
make sure your stack pointer is located appropriately.

Here I've stuck it at the end of memory. You'd want
to make sure you did the same.

Cheers,
Dave
> Sorry Jean-Jacques, I probably overstated the case for getting the RAM
> initialization to work.

I'm not sure you did. Not only are user variables candidates for
initialization, perhaps some of the library functions also depend on
it. If programmers initialized everything then we wouldn't need to
clear .bss either. I don't think that's going to happen either.

I think C absolutely depends on having .bss cleared at startup.

Using objdump as I posted this morning to create a .lss file will show
precisely what values are assigned to those symbols. It might also be
worth looking at the location of the stack.

Richard