⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 module_rt.c

📁 Source code for an Numeric Cmputer
💻 C
字号:
/****************************************************************************** * * Copyright (C) 2005 Peter G. Vavaroutsos <pete AT vavaroutsos DOT com> * * $RCSfile: module_rt.c,v $ * $Author: alex_joni $ * $Locker:  $ * $Revision: 1.5 $ * $State: Exp $ * $Date: 2005/10/30 22:00:40 $ * * This is a PLC component for the HAL. It is based on Classic Ladder. * * Installation of the component (realtime only): * * insmod classicladder_rt <numRungs=10> <numBits=500> <numWords=50> *	<numTimers=8> <numMonostables=8> <numPhysInputs=10> *	<numPhysOutputs=50> <numArithmExpr=100> <numSections=10> * * * The following items are exported to the HAL. <channel> is * formated as "%02d". * The following items are exported to the HAL. <plcId> is * formated as "%d". <channel> is formated as "%02d". * *   Pins: *	u8	classicladder.<plcId>.status	// 0=load, 1=stop, 2=run *	bit	classicladder.<plcId>.in-<channel> *	bit	classicladder.<plcId>.out-<channel> * *   Functions: *	void    classicladder.<plcId>.refresh * ****************************************************************************** * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2.1 of the GNU General * Public License as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA * * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of * harming persons must have provisions for completely removing power * from all motors, etc, before persons enter any danger area.  All * machinery must be designed to comply with local and national safety * codes, and the authors of this software can not, and do not, take * any responsibility for such compliance. * * This code was written as part of the EMC HAL project.  For more * information, go to www.linuxcnc.org. * ******************************************************************************/#ifndef RTAPI#error This is a realtime component only!#endif#include "rtapi.h"			// RTAPI realtime OS API.#include "rtapi_app.h"			// RTAPI realtime module decls.#include "hal.h"			// HAL public API decls.#include "classicladder.h"#include "global.h"#include "arrays.h"#include "vars_access.h"#include "calc_rt.h"#ifndef MODULE#define MODULE#endif#ifdef MODULE// Module information.MODULE_AUTHOR("Pete Vavaroutsos");MODULE_DESCRIPTION("PLC component for EMC HAL");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif // MODULE_LICENSEstatic long				period = 0;	// Thread period (0 = no thread).MODULE_PARM(period, "l");MODULE_PARM_DESC(period, "thread period (nsecs)");static int numRungs = 10;MODULE_PARM(numRungs, "i");MODULE_PARM_DESC(numRungs, "Number of rungs to allocate");static int numBits = 500;MODULE_PARM(numBits, "i");MODULE_PARM_DESC(numBits, "Number of bits to allocate");static int numWords = 50;MODULE_PARM(numWords, "i");MODULE_PARM_DESC(numWords, "Number of words to allocate");static int numTimers = 8;MODULE_PARM(numTimers, "i");MODULE_PARM_DESC(numTimers, "Number of timers to allocate");static int numMonostables = 8;MODULE_PARM(numMonostables, "i");MODULE_PARM_DESC(numMonostables, "Number of monostables to allocate");static int numPhysInputs = 10;MODULE_PARM(numPhysInputs, "i");MODULE_PARM_DESC(numPhysInputs, "Number of inputs to allocate");static int numPhysOutputs = 50;MODULE_PARM(numPhysOutputs, "i");MODULE_PARM_DESC(numPhysOutputs, "Number of outputs to allocate");static int numArithmExpr = 100;MODULE_PARM(numArithmExpr, "i");MODULE_PARM_DESC(numArithmExpr, "Number of arithmetic expressions to allocate");static int numSections = 10;MODULE_PARM(numSections, "i");MODULE_PARM_DESC(numSections, "Number of sections to allocate");#endif // MODULE/****************************************************************************** * PLC OBJECT * * This object contains the data for one PLC object. * ******************************************************************************/typedef struct {    // Pins.    hal_bit_t				*pValue;} DigitalInPinsParams;typedef struct {    // Pins.    hal_bit_t				*pValue;} DigitalOutPinsParams;typedef struct {    hal_u8_t				*pStatus;    DigitalInPinsParams			*pInPins;    DigitalOutPinsParams		*pOutPins;} Plc;// These methods are used for initialization.static int Plc_Init(Plc *this, int componentId);static int Plc_ExportPinsParametersFunctions(Plc *this, int componentId, int boardId);// These methods are exported to the HAL.static void Plc_Refresh(void *this, long period);// Private helper methods.static void Plc_ReadPhysicalInputs(Plc *this);static void Plc_WritePhysicalOutputs(Plc *this);/****************************************************************************** * COMPONENT OBJECT * * This object contains all the data for this HAL component. * ******************************************************************************/#define MAX_PLCS			1		// Classic Ladder is too							// broken to support more.typedef struct {    int					componentId;	// HAL component ID.    Plc					*plcTable[MAX_PLCS];} Component;static Component			component;/****************************************************************************** * INIT AND EXIT CODE ******************************************************************************/intrtapi_app_main(void){    int					i;    Plc					*pPlc;    // Connect to the HAL.    component.componentId = hal_init("classicladder_rt");    if (component.componentId < 0) {	rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: hal_init() failed\n");	return(-1);    }    for(i = 0; i < MAX_PLCS; i++){	component.plcTable[i] = NULL;    }    for(i = 0; i < MAX_PLCS; i++){	// Allocate memory for plc object.	pPlc = hal_malloc(sizeof(Plc));	if (pPlc == NULL) {	    rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: hal_malloc() failed\n");	    hal_exit(component.componentId);	    return(-1);	}	// Save pointer to plc object.	component.plcTable[i] = pPlc;	// Initialize PLC.	if(Plc_Init(pPlc, component.componentId)){	   hal_exit(component.componentId);	   return(-1);	}	// Export pins, parameters, and functions.	if(Plc_ExportPinsParametersFunctions(pPlc, component.componentId, i++)){	    hal_exit(component.componentId);	    return(-1);	}    }    // Was 'period' specified in the insmod command?    if (period > 0) {	// Create a thread.	if (hal_create_thread("classicladder.thread", period, 1) < 0){	    rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: hal_create_thread() failed\n");	    hal_exit(component.componentId);	    return(-1);	} else {	    rtapi_print_msg(RTAPI_MSG_INFO, "CLRT: created %d uS thread\n", period / 1000);	}    }    return(0);}voidrtapi_app_exit(void){    int					i;    Plc					*pPlc;    ClassicLadderFreeAll(component.componentId);    hal_exit(component.componentId);    for(i = 0; i < MAX_PLCS; i++){	if((pPlc = component.plcTable[i]) != NULL){#if 0	    // TODO: Free memory when HAL supports free.	    if(pPlc->pInPins != NULL)		hal_free(pPlc->pInPins);	    if(pPlc->pOutPins != NULL)		hal_free(pPlc->pOutPins);	    hal_free(pPlc);#endif	}    }}/****************************************************************************** * PLC OBJECT FUNCTION DEFINITIONS ******************************************************************************//* * LOCAL FUNCTIONS */static intPlc_Init(Plc *this, int componentId){    plc_sizeinfo_s			sizeInfo;    this->pOutPins = NULL;    // Allocate data for input pins.    this->pInPins = hal_malloc(sizeof(DigitalInPinsParams) * numPhysInputs);    if (this->pInPins == NULL) {	rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: hal_malloc() failed\n");	return(-1);    }    // Allocate data for output pins.    this->pOutPins = hal_malloc(sizeof(DigitalOutPinsParams) * numPhysOutputs);    if (this->pOutPins == NULL) {	rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: hal_malloc() failed\n");	return(-1);    }    // Copy module parameters for allocation into Classic Ladder structure.    sizeInfo.nbr_rungs = numRungs;    sizeInfo.nbr_bits = numBits;    sizeInfo.nbr_words = numWords;    sizeInfo.nbr_timers = numTimers;    sizeInfo.nbr_monostables = numMonostables;    sizeInfo.nbr_phys_inputs = numPhysInputs;    sizeInfo.nbr_phys_outputs = numPhysOutputs;    sizeInfo.nbr_arithm_expr = numArithmExpr;    sizeInfo.nbr_sections = numSections;    if(!ClassicLadderAllocAll(componentId, &sizeInfo)){	rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: ClassicLadderAllocAll() failed\n");	return(-1);    }    return(0);}static intPlc_ExportPinsParametersFunctions(Plc *this, int componentId, int plcId){    int					msgLevel, error, channel;    char				name[HAL_NAME_LEN + 2];    // This function exports a lot of stuff, which results in a lot of    // logging if msg_level is at INFO or ALL. So we save the current value    // of msg_level and restore it later.  If you actually need to log this    // function's actions, change the second line below.    msgLevel = rtapi_get_msg_level();    rtapi_set_msg_level(RTAPI_MSG_WARN);    // Export pins and parameters.    rtapi_snprintf(name, HAL_NAME_LEN, "classicladder.%d.status", plcId);    if((error = hal_pin_u8_new(name, HAL_WR, &(this->pStatus), componentId)) == 0){	// Init pin.	*(this->pStatus) = InfosGene->LadderState;    }    for(channel = 0; channel < numPhysInputs && !error; channel++){	// Pins.	rtapi_snprintf(name, HAL_NAME_LEN, "classicladder.%d.in-%02d", plcId, channel);	if((error = hal_pin_bit_new(name, HAL_RD, &(this->pInPins[channel].pValue), componentId)) != 0)	    break;	// Init pin.	*(this->pInPins[channel].pValue) = 0;    }    for(channel = 0; channel < numPhysOutputs && !error; channel++){	// Pins.	rtapi_snprintf(name, HAL_NAME_LEN, "classicladder.%d.out-%02d", plcId, channel);	if((error = hal_pin_bit_new(name, HAL_WR, &(this->pOutPins[channel].pValue), componentId)) != 0)	    break;	// Init pin.	*(this->pOutPins[channel].pValue) = 0;    }    // Export functions.    if(!error){	rtapi_snprintf(name, HAL_NAME_LEN, "classicladder.%d.refresh", plcId);	error = hal_export_funct(name, Plc_Refresh, this, 0, 0, componentId);    }    if(error){	rtapi_print_msg(RTAPI_MSG_ERR, "CLRT: ERROR: export digital in failed\n");    }    // Restore saved message level.    rtapi_set_msg_level(msgLevel);    return(error);}/* * HAL EXPORTED FUNCTIONS */static voidPlc_Refresh(void *arg, long period){    Plc					*this = (Plc *)arg;    if((*(this->pStatus) = InfosGene->LadderState) == STATE_RUN){	Plc_ReadPhysicalInputs(this);	RefreshAllRungs(period);	Plc_WritePhysicalOutputs(this);    }}/* * PRIVATE HELPER FUNCTIONS */voidPlc_ReadPhysicalInputs(Plc *this){    int					i;    // Copy HAL pin data to Classic Ladder structure.    for(i = 0; i < numPhysInputs; i++){	WriteVar(VAR_PHYS_INPUT, i, *(this->pInPins[i].pValue));    }}voidPlc_WritePhysicalOutputs(Plc *this){    int					i;    // Copy HAL pin data from Classic Ladder structure.    for(i = 0; i < numPhysOutputs; i++){	 *(this->pOutPins[i].pValue) = ReadVar(VAR_PHYS_OUTPUT, i);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -