View unanswered posts | View active topics It is currently Thu Nov 27, 2014 5:01 pm






Reply to topic  [ 7 posts ] 
programming the nxt ARM7 µC by a MT-capable C++ compiler? 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 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

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sat Aug 30, 2008 2:03 pm, edited 1 time in total.



Tue Aug 19, 2008 4:25 pm
Profile
Rookie

Joined: Wed Jun 25, 2008 6:07 pm
Posts: 46
Post 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)


Fri Aug 29, 2008 4:44 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3293
Location: Rotterdam, The Netherlands
Post 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

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Fri Aug 29, 2008 5:14 pm
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 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;
        };
      };
    };


_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Mon Sep 01, 2008 11:58 am, edited 2 times in total.



Fri Aug 29, 2008 5:32 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 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...



_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Mon Sep 01, 2008 2:22 am
Profile
Rookie

Joined: Sat Apr 19, 2008 11:51 am
Posts: 43
Post 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!


Mon Sep 01, 2008 4:45 am
Profile
Expert
User avatar

Joined: Fri Nov 09, 2007 4:51 am
Posts: 121
Location: Hungary, Europe
Post 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 :-)


Tue Sep 02, 2008 10:49 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 7 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.