Author Topic: porting uTasker to the winarmgcc  (Read 25520 times)

Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
porting uTasker to the winarmgcc
« on: July 18, 2007, 05:16:34 AM »
Hi

I have olimex board sam7x, i have tested it with uTasker compiled with IAR,  Marker sent to me bin file so it work very well.

I want use WinARM, i have made good code with it, USB CDC and USART, so i want use uTasker in my devices.

I want porting uTasker to compile with winarm, i have utasker makefile, but i had problem with libarm_enable_irq() and libarm_disable_irq() in sam7x.c file, functions from Rowley, i have used:

extern void __irq_en(void);  // enable interrupt in assembler code
 extern void __irq_dis(void);  // disable interrupt in assembler code


This form:

void libarm_disable_irq()
{
   __irq_dis();
}

void libarm_enable_irq()
{
  __irq_en();
 }


This modification don`t create compilation erros, but uTasker don`t work in board, i am trying debugger with openocd and insight GDB.

I had contacted winarm developer Martin Thomas, i ask him if winarm has lib that can fix this problem so he replied me:
         
         "Please browse the examples that come with WinARM for files called
          armVIC.h/.c (even if you find them in LPC2000 examples they can be used
          for the AT91SAM7 too). The functions enableIRQ and disableIRQ offer the
          needed functionality."


I use this files and functions inside, but i got another error in end of make compilation:

arm-elf-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I..\..\uTaskerV1.3 -D _GNU -D _HW_SAM7X -g -c -Os ..\winarm_irq\armVIC.c  -o Build\armVIC.o
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s: Assembler messages:
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:25: Error: selected processor does not support `mrs r1,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:39: Error: selected processor does not support `msr cpsr,r3'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:62: Error: selected processor does not support `mrs r1,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:76: Error: selected processor does not support `msr cpsr,r3'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:98: Error: selected processor does not support `mrs r0,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:108: Error: selected processor does not support `msr cpsr,r3'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:130: Error: selected processor does not support `mrs r0,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:141: Error: selected processor does not support `msr cpsr,r2'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:163: Error: selected processor does not support `mrs r0,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:173: Error: selected processor does not support `msr cpsr,r3'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:195: Error: selected processor does not support `mrs r0,cpsr'
C:\DOCUME~1\Emerson\LOCALS~1\Temp/ccYbbaaa.s:206: Error: selected processor does not support `msr cpsr,r2'
make.exe: *** [Build\uTasker.o] Error 1
[/color]

well, if somebody has experience in porting or how i can  fix the problem, please tell me.

I have makefile to winarm and uTasker bin to IAR, i have to openocd.cfg file and how load insight and openocd by programmenotepad, i can send by email just request me.

Thanks

Emerson M A Alves
Brazil
emerson@saaepirapora.com.br
« Last Edit: July 18, 2007, 05:36:17 AM by tecnoemerson »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #1 on: July 18, 2007, 08:06:30 AM »
Hi Emerson

Try compiling this file from WinArm without the -mthumb flag. I have a feeling that the assembler instructions which are throwing errors are ARM mode instructions and so will not assemble in Thumb mode. Since the project is using -mthumb-interwork it is possible to mix ARM and Thumb compiled programs - the compiler sorts out the mode switching.

Good luck

Mark

Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #2 on: July 18, 2007, 02:13:34 PM »
Yeah! Mark


I removed -mthum flag, so  fix the assembly error, but bin file don`t work in olimex board, but usb now is stable, before usb was in reset loop, maybe watchdog. The size of the file is 75kb was 52.

Thanks

Emerson
« Last Edit: July 18, 2007, 02:16:16 PM by tecnoemerson »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #3 on: July 18, 2007, 04:15:08 PM »
Emerson

Only remove the thumb flag in the single winARM C-file.
This should only increase the complete code by a very small amount. The present increase is surprisingly large and doesn't sound right.

With the debugger try to work your way through the following porting list. It is probably not complete but it will serve as a starting point to see at about which point the code is failing.

1. The start up code must set up the memory correctly. The link file that I sent should be used as a reference and the start up code must also use the defines there for setting up the various stack pointers.

2. The start up code must initialise PLL, default interrupt handlers and variables – it is best to call AT91F_LowLevelInit() in sam7x.c

3. Then the code must jump to main() in SAM7x.c

4. It has to be checked that the heap initialisation is correct. __heap_end__ is used as start address for the heap (__heap_end__ is taken from the linker script file)

5. The uTasker tasks will then be configured and the timer interrupt (TICK) configured. The interrupts will also be enabled.

6. The interrupt TICK will be called if the low level interrupt handler is working correctly.

Note that I have created a file called startup_gnu.s which is use as a start up file in the project and it contains all that is needed. It is also compatible with the linker script file. Verify that you are using this rather than one supplied with the GNU compiler. Then try to step through the code to see what is working correctly and where it goes wrong.

Once the TICK is operating correctly, the watchdog will be retriggered every 200ms and an output or LED will be blinking (see which one is defined in app_hw_sam7X.h and modify to suit the board in question if needed).
As long as it gets this far the basis is ready and any additional problems will be very specific (compiler specialities like packing, but this should be solved for GCC).

Good luck

Regards

Mark

Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #4 on: July 18, 2007, 07:52:26 PM »
Mark

I have dedicated a lot in porting uTasker.

Ok, i removed -mthumb flag just  armVIC.o file from winarm, the  file size is smaller than previous, almost 55kb, so now i am trying debug it,  i use openocd and insight, so i have some questions:

Can i use simulator to test code?

What is fisrt file after reset sam7x?  is sam7x.c and function AT91_LowLevel_init?

Thank you again.


Emerson M A Alves
Brazil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #5 on: July 18, 2007, 09:03:57 PM »
Hi Emerson

No the simulator can not be used when porting to a different compiler environment. The simulator assumes that the code starts up correctly and the TICK is operating - it can neither check the start up assembler, the way the compiler cross compiles (and any possible errors it makes) nor the memory map on the target.

Therefore the only real tool is the debugger. I haven't used the tools which you are using so can't make any suggestions there. But this is the way that I expect the code to start. If you step through it you can hopefully also see the source during this phase. Either you can use the WinArm start up or try with the "startup_gnu.s" which should be in your hardware directory (in this case you must inform the linker not to use the libray start up files using "-nostartfiles").

Usually the first step after a reset is to set the stack pointers. There are various stack pointers (undefined, abort, IRQ, FIQ, supervisor and system). The following shows setting up one of these in assember:

Code: [Select]
    mrs r0, cpsr                                                         /* Read the status register */
    bic r0, r0, #0x1f                                                    /* Mask out the mode bits */
    orr r1, r0, #0x1b                                                    /* prepare undefined mode */
    msr     cpsr_cxsf, r1                                                /* set mode */
    ldr     sp, = __stack_und_end__                                      /* set undefined stack pointer */

__stack_und_end__ is defined in the linker script file.
See the linker script uTaskerV1.3_FLASH.ld in \Applications\uTaskerV1.3\GNU_SAM7X. Also don't forget that the actually used linker script depends on whether the code will be loaded to FLASH or to RAM (debug version).

In my start up I then call AT91F_LowLevelInit()

Code: [Select]
    ldr     r0,= AT91F_LowLevelInit                                      /* call C code to initialise variables */
    mov     lr, pc
    bx     r0

This contains code to set up interrupts, the speed of the PLL, FLASH wait states and other details, and to copy bss (variables with zero value at initialisation) and initialised variables (a copy from initial values from FLASH to RAM) plus text (if not defined to stay in FLASH).

This is for example how the variables are initialised:

Code: [Select]
    unsigned char *ptrData = &__data_start__;
    const unsigned char *ptrFlash = &__data_load_start__;
    unsigned long ulInitDataLength = (&__data_end__ - &__data_start__);
    while (ulInitDataLength--) {                                         // initialise data
        *ptrData++ = *ptrFlash++;
    }

This requires also that the sections are declared correctly in the linker script file. Since you have no linker errors they seem all to be available.


After returning from this low level initialisation routine the code simply jumps to main() in sam7x.

Code: [Select]
    ldr r0,=main                                                         /* jump to main */
    bx r0


If you get to main, take a look at the stack pointer set up. You should be in System/supervisor mode. The stack pointer should be almost at the top of SRAM (around 0x0020FF00 for SAM7X256 - check that you don't have a smaller chip since this needs the RAM setting in the linker script to be set to 0x00008000 instead!!).

The code should call fnInitHW() and fnUserHWInit(). These should not be able to fail.

The next important call is fnInitialiseHeap(ctOurHeap, HEAP_START_ADDRESS);
This dynamically defines the heap to be used by uMalloc. This is possitioned from the last variable space in RAM and has the size OUR_HEAP_SIZE as defined in config.h. All remoaining SRAM will beb filled with a pattern (default is 0x55).
For thsi to work correctly the top of variables in RAM - supplied by the linker - must be known and correct.
I use     #define HEAP_START_ADDRESS &__heap_end__. If your compiler supplies something else you can put it here but again it seems as though all is available as you can link.

After the heap has been set up, you can check that the variables pucTopOfHeap and pucBottomOfHeap make sense and that the free memory has the expected pattern.

Here is a quick memory map of what is to be expected in RAM.

TOP (0x20ffff) (some stacks may be zero in size)
- Undefine stack
- Abort stack
- IRQ stack
- FIQ stack
- Supervisor stack <-- present stack pointer
...0x55 0x55 0x55...
...
Top of heap (pucTopOfHeap)
..heap memory of size OUR_HEAP_SIZE
Bottom of heap (pucBottomOfHeap )
initialised variables
(possibly initialised text)
bss (zero initialised variables)
BOTTOM (0x200000)

Once you are sure all is correct to here the next step is to verify that the interrupt handling is correct (interrupts enabled, handling correct, ...). After which not a lot more can go wrong.


However it is best to ensure that the memory is all correct before starting with the IRQ verification.


It is unfortunately true that setting up a compiler (even a different GCC version) can cause some heart-ache. Although we write using ANSI C which will enable portability between compiler and processors there is nothing which defines the compiler start up rules. Each time it is an adventure which can either work quickly or can eat up lots of work or free time. Nothing replaces deep understanding of the chips needs, the memory map and the interrupt operation.
I hope that you can make some progress soon and start with your real work.

Good luck

Regards

Mark



Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #6 on: July 20, 2007, 05:43:42 AM »
Mark

After i had studied a lot about debugger, i use Eclipse + openOCD + arm-elf-gdb to debug software in olimex board.

I tested it with simple software that blink led, all righ, it worked very well.

So i tested utasker, the sequence in debug is:

file SAM7X.c

ptrSeed = &usRandomSeed;                        // 1  step in
 if (!WATCHDOG_DISABLE()) {                      // 2 step in
        WDT_MR = CONFIGURE_WATCHDOG;      // 3 step in                                   
           }

    fnUserHWInit();                             //4 step in call the function

When call function jump all and go to end of the function

extern void fnUserHWInit(void)
{
#ifdef LAN_REPORT_ACTIVITY
    CONFIGURE_LAN_LEDS();                                                // configure and drive ports
#endif

#ifdef SUPPORT_KEY_SCAN
    #if defined (STR912_SK)                                              // Since the port configuration on the STR91XF is a little complicated we do it in code here
        // Configure the keypad ports
        // Inputs - enable clock and disable port reset
        SCU_PCGR1 |= GPIO6;
        SCU_PRR1  |= GPIO6;

        // Outputs - enable clock and disable port reset (these are also inputs when not driving)
        SCU_PCGR1 |= GPIO5;
        SCU_PRR1  |= GPIO5;

        SCU_GPIOOUT6 &= ~((MASK_FUNCTION << (2*4)) | (MASK_FUNCTION << (2*5)) | (MASK_FUNCTION << (2*6)) | (MASK_FUNCTION << (2*7)));  // mask peripheral function select
        SCU_GPIOIN6  &= ~(KEY_ROW_IN_1 | KEY_ROW_IN_2 | KEY_ROW_IN_3 | KEY_ROW_IN_4);          // ensure input not connected to a peripheral
        GPIO_DIR_6   &= ~(KEY_ROW_IN_1 | KEY_ROW_IN_2 | KEY_ROW_IN_3 | KEY_ROW_IN_4);          // ensure inputs

        SCU_GPIOOUT5 &= ~((MASK_FUNCTION << (2*4)) | (MASK_FUNCTION << (2*5)) | (MASK_FUNCTION << (2*6)) | (MASK_FUNCTION << (2*7)));  // mask peripheral function select
        SCU_GPIOIN5  &= ~(KEY_COL_OUT_1 | KEY_COL_OUT_2 | KEY_COL_OUT_3 | KEY_COL_OUT_4);      // ensure input not connected to a peripheral
        GPIO_DIR_5   |=  (KEY_COL_OUT_1 | KEY_COL_OUT_2 | KEY_COL_OUT_3 | KEY_COL_OUT_4);      // prepare outputs
        GPIO_DATA_5  &= ~(KEY_COL_OUT_1 | KEY_COL_OUT_2 | KEY_COL_OUT_3 | KEY_COL_OUT_4);      // prepare outputs low
    #else
        INIT_KEY_SCAN();                                                 // General initialisation for key scamn
    #endif
#endif
}
  come here debugger  // 5 step in

  prtInfo = ptMultiStartTable;            //6  step in
   if (prtInfo == 0) {                 // 7 step in
    if (prtInfo->new_hw_init) {    //8 step in

so debugger crash, i am not sure if is problem with arm-elf-gdb or if really is problem in uTasker file compiled.

Do you have idea about it? I will continue trying debug it!!!    I have assembly sequency code too.

Thank you again!


Emerson
Brazil
« Last Edit: July 20, 2007, 05:46:04 AM by tecnoemerson »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #7 on: July 20, 2007, 10:36:49 AM »
Hi Emerson

Checking the code the following is not a sequence of lines in the file but the order that the lines of code are executed when stepping with the debugger.
prtInfo = ptMultiStartTable;            //6  step in
   if (prtInfo == 0) {                 // 7 step in
    if (prtInfo->new_hw_init) {    //8 step in


This means that ptMultiStartTable is NOT equal to 0 since it is trying to access a memeber of the structure pointed to by it - causing an abort.

Now I think that ptMultiStartTable is in fact the first variable being used and it is 0 in the demo project (if nothing has been changed).

This suggests to me that your variables are not being correctly initialised.
Check the location of ptMultiStartTable in the map file (it should be in the BSS section) and try to find out why its value has not been set to 0. You can also do the same test with an initialised variable to ensure that it is correctly initialised to the expected value.
All initialisation should have been completed by the time that the code above is executed but I think that you will find that this is not the case. This must be solved to be able to run code from this point.

Good luck!!

Mark


Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #8 on: July 20, 2007, 03:48:16 PM »
MarK

look the map file:
               0x0020009c                __bss_start__ = .
 *(.bss .bss.* .gnu.linkonce.b.*)
 .bss           0x0020009c       0x14 Build\application.o
                0x002000a4                ucSMTP_server
                0x002000a0                temp_pars
                0x0020009c                parameters
 .bss           0x002000b0       0x3c Build\debug.o
                0x002000b0                usData_state
 .bss           0x002000ec       0x58 Build\webInterface.o
 .bss           0x00200144        0x0 Build\KeyScan.o
 .bss           0x00200144        0x0 Build\LCD.o
 .bss           0x00200144        0x0 Build\NetworkIndicator.o
 .bss           0x00200144        0x0 Build\startup_gnu.o
 .bss           0x00200144      0x6e4 Build\SAM7X.o
 .bss           0x00200828        0x0 Build\eth_drv.o
 .bss           0x00200828        0x8 Build\Driver.o
                0x00200828                que_ids
 .bss           0x00200830        0xc Build\uMalloc.o
 .bss           0x0020083c       0x14 Build\uTasker.o
                0x0020083c                ptMultiStartTable
                0x00200840                JumpTable
 .bss           0x00200850       0x10 Build\Tty_drv.o
 .bss           0x00200860        0x8 Build\uFile.o
 .bss           0x00200868        0x0 Build\watchdog.o
 .bss           0x00200868       0x30 Build\GlobalTimer.o
 .bss           0x00200898       0x4c Build\Ethernet.o
                0x00200898                Ethernet_handle

All right to ptMultiStartTable or was necessary .bss in front line.

I wil check the variable initialisation

Thank you

Emerson

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #9 on: July 20, 2007, 04:34:48 PM »
Emerson

This is OK.

Code: [Select]
.bss           0x00200830        0xc Build\uMalloc.o
 .bss           0x0020083c       0x14 Build\uTasker.o
                0x0020083c                ptMultiStartTable
                0x00200840                JumpTable

It is just showing where the bss section for uTasker.o begins and that it contains 2 global variables (ptMultiStartTable and JumpTable) with their addresses.

uMalloc in comparison does has zero initialised variables (probably 0x0c in total length) but they are not listed since they are declared static and so are private to the file (addresses are not available globally).

The map shows that the linker has done everything correctly. Assuming that these variables are not 0 it means that the initialisation code is not being called or it is making mistakes.

Regards

Mark


Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #10 on: July 22, 2007, 04:45:23 AM »
Mark

Really i didn't identify with variable  ptMultiStartTable don't initialise with 0 value, in debugger i can see value in  ptMultiStartTable, so i tried two ways:

1: force  ptMultiStartTable =0 in sam7x.c code and  to compile.
2:  force  ptMultiStartTable  manualy in debugger.


In two situations debugger go until in utasker.c file:

// This is normally called from within a forever loop in main()
//
#ifdef MULTISTART
    extern MULTISTART_TABLE *uTaskerSchedule( void )
#else
    extern void uTaskerSchedule( void )
#endif
{
    TTASKTABLE *ptTaskTable = tTaskTable;                                // set at start and work down till bottom
    while (ptTaskTable->pcTaskName) {                                    // for each task in the task table
        if (ptTaskTable->ucTaskState & (UTASKER_GO | UTASKER_ACTIVATE)) {// if the task is to be scheduled
            uDisable_Interrupt();                                        // protect from interrupts during this check
            if ((ptTaskTable->TaskRepetition) || (!(ptTaskTable->ucTaskState & UTASKER_GO))) {
                if (ptTaskTable->ucEvent != 0) {                         // if woken from timer delay set write event to queue if there is one
                    unsigned char timer_message[HEADER_LENGTH];          // timer event message space
                    timer_message[MSG_DESTINATION_NODE] = INTERNAL_ROUTE;// internal event
                    timer_message[MSG_SOURCE_NODE] = INTERNAL_ROUTE;
                    timer_message[MSG_DESTINATION_TASK] = *(ptTaskTable->pcTaskName); // event to this task[/color


So in red part above, the degugger crash when in step in.

Thank you.

Emerson
« Last Edit: July 22, 2007, 05:16:01 AM by tecnoemerson »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #11 on: July 22, 2007, 10:57:31 AM »
Hi Emerson

When you set the variable to zero you are 'correcting' the error in one place but then it will also have further problems afterwards. This does however seem to confirm the fact that the BSS variables are really not getting set to zero.

Therefore the only solution is to solve the problem there. Here is the code which performs the initialisation. Check that it is really being called, that the values are correct (check that the addresses which are taken from the linker script are from the correct linker script). The same is valid for the initialised variables since these may well  have the same problem.

1. In sam7x.c, the routine AT91F_LowLevelInit() is called from the start up assembler file.
2. __init_gnu_data(); is called to perform variable initialisation. Note that it is conditional on the define _GNU. Make sure that your make file is defining this (-D _GNU)
3. This code copies the variables. You need to study this and try to work out why it is not setting the values of all variables in the BSS section to 0 and possibly why it is not copying initialised variables from FLASH to RAM.

Code: [Select]
extern unsigned char __data_start__, __data_end__;
extern const unsigned char __data_load_start__;
extern unsigned char __text_start__, __text_end__;
extern const unsigned char __text_load_start__;
extern unsigned char __bss_start__, __bss_end__;

extern void __init_gnu_data(void)
{
    unsigned char *ptrData = &__data_start__;
    const unsigned char *ptrFlash = &__data_load_start__;
    unsigned long ulInitDataLength = (&__data_end__ - &__data_start__);
    while (ulInitDataLength--) {                                         // initialise data
        *ptrData++ = *ptrFlash++;
    }

    ptrData = &__text_start__;
    ptrFlash = &__text_load_start__;
    ulInitDataLength = (&__text_end__ - &__text_start__);
    while (ulInitDataLength--) {                                         // initialise text
        *ptrData++ = *ptrFlash++;
    }

    ptrData = &__bss_start__;
    ulInitDataLength = (&__bss_end__ - &__bss_start__);
    while (ulInitDataLength--) {                                         // initialise bss
        *ptrData++ = 0;
    }
}

Only once you have solved this will it be possible to continue.

Good luck

Regrads

Mark

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: porting uTasker to the winarmgcc
« Reply #12 on: August 09, 2007, 10:36:23 PM »
Hi Emerson

I have just installed the tool chain as described in James Lynch's latest "Using Open Source Tools for AT91SAM7S Cross Development revision C". I will create a new thread with more details to see whether we can get this working correctly with the uTasker project.

Regards

Mark

Offline tecnoemerson

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: porting uTasker to the winarmgcc
« Reply #13 on: August 14, 2007, 06:45:59 AM »
All Developers

Problem to porting uTasker to WINARM Solved!!!


I changed my tools to Yagaro and tool chain as described in James Lynch's latest "Using Open Source Tools for AT91SAM7S Cross Development revision C.

The tutorial use Yagarto + Eclipse use same GCC (gcc 4.1.1) of WINARM, but better than WINARM, more tools and detals!

I recommend all people that has sam7x to test the tutorial, it is step by step, very easy use it!

Excellents tools and Marker worked it, so go to topic: "Using Open Source Tools with SAM7X and uTasker project ".



Thanks

Emerson M A Alves
tecnoemerson@interpira.com.br
Brazil
« Last Edit: August 15, 2007, 05:32:00 AM by tecnoemerson »