Presentation is loading. Please wait.

Presentation is loading. Please wait.

User C Programs in Power PMAC December 2013

Similar presentations


Presentation on theme: "User C Programs in Power PMAC December 2013"— Presentation transcript:

1 User C Programs in Power PMAC December 2013

2 C vs. Script Programs Why write Power PMAC programs and routines in C?
Compiled C code runs much faster than interpreted Script code (10-20x) C is a powerful and flexible language Many programmers are already familiar with C Why not write Power PMAC programs and routines in C? Many engineers are not experienced in C C is a difficult language for non-programmers C requires explicit type matching of different variables C access to I/O registers is less straightforward than in Script C lacks automatic sequencing and pipelining of Script motion programs

3 Priorities for C Programs in Power PMAC
Capture/compare interrupt: Fast updating to/from PMAC3 IC Phase interrupt: “User-written phase” function Typically for specialized commutation and current-loop algorithms For non-commutation tasks, use extra motor Servo interrupt: “User-written servo” function Typically for specialized feedback and feedforward algorithms For non-servo tasks, use extra motor Real-time interrupt: “Real-time C PLC” function Equivalent of Turbo PMAC PLCC0 Each background scan: “Background C PLC” functions Called between each scan of one background Script PLC 32 separate programs (0 – 31), separately enabled General-purpose operating system: C programs (applications) Run as programs (not called functions) on standard computer Linux GPOS allocates CPU time (when free from interrupt tasks)

4 Creating C Routines and Programs
Power PMAC IDE provides tool set for implementing C routines Project manager to organize all C and Script software Smart text editor for writing software (or pasting in from other source) GNU C cross-compiler automatically invoked on project “build” In Project Manager’s “Solution Explorer”, expand “C language” branch For user-written servo and/or phase, expand “Realtime Routines”, then select “usrcode.c” for editing (multiple routines can be in this file) For RTI CPLC, expand “CPLCs” and “rticplc”, then select “rticplc.c” for editing For background CPLCs, click on “CPLCs” and select program number (nn = 0 to 31) in resulting window, creating “bgcplcnn” subfolder and “bgcplcnn.c” file for editing For background applications, expand “Background Programs”, and add your own files for editing To compile and download code, right-click on project name, then select “Build and Download All Programs”

5 IDE Support for C Programming

6 Accessing Shared Memory and Structures
All files with C code must start with “#include <gplib.h>” Header file provides access to shared-memory structures Access for both “real time” (interrupt-driven) and “general-purpose” (background) code Functions called by Power PMAC control code (user-written phase and servo, RTI and background CPLCs) automatically have access to several pre-defined pointers pshm: Pointer to SHM shared-memory data structure piom: Pointer to I/O memory space pushm: Pointer to user-defined buffer memory space Independent background programs must declare variables for these pointers Structure elements are basically the same as in the Script environment Case-sensitive names in C (not in Script) No write-protection in C (but no access to many “internal” elements) Only full-word elements in I/O structures

7 C User-Written Servo Routines
Each servo update period, every active motor calls its specified servo routine (built-in or user-written) as function Each motor can have its own routine Can provide own name(s) for user-written routine(s) Routine must return a “double” value for servo command output Must be in range of +/-32,768.0 Power PMAC will copy to output or use for commutation Routine must accept a “MotorData” pointer as argument Power PMAC will automatically pass pointer to present motor’s structure Permits same algorithm to be used unchanged for different motors Provides access to several useful automatically computed floating-point values DesPos: Net desired position (trajectory + master) ActPos: Net actual position (including corrections) PosError: Following error DesVel: Net desired velocity ActVel: Net actual velocity

8 C User-Written Servo Routines (cont.)
Declare in form: “double MyServoAlg(struct MotorData *Mptr)” IDE creates declaration automatically from user-entered routine name Use IDE Project Manager to tell which motor(s) use this routine In Solution Explorer, right-click on “Realtime Routines” under “C Language” Select “User Servo Setup” to get window to assign routines to motors Sets Motor[x].Ctrl to UserAlgo.ServoCtrlAddr[i] Multiple-motor servo algorithms can be implemented Permits sophisticated handling of dynamic cross-coupling effects Algorithm to be executed for lowest-numbered of consecutively-numbered motors Set Motor[x].ExtraMotors to number of additional motors handled here Can access elements for additional motors in two ways: Relative addressing: Mptr2 = Mptr + 1; Mptr2->Integrator += Mptr2->PosError; Absolute addressing: pshm->Motor[7].Integrator += pshm->Motor[7].PosError; Write to Mptrn->ServoOut for additional motor command outputs

9 Example User-Written Servo Routine
Very simple PID control algorithm Uses Delta Tau-defined saved gain elements Kp, Kvfb, Ki double user_pid_ctrl(struct MotorData *Mptr) { double ctrl_effort; if (Mptr->ClosedLoop) { // Servo active in closed loop? ctrl_effort = Mptr->Servo.Kp * Mptr->PosError - Mptr->Servo.Kvfb * Mptr->ActVel; // PD terms Mptr->Servo.Integrator += Mptr->PosError * Mptr->Servo.Ki; // I term ctrl_effort += Mptr->Servo.Integrator; // Combine return ctrl_effort; // Return value for automatic handling } else { // Open loop mode Mptr->Servo.Integrator = 0.0; // Clear integrator return 0.0; // Zero output

10 C User-Written Phase Routines
Each phase update period, every motor with PhaseCtrl > 0 calls its specified phase routine (built-in or user-written) as function Each motor can have its own routine Can provide own name(s) for user-written routine(s) Routine must accept a “MotorData” pointer as argument Power PMAC will automatically pass pointer to present motor’s structure Permits same algorithm to be used unchanged for different motors Can use saved setup elements as for standard algorithm Must directly access I/O registers No automatic pre/post-processing as for servo Must explicitly convert between fixed-point I/O and (recommended) floating-point computations Have access to Power PMAC’s floating-point math library, even though executing in the real-time kernel

11 C User-Written Phase Routines (cont.)
Must be declared in form: “void MyPhaseAlg(struct MotorData *Mptr)” IDE creates declaration automatically from user-entered routine name Routine must write command values directly to output registers Can use address set by Motor[x].pDac, as built-in routine does, e.g.: Mptr->pDac[0] = PhaseACmd; Mptr->pDac[1] = PhaseBCmd; Use IDE Project Manager to tell which motor(s) use this routine In Solution Explorer, right-click on “Realtime Routines” under “C Language” Select “User Servo Setup” to get window to assign routines to motors

12 Example User-Written Phase Routine
Simple sine output commutation routine: void user_phase(struct MotorData *Mptr) { int PresentEnc, PhaseTableOffset; float *SineTable; double DeltaEnc, PhasePos, IqVolts, IaVolts, IbVolts; PresentEnc = *Mptr->pPhaseEnc; // Read new rotor position DeltaEnc = (double) (PresentEnc - Mptr->PrevPhaseEnc); // Compute change and convert to floating-point Mptr->PrevPhaseEnc = PresentEnc; // Store new rotor position for next cycle PhasePos = Mptr->PhasePos + Mptr->PhasePosSf * DeltaEnc; // Scale change to sine table increments and accumulate if (PhasePos < 0.0) PhasePos += ; // Negative rollover? else if (PhasePos >= ) PhasePos -= ; // Positive rollover? PhaseTableOffset = (int) PhasePos; // Table entry index Mptr->PhasePos = PhasePos; // Store in structure for next cycle IqVolts = Mptr->IqCmd; // Get torque (quadrature) command from servo output SineTable = Mptr->pVoltSineTable; // Start address of lookup table IaVolts = IqVolts * SineTable[(PhaseTableOffset + 512) & 2047]; // Compute Phase A command IbVolts = IqVolts * SineTable[(PhaseTableOffset + Mptr->PhaseOffset + 512) & 2047]; // Compute Phase B command Mptr->pDac[0] = ((int) (IaVolts * 65536)); // Scale, fix, and output Phase A Mptr->pDac[1] = ((int) (IbVolts * 65536)); // Scale, fix, and output Phase B }

13 Using Matlab/SimulinkTM for Servo Design
Design algorithm graphically in Simulink Simulate performance with plant model and excitation block Use “scopes” to analyze performance Debug and refine until ready to test

14 Using Matlab/SimulinkTM for Servo Design (cont.)
Replace excitation block(s) and plant model with provided Power PMAC I/O blocks (One-time) installation of “DELTATAU PPMAC Library” in Simulink Library Browser (One-time) load of preset “Configuration Parameters” Invoke Embedded CoderTM “Build Model” action Bring resulting “.c” and “.h” files into IDE, compile, and download

15 Selecting User-Written Phase and Servo

16 C Capture/Compare Interrupt Routine
Interrupt comes from PMAC3-style IC Can be generated on capture or compare event on any channel of IC User unmasks any or all interrupt sources from IC(s) This interrupt is highest priority in Power PMAC Can suspend phase and servo calculations Can execute at 60 kHz+ frequency Essential to keep interrupt service routine short! Mainly intended to update to/from list of positions in memory Usually list is in user shared memory buffer Must be declared as void CaptCompISR (void); Must be placed in usrcode.c file No floating-point math permitted (cannot use P & Q variables!) Enabled if UserAlgo.CaptCompIntr = 1

17 Sample Capture/Compare ISR
Interrupt Service Routine C code to log captured positions void CaptCompISR (void) { volatile GateArray3 *MyFirstGate3IC; // ASIC structure pointer int *CaptCounter; // Logs number of triggers int *CaptPosStore; // Storage pointer MyFirstGate3IC = GetGate3MemPtr(0); // Pointer to IC base CaptCounter = (int *)pushm ; // Sys.Idata[65535] CaptPosStore = (int *)pushm + *CaptCounter ; // Sys.Idata[65536+Counter] *CaptPosStore = MyFirstGate3IC->Chan[0].HomeCapt; // Store in array (*CaptCounter)++; // Increment counter MyFirstGate3IC->IntCtrl = 1; // Clear interrupt source } Script commands to set up ISR Gate3[0].IntCtrl = $ // Unmask PosCapt[0] Sys.Idata[65535] = 0 // Initialize counter UserAlgo.CaptCompIntr = 1 // Enable capture/compare ISR

18 Real-Time Interrupt C PLC Routine
Each real-time interrupt (Sys.RtIntPeriod+1 servo interrupts), Power PMAC calls “realtimeinterrupt_plcc” routine if UserAlgo.RtiCplc = 1 Note that if tasks from previous RTI are not finished, can “skip a beat” Routine must be in file rticplc.c in folder rticplc under CPLCs and C Language in project Routine must be declared as “void realtimeinterrupt_plcc()” Do not put within indefinite loop – Power PMAC causes repeated execution by repeated calls Use a “sleep” function instead to suspend

19 Background C PLC Routines
After each scan of one background Script PLC, Power PMAC calls each background C PLC routine n as function if its UserAlgo.BgCplc[n] = 1 Up to 32 background C PLC routines (n = 0 to 31) Routine for C PLC n must be in file bgcplcnn.c in folder bgcplcnn under CPLCs and C Language in project Each routine must be declared as “void user_plcc()” (routines are distinguished by file name and folder) These background C PLC routines are equivalent to background compiled PLC programs in Turbo PMAC Next background Script PLC will not run until C PLCs are finished, or 100 μsec later, whichever is less Do not put within indefinite loop – Power PMAC causes repeated execution by repeated calls Use a “sleep” function instead to suspend

20 Example C PLC Routine Sample program to alternate outputs on UMAC I/O Card #include <RtGpShm.h> #include <stdio.h> #include <dlfcn.h> #define IoCard0Out0_7 *(piom + 0xA0000C/4) #define IoCard0Out8_15 *(piom + 0xA00010/4) #define IoCard0Out16_23 *(piom + 0xA00014/4) #define OutputData(x) (x << 8) void user_plcc() // Background C PLC function { static int i = 0; if (i++ > 1000) { // > 1 sec from cycle start IoCard0Out0_7 = OutputData(0xAA); // Odd-numbered outputs on IoCard0Out8_15 = OutputData(0xAA); IoCard0Out16_23 = OutputData(0xAA); if (i > 2000) i = 0; // Reset to start of cycle } else { // < 1 sec from cycle start IoCard0Out0_7 = OutputData(0x55); // Even-numbered outputs on IoCard0Out8_15 = OutputData(0x55); IoCard0Out16_23 = OutputData(0x55);

21 “CfromScript” Subroutine
Permits any Script program to call a C function as a subroutine Useful when need flexibility of C Useful when need high-speed computation of C Mainly used for intensive kinematic calculations C function must be declared as: double CfromScript (double arg1, double arg2, … , double arg7, LocalData *Ldata) Script program command must invoke function with 7 double arguments and accept returned double value – e.g.: Test = CfromScript (CSNum, Mode, 0, 0, 0, 0, 0); Pointer to local variable structure passed automatically Only single function of this type permitted in Power PMAC Logic inside can allow calling this function for multiple purposes

22 Background C Application Programs
Generic applications that run under Linux GPOS (not real-time) Applications are separate programs, not functions/subroutines (but can call their own functions/subroutines) Can be completely independent of Power PMAC dedicated tasks Execution and scheduling are functions of Linux OS settings Can have access to Power PMAC shared memory structures Must use “#include <RtGpShm.h>” to access header file with definitions Must explicitly declare variables to access structures, e.g.: volatile struct SHM *pshm; (“volatile” specifies re-read for every access) (This is unlike C routines called as Power PMAC functions)


Download ppt "User C Programs in Power PMAC December 2013"

Similar presentations


Ads by Google