ROBOTC.net forums
http://www.robotc.net/forums/

programming the nxt ARM7 µC by a MT-capable C++ compiler?
http://www.robotc.net/forums/viewtopic.php?f=14&t=690
Page 1 of 1

Author:  Ford Prefect [ Tue Aug 19, 2008 4:25 pm ]
Post subject:  programming the nxt ARM7 µC by a MT-capable C++ compiler?

I wonder if this could be possible:
a real ANSI 2003 C++ compiler which has multitasking capability, produces executable ARM7 machine code for the nxt (not an interpreter!), and has a stack and a heap?



By this you'd be able to break through the Lego firmware limitations (cause there won't be any firmware except a BIOS), you might expand memory and have a stack/heap memory architecture...

Image

Author:  AvidProgrammer [ Fri Aug 29, 2008 4:44 pm ]
Post subject:  Re: programming the nxt ARM µC by a MT-capable C++ compiler?

Have you taken a look at Lejos-OSEK?
http://lejos-osek.sourceforge.net/

Quote:
ANSI C/C++ programming environment by using GCC tool chain
(Application is executed natively on the ARM7 and nxtOSEK itself consumed totally just about 10Kbytes)

Author:  mightor [ Fri Aug 29, 2008 5:14 pm ]
Post subject:  Re: programming the nxt ARM µC by a MT-capable C++ compiler?

Ford,

Programming with Lejos-OSEK would require fairly intimate knowledge of interrupt handling and other low level programming tricks. I don't think that is your cup of tea, judging from previous conversations :)

Regards,
Xander

Author:  Ford Prefect [ Fri Aug 29, 2008 5:32 pm ]
Post subject:  Re: programming the nxt ARM µC by a MT-capable C++ compiler?

hi, thx for your post!

I read sth about this some weeks ago as I was looking for some segway programs.
But my English actually is not good enough, and so I still don't understand the software architecture, and also other things I didn't understand quite right.
[EDIT:] actually - this really seems to be a C compiler ...

Quote:
nxtOSEK uses LEJOS NXJ low level device driver written in C/Assembly, but it is NOT another Java VM implementation for NXT. nxtOSEK is an RTOS(Real-Time Operating System) for LEGO MINDSTORMS NXT and user can write native application in ANSI C/C++ by using GCC tools.


But more important than this is:
how big is the variable memory? (very important! 15k are much too poor!)
how big are stack and heap? (heap: very important for dynamic memory allocation!)
(indeed it got a stack: STACKSIZE = 512; /* Stack size */ used in a task control; but what is maximum variable stack?
are fully recursive functions possible? (very important if different functions call each other)
may the memory be extended by external memory, e.g. SD cards via I²C (maybe even RS485)? (very important e.g. maps for navigation, a-star...)
and to the current dicussion: has it got a RS485 network protocol? (very important for RS485 Smux/Mmux remote access and co-calculation)
(MT is featured as I found)

Those related imperfections are the reason why I'm looking for a "real C" compiler w/o any Lego firmware limitations.
About this I still haven't found all the answers - could you plz help me with this?

EDIT: aah: Mightor was again faster than me... :?

PS:
the syntax appears to be not so very strange:
Code:
    /* nxtgt.c */
    #include "kernel.h"
    #include "kernel_id.h"
    #include "ecrobot_interface.h"

    /* OSEK declarations */
    DeclareCounter(SysTimerCnt);
    DeclareTask(TaskInitialize);
    DeclareTask(TaskControl);
    DeclareTask(TaskSonar);
    DeclareTask(TaskLCD);

    /* Definitions */
    #define MOTOR_STEERING     NXT_PORT_A
    #define MOTOR_LEFT         NXT_PORT_B
    #define MOTOR_RIGHT        NXT_PORT_C
    #define STEERING_LIMIT             40 /* degree */
    #define STEERING_P_GAIN             2 /* proportinal gain */
    #define DIFF_GAIN_MAX            0.7F /* 1.0-DIFF_GAIN_MAX: max. differential effect */
    #define NEUTRAL_DEAD_ZONE           2 /* degree */
    #define PWM_OFFSET                 10 /* friction compensator */
    #define EDC_ON                     -1 /* Electronic Differential Control: ON */
    #define EDC_OFF                     1 /* Electronic Differential Control: OFF */

    static S8 EDC_flag;                   /* EDC flag */

    /* Prototypes */
    S32 FrictionComp(S32 ratio, S32 offset);

    /* nxtOSEK hooks */
    void ecrobot_device_initialize(void)
    {
      ecrobot_set_light_sensor_active(NXT_PORT_S1);
      ecrobot_set_light_sensor_active(NXT_PORT_S3);
      ecrobot_init_sonar_sensor(NXT_PORT_S2);
      ecrobot_init_bt_connection();
    }

    void ecrobot_device_terminate(void)
    {
      nxt_motor_set_speed(MOTOR_STEERING, 0, 1);
      nxt_motor_set_speed(MOTOR_RIGHT, 0, 1);
      nxt_motor_set_speed(MOTOR_LEFT, 0, 1);
      ecrobot_set_light_sensor_inactive(NXT_PORT_S1);
      ecrobot_set_light_sensor_inactive(NXT_PORT_S3);
      ecrobot_term_sonar_sensor(NXT_PORT_S2);
      ecrobot_term_bt_connection();
    }

    void user_1ms_isr_type2(void)
    {
      StatusType ercd;

      ercd = SignalCounter(SysTimerCnt); /* Increment OSEK Alarm Counter */
      if (ercd != E_OK)
      {
        ShutdownOS(ercd);
      }
    }

    /* TaskInitialize */
    TASK(TaskInitialize)
    {
      nxt_motor_set_speed(MOTOR_STEERING, 0, 1);
      nxt_motor_set_speed(MOTOR_RIGHT, 0, 1);
      nxt_motor_set_speed(MOTOR_LEFT, 0, 1);
      nxt_motor_set_count(MOTOR_STEERING, 0);
      nxt_motor_set_count(MOTOR_RIGHT, 0);
      nxt_motor_set_count(MOTOR_LEFT, 0);

      EDC_flag = EDC_OFF;

      TerminateTask();
    }

    /* TaskControl executed every 10msec */
    TASK(TaskControl)
    {
      S32 analog_stick_left;  /* speed command data from GamePad */
      S32 analog_stick_right; /* steering command data from GamePad */
      S32 steering_angle;
      S32 steering_err;
      S32 steering_speed;
      S32 diff_gain;
      U8 touch_sensor;
      static U8 touch_sensor_state = 0;
      static U8 bt_receive_buf[32]; /* buffer size is fixed as 32 */

      /* receive NXTGamePad command
       * byte0 speed_data -100(forward max.) to 100(backward max.)
       * byte1 steering_data -100(left max.) to 100(right max.)
       */
      ecrobot_read_bt_packet(bt_receive_buf, 32);
      analog_stick_left = -(S32)(*(S8 *)(&bt_receive_buf[0])); /* reverse the direction */
      analog_stick_right = (S32)(*(S8 *)(&bt_receive_buf[1]));

      /* read Touch Sensor to switch Electronic Differential Control */
      touch_sensor = ecrobot_get_touch_sensor(NXT_PORT_S4);
      if (touch_sensor == 1 && touch_sensor_state == 0)
      {
        EDC_flag = ~EDC_flag + 1; /* toggle */
      }
      touch_sensor_state = touch_sensor;

      /* steering control */
      steering_angle = nxt_motor_get_count(MOTOR_STEERING);
      steering_err = (STEERING_LIMIT*analog_stick_right)/100 - steering_angle;
      steering_speed = STEERING_P_GAIN*steering_err;
      nxt_motor_set_speed(MOTOR_STEERING, FrictionComp(steering_speed,PWM_OFFSET), 1);

      /* wheel motors control with Electric Differential Control */
      diff_gain = 10;
      if (steering_angle > NEUTRAL_DEAD_ZONE) /* turn right */
      {
        if (EDC_flag == EDC_ON)
        {
          diff_gain = (S32)((1.0F - (float)steering_angle*DIFF_GAIN_MAX/STEERING_LIMIT)*10);
        }
        nxt_motor_set_speed(MOTOR_RIGHT,
          FrictionComp((analog_stick_left*diff_gain)/10,PWM_OFFSET), 1);
        nxt_motor_set_speed(MOTOR_LEFT, FrictionComp(analog_stick_left,PWM_OFFSET), 1);
      }
      else if (steering_angle < -NEUTRAL_DEAD_ZONE) /* turn left */
      {
        if (EDC_flag == EDC_ON)
        {
          diff_gain = (S32)((1.0F + (float)steering_angle*DIFF_GAIN_MAX/STEERING_LIMIT)*10);
        }
        nxt_motor_set_speed(MOTOR_RIGHT, FrictionComp(analog_stick_left,PWM_OFFSET), 1);
        nxt_motor_set_speed(MOTOR_LEFT,
          FrictionComp((analog_stick_left*diff_gain)/10,PWM_OFFSET), 1);
      }
      else /* go straight */
      {
        nxt_motor_set_speed(MOTOR_RIGHT, FrictionComp(analog_stick_left,PWM_OFFSET), 1);
        nxt_motor_set_speed(MOTOR_LEFT, FrictionComp(analog_stick_left,PWM_OFFSET), 1);
      }

      /* send NXT status data to NXT GamePad */
      ecrobot_bt_data_logger((S8)analog_stick_left, (S8)analog_stick_right);

      TerminateTask();
    }

    /* TaskSonar executed every 50msec */
    TASK(TaskSonar)
    {
      S32 sonar;

      /* Sonar Sensor is invoked just for data logging */
      sonar = ecrobot_get_sonar_sensor(NXT_PORT_S2);

      TerminateTask();
    }

    /* TaskLCD executed every 500msec */
    TASK(TaskLCD)
    {
      ecrobot_status_monitor("NXT GT");

      TerminateTask();
    }

    /* Sub functions */
    S32 FrictionComp(S32 ratio, S32 offset)
    {
      if (ratio > 0)
      {
        return ((100-offset)*ratio/100 + offset);
      }
      else if (ratio < 0)
      {
        return ((100-offset)*ratio/100 - offset);
      }
      else
      {
        return ratio;
      }
    }

the task control seemes fine:
samples\nxtgt\nxtgt.oil
Code:
    #include "implementation.oil"

    CPU ATMEL_AT91SAM7S256
    {
      OS LEJOS_OSEK
      {
        STATUS = EXTENDED;
        STARTUPHOOK = FALSE;
        ERRORHOOK = FALSE;
        SHUTDOWNHOOK = FALSE;
        PRETASKHOOK = FALSE;
        POSTTASKHOOK = FALSE;
        USEGETSERVICEID = FALSE;
        USEPARAMETERACCESS = FALSE;
        USERESSCHEDULER = FALSE;
      };

      /* Definition of application mode */
      APPMODE appmode1{};

      /* Definition of TaskInitialize */
      TASK TaskInitialize
      {
        AUTOSTART = TRUE
        {
          APPMODE = appmode1;
        };
        PRIORITY = 4;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512; /* Stack size */
      };

      /* Definition of TaskControl */
      TASK TaskControl
      {
        AUTOSTART = FALSE;
        PRIORITY = 3;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512; /* Stack size */
      };

      /* Definition of TaskSonar */
      TASK TaskSonar
      {
        AUTOSTART = FALSE;
        PRIORITY = 2;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512; /* Stack size */
      };

      /* Definition of TaskLCD */
      TASK TaskLCD
      {
        AUTOSTART = FALSE;
        PRIORITY = 1;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512; /* Stack size */
      };

      /* Definition of OSEK Alarm Counter */
      COUNTER SysTimerCnt
      {
        MINCYCLE = 1;
        MAXALLOWEDVALUE = 10000;
        TICKSPERBASE = 1; /* One tick is equal to 1msec */
      };

      /* Definition of TaskControl execution timing */
      ALARM cyclic_alarm_TaskControl
      {
        COUNTER = SysTimerCnt;
        ACTION = ACTIVATETASK
        {
          TASK = TaskControl;
        };
        AUTOSTART = TRUE
        {
          ALARMTIME = 1;
          CYCLETIME = 10; /* executed every 10msec */
          APPMODE = appmode1;
        };
      };

      /* Definition of TaskSonar execution timing */
      ALARM cyclic_alarm_TaskSonar
      {
        COUNTER = SysTimerCnt;
        ACTION = ACTIVATETASK
        {
          TASK = TaskSonar;
        };
        AUTOSTART = TRUE
        {
          ALARMTIME = 1;
          CYCLETIME = 50; /* executed every 50msec */
          APPMODE = appmode1;
        };
      };

      /* Definition of TaskLCD execution timing */
      ALARM cyclic_alarm_TaskLCD
      {
        COUNTER = SysTimerCnt;
        ACTION = ACTIVATETASK
        {
          TASK = TaskLCD;
        };
        AUTOSTART = TRUE
        {
          ALARMTIME = 1;
          CYCLETIME = 500; /* executed every 500msec */
          APPMODE = appmode1;
        };
      };
    };


Author:  Ford Prefect [ Mon Sep 01, 2008 2:22 am ]
Post subject:  Re: programming the nxt ARM7 µC by a MT-capable C++ compiler?

hi,
I just got some answers to my questions from the nxtOSEK developer:
Takashi Chikamasa <takashic@cybernet.co.jp> wrote:
Hi,

Thank you for your questions.
I am trying to answer your questions with my best effort:

> how big is the variable memory / stack? (very important! 15k of RobotC are
> much to poor!)
nxtOSEK provides two ways of program execution.
1. In case of using enhanced NXT standard firmware
In this case, user available memory/stack is max. 64Kbytes.
All user program (includes ROM/RAM memory) has to be less than 64Kbytes.
If enhanced NXT stadard firmware was used for program download, user
program has be executed from SRAM in the NXT.
2. In case of using NXT BIOS
In this case, user available memory/stack is as follows
ROM: max. 224Kbytes
RAM: max. 50Kbytes
NXT BIOS is a simple program bootloader, so user can use all most full
memory space of ARM7 in the NXT.


> what is maximum variable heap? (very important for dynamic memory
> allocation!)
I haven't tested dynamic memory allocation features provided by GCC, but
it should be OK up to the above resrictions.


> are fully recursive functions possible? (very important if different
> functions call each other)
No problem. GCC is a real C/C++ compiler and it has been used for
millions of complex software (e.g. Linux) in the computer industory.
GCC for NXT(ARM7) is essentially same as GCC which is used for Linux.
I believer that you can write your program in C as you like.


> may the memory be extended by external memory, e.g. SD cards via I2C (or by
> RS485)?
> (very important e.g. maps for navigation, a-star...)
> has it got a RS485 full or half duplex network protocol? (very important to
> control "slave nxt's" by RS485 as sort of Smux/Mmux remote
> access to and co-calculation maybe for navigation calculations or a neural
> net runnung on 2-4 connected nxt's)
Currently, nxtOSEK does not support RS-485 comm. and I haven't
investigated it. Sorry.


> how does I2C communication work for third party (e.g., POB-eye cam) or
> homebrewed motor and sensor multiplexers?
Yes. nxtOSEK supports various types of third party I2C sensors. (e.g.
HiTechnic Accel, LATTEBOX NXTe...) and I2C API is also published.


> multitasking is elementary (but as I understood, it's actually featured by nxtOSEK)?
Yes. nxtOSEK provides preemptive multitasking features. This is one of the
most valuable features for real-time control.
This OSEK technology is come from from Europian automotive industory
such as BMW, Mercedes, Siemens, Bosch...



Author:  spaceballs [ Mon Sep 01, 2008 4:45 am ]
Post subject:  Re: programming the nxt ARM7 µC by a MT-capable C++ compiler?

hi Ford,
thx for your post!
I even sent your question to the forums, but they don't seem to be very high frequented :(
but most of your questions heve been answered, and this
Quote:
In this case, user available memory/stack is as follows
ROM: max. 224Kbytes
RAM: max. 50Kbytes

is really amazing!

Author:  elemes [ Tue Sep 02, 2008 10:49 pm ]
Post subject:  Re: programming the nxt ARM7 µC by a MT-capable C++ compiler?

Yeah, I suppose I will exploit Ford's findings sooner or later, however, at my stage of development I prefer the environment of RobotC. The resulting code can be ported to the "final" environment easily. I hope :-)

Thus, I must say thank you, Ford -- pioneers move the world :-)

Page 1 of 1 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/