zu a)

ja, task_PID_[ABC] wird durch die allgemeine form pid_calc ersetzt.

Sinngemäss wie du auf die Elemente des Arrays zugreifst sähe so aus (ohne das ich jetzt verstehe was dein Algo macht):
Code:
void *pid_calc(void *arg) {
  float aspeed, damp, PWMpwr, readold, errorold, tprop;
  long  readstart, cmax, cmin;                         // for monitoring
  long  starttime, runtime, clock, dtime;              // timer
  char  regloop;
  
  // arg nach index casten
  unsigned port = (unsigned)arg;

  motor[port].runstate = 0x10;                               // reg state: RAMPUP
  motor[port].read     = (MotorRotationCount(port));        // get current encoder reading
  motor[port].err      = motor[port].target - motor[port].read;          // error to target

  readstart      = motor[port].read;
  regloop        = 1;

  damp=0;                                 // damp the integral memory

  starttime= CurrentTick();


  // appoach target
  _Astart:
  motor[port].runstate = 0x10;                  // run state: RUNNING

  do {
    pthread_testcancel();

    dtime    = CurrentTick() - clock;
    clock    = CurrentTick();
    runtime  = clock - starttime;
    tprop    = dtime/20.0;

    if ((motor[port].err==errorold)&& (abs(motor[port].err)>motor[port].precis))
      damp=1; // stalling
    else
      damp=motor[port].damp;

    motor[port].integr = (damp * motor[port].integr) + motor[port].err;

    if((motor[port].integr) > 3*motor[port].maxout) 
      motor[port].integr = 3*motor[port].maxout; // cut away
    else if((motor[port].integr) <-3*motor[port].maxout)
      motor[port].integr =-3*motor[port].maxout;

    PWMpwr= (motor[port].P*motor[port].err) + (motor[port].I*motor[port].integr)*tprop + (motor[port].D*(motor[port].err-errorold))/tprop;


    if(PWMpwr >  motor[port].maxout)
      PWMpwr=  motor[port].maxout;   // forward maxout
    else if(PWMpwr < -motor[port].maxout)
      PWMpwr= -motor[port].maxout;   // reverse maxout

    motor[port].speed= (motor[port].read-readold)*100/dtime;  // rotat speed [degrees/100ms]

    aspeed = abs(motor[port].speed) ;

    if (aspeed > motor[port].tarpwm)  {
        PWMpwr = sign(PWMpwr)*motor[port].tarpwm;
    }

    motor[port].outp = round(PWMpwr);

     //**************************************************************************
                                                   // PID regulation !
    OnFwd(port, (motor[port].outp));                         // action !
    Wait(motor[port].regtime);                                // wait regulation time

    //**************************************************************************

    readold     = motor[port].read;                           // save old sensor
    errorold    = motor[port].err;                            // save old error

    motor[port].read  = (MotorRotationCount(port));          // get new encoder value
    motor[port].err   = motor[port].target-motor[port].read;              // new error to target

    if (motor[port].read>cmax) 
      cmax=motor[port].read;               // monitor overshooting
    else if (motor[port].read<cmin)
      cmin=motor[port].read;               // monitor overshooting

    if ((motor[port].cont)&& (abs(motor[port].err)<=motor[port].precis))
      motor[port].runstate = 0x60;
    else 
      motor[port].runstate = 0x20;

    if (motor[port].cont) 
      continue;
    if (abs(motor[port].err)<=motor[port].precis) {
      regloop +=1 ; 
      motor[port].runstate = 0x40;
    }

  } while ((abs(motor[port].err)>=motor[port].precis) && (regloop<=5));  // target reached

  Off(port);                                      // finished - brake motor
  motor[port].runstate = 0x40;                           // run state: RAMPDOWN
  motor[port].outp=0;

  Wait(50);
  motor[port].read = MotorRotationCount(port);
  regloop=1;

  if (motor[port].read>cmax) cmax=motor[port].read;            // detect overshooting
  if (motor[port].read<cmin) cmin=motor[port].read;            // detect overshooting
  motor[port].err = motor[port].target-motor[port].read;

  if ((abs(motor[port].err)>motor[port].precis)) {
    goto _Astart;
  }

  motor[port].runstate=0;
  Wait(1);                                //runstate = IDLE

}
zu b)

klar geht das, in deinem Beispiel legst du einfach fünf Threads an, die vom OS ausgeführt werden.
Was du nicht machen darfst ist zweimal ein RotatePID mit der identischen Portnummer aufzurufen ohne vorher ein StopPIDcontrol aufzurufen. Würdest du das machen hättest du zwei Threads die dann doch wieder auf einem PID rumrechnen.
Ausserdem würde ich statt Nummern für die Ports eine enum erstellen, Namen sind einfacher zu lesen, als mit 0,4,7 einen Motor zu assoziieren.