INOS
cinosbus.h
Go to the documentation of this file.
1 //******************************************************************************
27 //******************************************************************************
28 
29 #ifndef INC_CINOSBUS_H
30 #define INC_CINOSBUS_H
31 
32 //------------------------------------------------------------------------------
33 // defines
34 //------------------------------------------------------------------------------
35 //
36 #define DF_INOS_BUS_DBT "INOS-BUS" // INOS-BUS db table name
37 //
38 #define DF_INOS_BUS_MAX_NUMBER 4 // max. number of inos buses on one target
39 #define DF_INOS_BUS_MAX_DMY_JOBS 4 // max. number of dummy jobs
40 #define DF_INOS_BUS_MAX_CATEGORY 4 // max. number of cycletime categories
41 #define DF_INOS_BUS_MAX_CYCLE_NUMBER 32 // max. number of bus cycles supported (32 kHz)
42 //
43 #define DF_INOS_BUS_CATEGORY_INVALID 255 // invalid category number
44 #define DF_INOS_BUS_CATEGORY_1000_US 3 // category number 1ms
45 #define DF_INOS_BUS_CATEGORY_250_US 2 // category number 250us
46 #define DF_INOS_BUS_CATEGORY_125_US 1 // category number 125us
47 #define DF_INOS_BUS_CATEGORY_FASTEST 0 // category number 'fastest' (16, 32 or 64 kHz)
48 //
49 #define DF_INOS_BUS_CORE_0 0 // running on core 0
50 #define DF_INOS_BUS_CORE_1 1 // running on core 1
51 #define DF_INOS_BUS_CORE_2 2 // running on core 2
52 #define DF_INOS_BUS_CORE_3 3 // running on core 3
53 //
54 #define DF_INOS_BUS_JOB_CTM_RES 0x8000 // job in 2 dim array is CTM reserved
55 #define DF_INOS_BUS_JOB_CLD_RES 0x4000 // job in 2 dim array is CLD reserved
56 #define DF_INOS_BUS_JOB_WTG_RES 0x2000 // job in 2 dim array is WTG reserved
57 #define DF_INOS_BUS_JOB_TIM_RES 0x1000 // job in 2 dim array is TIM reserved
58 #define DF_INOS_BUS_JOB_IRQ_REQ 0x0800 // job in 2 dim array has IRQ request
59 #define DF_INOS_BUS_JOB_NDY_MSK 0xE000 // job 'not a dummy' mask in 2 dim array
60 #define DF_INOS_BUS_JOB_IND_MSK 0x07FF // job index/time mask in 2 dim array
61 //
62 #define DF_INOS_BUS_STACKSIZE_MIN 32768 // minimum stack size required for bus task
63 //
64 // --- inos bus states ---------------------------------------------------------
65 //
66 #define DF_INOS_BUS_STAT_IDLE 0 // state IDLE
67 #define DF_INOS_BUS_STAT_SCAN 1 // state SCAN
68 #define DF_INOS_BUS_STAT_INIT 2 // state INIT
69 #define DF_INOS_BUS_STAT_RUN 3 // state RUN
70 #define DF_INOS_BUS_STAT_RUN_DIAG 4 // state RUN DIAGNOSIS
71 #define DF_INOS_BUS_STAT_DOWN 5 // state DOWN
72 #define DF_INOS_BUS_STAT_STOPPED 6 // state STOPPED
73 //
74 // --- inos bus options --------------------------------------------------------
75 //
76 #define DF_INOS_BUS_OPTION_FLOAT 0x00000001 // option 'floating point support'
77 #define DF_INOS_BUS_OPTION_NO_1MS 0x00000002 // option 'has no 1ms handler'
78 #define DF_INOS_BUS_OPTION_SPLIT_SC 0x00000004 // option 'split sub cycle'
79 #define DF_INOS_BUS_OPTION_STOP_ON_OVERRUN 0x00000008 // option 'stop in case of overrun'
80 #define DF_INOS_BUS_OPTION_IGNORE_MAC 0x00000010 // option 'ignore slave mac address'
81 #define DF_INOS_BUS_OPTION_NO_IRQ 0x00000020 // option 'run with disabled irq's'
82 #define DF_INOS_BUS_OPTION_NO_INCO 0x00000040 // option 'no inco communication support
83 #define DF_INOS_BUS_OPTION_CYCLE_CAT 0x00000080 // option 'cycle categories'
84 #define DF_INOS_BUS_OPTION_NO_POST_HANDLER 0x00000100 // option 'do not create posthandler task'
85 #define DF_INOS_BUS_OPTION_FAKE 0x00000200 // option 'fake bus'
86 #define DF_INOS_BUS_OPTION_EXTENDED_PAUSE 0x00000400 // option 'extended pause bits (InfoLink)'
87 #define DF_INOS_BUS_OPTION_SIMULATED 0x00000800 // option 'fieldbus is simulated'
88 #define DF_INOS_BUS_OPTION_SLOT_IRQTIME 0x00001000 // option 'slot irq time always required'
89 #define DF_INOS_BUS_OPTION_JITTER_CHECK 0x00002000 // option 'jitter supervision check required'
90 //
91 #define DF_INOS_BUS_OPTIONEX_OPT_PORT_HANDLING 0x00000001 // option 'optimized port handling'
92 #define DF_INOS_BUS_OPTIONEX_RINGMODE 0x00000002 // option 'ginlink in ring mode'
93 #define DF_INOS_BUS_OPTIONEX_AUTO_CLOSE 0x00000004 // option 'ginlink in auto close mode'
94 #define DF_INOS_BUS_OPTIONEX_LATE_STATE_RUNNING 0x00000008 // option that sets bus state to 'running' *after* LinkUp() has been called
95 #define DF_INOS_BUS_OPTIONEX_DO_NOT_CREATE_PORTS 0x00000010 // option 'do not create ports of scanned modules'
96 #define DF_INOS_BUS_OPTIONEX_SETUP_OFFLINE_MODULE 0x00000020 // option 'setup bus module even if the module is offline'
97 #define DF_INOS_BUS_OPTIONEX_USE_ALL_CORES 0x00000040 // option 'use all available cores'
98 #define DF_INOS_BUS_OPTIONEX_PORTS_PUBLIC 0x00000080 // option 'all ports are public' (used on 3 ported ram slaves)
99 #define DF_INOS_BUS_OPTIONEX_MODULES_MULTICORE 0x00000100 // option 'restrict supported modules on multicore systems'
100 #define DF_INOS_BUS_OPTIONEX_ONLY_SETUP_KNOWN_MODULES 0x00000200// option 'only configure/safe/operational known modules'
101 #define DF_INOS_BUS_OPTIONEX_DO_NOT_STOP_ON_TRAP 0x00000400 // option 'do not stop bus in case of a trap'
102 #define DF_INOS_BUS_OPTIONEX_DMA_TRANSFER 0x00000800 // option 'use DMA if available'
103 #define DF_INOS_BUS_OPTIONEX_PORT_REC_OVERWRITE_OFFLINE 0x00001000 // option 'set ports to receive overwrite if slave is offline'
104 #define DF_INOS_BUS_OPTIONEX_OPT_CHANNEL_NUMBERING 0x00002000 // option 'optimized channel numbering'
105 #define DF_INOS_BUS_OPTIONEX_NO_RECEIVE_DATA 0x00004000 // option 'do not handle receive data'
106 #define DF_INOS_BUS_OPTIONEX_CLEANUP_AT_RESCAN 0x00008000 // option 'cleanup processimage at rescan'
107 #define DF_INOS_BUS_OPTIONEX_TRADATA_COPY_IN_RAM 0x00010000 // option 'transmit data copy in ram'
108 #define DF_INOS_BUS_OPTIONEX_LOOPBACK 0x00020000 // option 'ginlink in loopback mode'
109 #define DF_INOS_BUS_OPTIONEX_HARDWARE_SLOTCOUNT 0x00040000 // option 'ginlink in hardware slot count mode'
110 #define DF_INOS_BUS_OPTIONEX_MULTIPLE_INSTANCE_SUPPORT 0x00080000 // option 'multiple bus type instances supported'
111 //
112 #define DF_INOS_BUS_SYNCTOLERANCE_DEFAULT 2000 // default sync tolerance [ns]
113 #define DF_INOS_BUS_WATCHDOGLEVEL_DEFAULT 4 // default watchdog level
114 //
115 // --- inos bus errors ---------------------------------------------------------
116 //
117 #define ER_INOS_BUS_ERRORCOUNTER 0x00000001 // error counter
118 #define ER_INOS_BUS_OVERRUNCOUNTER 0x00000002 // overrun counter
119 #define ER_INOS_BUS_DOWN 0x00000004 // bus down
120 #define ER_INOS_BUS_POSTOVERRUNCOUNTER 0x00000008// post overrun counter
121 #define ER_INOS_BUS_SYNCCORES_TIMEOUT 0x00000010// SyncCores with timeout waiting for the other core(s)
122 #define ER_INOS_BUS_RESCAN 0x00000020// bus rescan was performed
123 #define ER_INOS_BUS_MAINTENANCE 0x00000040// maintenance overrun counter
124 #define ER_INOS_BUS_JITTER_MAX 0x00000080// max. allowed jitter exeeded
125 //
126 // --- inos bus hook flags -----------------------------------------------------
127 //
128 #define DF_INOS_BUS_HOOK_FLAG_ENB 0x0001 // bus hook enabled
129 #define DF_INOS_BUS_HOOK_FLAG_REM 0x0002 // bus hook has to be removed
130 //
131 // --- inos bus hook priorities ------------------------------------------------
132 //
133 #define DF_INOS_BUS_HOOK_ORDER_PRE_AXIS -20
134 #define DF_INOS_BUS_HOOK_ORDER_AXIS_PRE_MAP -10
135 #define DF_INOS_BUS_HOOK_ORDER_AXIS_MAP 0
136 #define DF_INOS_BUS_HOOK_ORDER_CONTROL 0
137 #define DF_INOS_BUS_HOOK_ORDER_AXIS_PST_MAP 10
138 #define DF_INOS_BUS_HOOK_ORDER_PST_AXIS 20
139 #define DF_INOS_BUS_HOOK_ORDER_DEFAULT 20
140 //
141 // --- inos bus page types -----------------------------------------------------
142 //
143 #define DF_INOS_BUS_PAGE_ANALOG 1 // bus page analog
144 #define DF_INOS_BUS_PAGE_DIGITAL 2 // bus page digital
145 #define DF_INOS_BUS_PAGE_AXIS 3 // bus page axis
146 //
147 //------------------------------------------------------------------------------
148 // macros
149 //------------------------------------------------------------------------------
150 //
151 /* CycleId :
152 
153  15 10 9 8 7 0
154  --------------------------------
155  | | | |
156  --------------------------------
157  | | |
158  | | cycle number (0..255)
159  | category (0..3)
160  core id (0..63)
161 */
162 
167 #define INOS_CYCLEID(auCoreId, auCategory, auCycleNumber) (((uint16)auCoreId<<10)+((uint16)auCategory<<8)+(auCycleNumber&0xff))
168 #define INOS_CORE_FROM_CATEGORY(aCategory) ((aCategory>>2)&0x3F)
169 #define INOS_CATEGORY_FROM_CATEGORY(aCategory) (aCategory&0x03)
170 #define INOS_CORE_FROM_CYCLEID(aCycleId) ((uint8)((aCycleId>>10)&0x3F))
171 #define INOS_CATEGORY_FROM_CYCLEID(aCycleId) ((uint8)((aCycleId>>8)&0x03))
172 #define INOS_CYCLENUMBER_FROM_CYCLEID(aCycleId) ((uint8)(aCycleId&0xFF))
173 
174 #define INOS_CYCLEID_DONT_CARE (0xffff)
175 #define INOS_CORE_ID_DONT_CARE (0x3f)
176 
177 #define INOS_CYCLEID_ANY_CAT_AND_NUM ((uint16)0x03ff)
178 
179 #define INOS_CYCLEID_ANY_ON_CORE(auCoreId) (((uint16)auCoreId<<10) | INOS_CYCLEID_ANY_CAT_AND_NUM)
181 
182 
183 //
184 //------------------------------------------------------------------------------
185 // includes
186 //------------------------------------------------------------------------------
187 //
188 // system
189 #include <inos.h>
190 #include <cinosbushooks.h>
191 #include <cinosbusjob.h>
192 #include <cinosbusmodule.h>
193 //
194 // C++
195 #include <atomic>
196 #include <xmlparser.h>
197 //
198 // project
199 //
200 //------------------------------------------------------------------------------
201 //--- structures ---------------------------------------------------------------
202 //------------------------------------------------------------------------------
203 //
204 struct SINOSBus
205  //; structure of INOS-BUS database table
206 {
207  inosName32 m_cName;
208  //; bus name
209  inosName m_cType;
210  //; inos bus type name
211  uint32 m_uOffset;
212  //; bus offset in process image
213  uint16 m_uMainCycleTime;
214  //; bus main cycle time in us (0-don't care)
215  uint16 m_uWaitAfterReset;
216  //; time [us] to wait after reset
217  uint16 m_uScanMaxWaitForBus;
218  //; max. waiting time [ms] until bus comes up (e.g. link closed)
219  uint16 m_uScanMaxWaitForModules;
220  //; max. waiting time [ms] until modules ready (e.g. IMP-MAS)
221  uint16 m_uStackSize;
222  //; stack size of bus task
223  uint16 m_uMaxEepromSize;
224  //; max. size of module eeproms [bytes]
225  uint32 m_uOptions;
226  //; Bit 0 : 0-no floatingpoint support, 1-floatingpoint support
227  //; Bit 1 : 0-has 1ms handler, 1-no 1ms handler
228  //; Bit 2 : 0-standard sub cycle, 1-splitted subcycle (for heavy loads)
229  //; Bit 3 : 1-stop bus in case of overrun
230  //; Bit 4 : 1-ignore slave mac address
231  //; Bit 5 : 1-run with disabled irq's
232  //; Bit 6 : 1-no inco communication support
233  //; Bit 7 : 1-has cycle categories
234  //; Bit 8 : 1-no post handler task requested
235  uint8 m_uPriority;
236  //; bus task priority
237  uint8 m_uId;
238  //; bus id (0, 1, ...)
239  uint8 m_uInstance;
240  //; bus type instance (GinLink0, Ginlink1, ...)
241  uint8 m_uCores;
242  //; number of cores used by the bus
243  uint8 m_uCoreId;
244  //; base core id (virtual core id of first core)
245  uint32 m_uMaxHooks;
246  //; max. number of hooks supported
247  uint8 m_uScanIncludeModuleName;
248  //; include module name in process image channel name (0-no, 1-yes)
249  uint32 m_uOptionsEx;
250  //; Bit 0 : 1-optimized port handling
251  uint32 m_uMaxChannelsPerModule;
252  //; max. number of 32 bit channels per bus module
253  uint32 m_uMaxBitsPerModule;
254  //; max. number of bit channels per bus module (e.g. digital inputs/outputs)
255  uint32 m_uCycleTimeCat[DF_INOS_BUS_MAX_CATEGORY];
256  //; requested categoy cycle times
257  uint8 m_uCycleTimePage[DF_INOS_BUS_MAX_CATEGORY];
258  //; requested page number per category
259  uint8 m_uCycleTimeOversampling[DF_INOS_BUS_MAX_CATEGORY];
260  //; requested oversampling per category
261  uint32 m_uErrorMask;
262  //; error mask: defines which errors shall be reported and which shall
263  //; be ignored.
264  uint8 m_uSyncType;
265  //; syncing type(0-none, 1-master, 2-sync to master, 3- sync to time)
266  uint32 m_uSyncOffset;
267  //; syncing offset [ns] within a 1ms cycle (0xffffffff -> don't care)
268  uint32 m_uSyncTolerance;
269  //; syncing tolerance [ns] within a 1ms cycle (default = 2000)
270  uint32 m_uWatchdogLevel;
271  //; number of missing frames till category watchdog (default = 4)
272  uint32 m_uHookFreeze;
273  //; hook freeze trigger time [ns] (default = 0)
274 };
275 //
277 {
279  uint8 m_uCommand;
281  uint8 m_uReserved[sizeof(uintptr)-1];
282 };
283 //
285 {
287  uintptr m_uAddress;
288 };
289 //
291 {
293  void* m_pObject;
295  void* m_pMethod;
297  uint32 m_uParam;
298 };
299 //
301 {
302  enum {
303  eSize16 = 0x00000001,
304  eSize32 = 0x00000000,
305  eSizeMask = 0x00000001
306  };
307  enum {
308  eCmdPort = 0x00,
309  eCmdCall = 0x01
310  };
311  // add port read 16
312  void AddPort16(volatile void* apAddress)
313  {
314  // avoid buffer overflows
316  // ensure no address conflict
317  ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
318  // set values
320  p->m_uCommand = eCmdPort;
321  p->m_uAddress = (uintptr) apAddress + eSize16;
322  // adjust write index
324  }
325  // add port read 32
326  void AddPort32(volatile void* apAddress)
327  {
328  // avoid buffer overflows
330  // ensure no address conflict
331  ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
332  // set values
334  p->m_uCommand = eCmdPort;
335  p->m_uAddress = (uintptr) apAddress + eSize32;
336  // adjust write index
338  }
339  #if defined(INOS_PORTS_64BIT)
340  // add port read 64
341  void AddPort64(volatile void* apAddress)
342  {
343  // avoid buffer overflows
345  // ensure no address conflict
346  ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
347  // set values
349  p->m_uCommand = eCmdPort;
350  // not yet supported
351  ASSERT_ALWAYS(0);
352  // adjust write index
354  }
355  #endif
356  // add call
357  void AddCall(void* apObject, void* apMethod, uint32 auParam = 0)
358  {
359  // avoid buffer overflows
361  // method pointer needs to be valid
362  ASSERT_ALWAYS(apMethod != nullptr);
363  // set values
365  p->m_uCommand = eCmdCall;
366  p->m_pObject = apObject;
367  p->m_pMethod = apMethod;
368  p->m_uParam = auParam;
369  // adjust write index
371  }
372  // return true if buffer is empty
373  bool IsEmpty()
374  {
375  // check write index
376  return m_uWriteIndex==0;
377  }
378  // return true if buffer is empty
379  void Reset()
380  {
381  // reset write index
382  m_uWriteIndex = 0;
383  // temporary data
384  memset(m_uTemporary, 0, sizeof(m_uTemporary));
385  // and the whole buffer
386  memset(m_cData, 0, sizeof(m_cData));
387  }
388 
389  // constructor
391  {
392  // reset buffer
393  Reset();
394  }
398  uint32 m_uTemporary[2];
401  #if defined(INOS_64)
402  char m_cData[0x10000-3*sizeof(uint32)];
403  #else
404  char m_cData[0x4000-3*sizeof(uint32)];
405  #endif
406  // allow dynamic handling
407  DECLARE_DYNAMIC(SINOSBusHandlerBuffer);
408 };
412  void* m_pHandler;
413  //; pointer to hook handler
414  void* m_pObject;
415  //; pointer to hook object
416  uint32 m_uTimeBase;
417  //; global time base
418 
419  // allow dynamic handling
420  DECLARE_DYNAMIC(SINOSBusInfoHook);
421 };
428  uint16 m_uCatActCycle{};
429  uint32 m_uOverrunCounter{};
430 
431  uint32 m_uAct{};
432  uint32 m_uMin{};
433  uint32 m_uMax{};
434  uint32 m_uAllowed{};
435  uint32 m_uOverrunCounterDisabled{};
436  bool m_bOverrunDetectedByIrq{};
437 
439  std::atomic<uint32> m_uHooks{};
440 
441  #ifdef INOS_ADDITIONAL_BUS_TIME_MEASUREMENTS
442  bool m_bWtgLastTicksValid{};
444  uint32 m_uWtgLastTicks{};
445  uint32 m_uWtgDeltaAct{};
446  uint32 m_uWtgDeltaMin{};
447  uint32 m_uWtgDeltaMax{};
448 
450  #endif
451 
452  // allow dynamic handling
453  DECLARE_DYNAMIC(SINOSBusTiming);
454 };
469  uint32 m_uPostOverrunCounter;
470  bool m_bValid;
471  uint32 m_uSuspendTicks;
472  int32 m_uAct;
473  uint32 m_uMax;
474  uint32 m_uAllowed;
475 
477  uint32 m_uPostHooks;
478 
479  #ifdef INOS_ADDITIONAL_BUS_TIME_MEASUREMENTS
481  #endif
482 
483  // allow dynamic handling
484  DECLARE_DYNAMIC(SINOSBusPostTiming);
485 };
486 //
487 struct SINOSCatInfo {
496 
497  SINOSBusTiming m_CycleTiming[DF_INOS_MAX_CORES]; // array of bus timing
498  SINOSBusPostTiming m_CyclePostTiming[DF_INOS_MAX_CORES]; // array of bus 'post' timing
499 };
500 //
501 struct SINOSBusInfo {
502 
503  std::atomic<uint32> m_uOverrunCounter;
504  //; overrun counter
505  uint32 m_uOverrunCounterReported;
506  //; overrun counter as reported by calling SetError. It's required to
507  //; avoid that "the same overrun count" is reported multiple times when
508  //; the according error is being accepted.
509  //; This member is currently not used by the "category specific info"
510  //; instances, but it has been added here non the less (as adding new
511  //; members to CINOSBus is always a bit risky due to INFOLink.s)
512  std::atomic<uint32> m_uPostOverrunCounter;
513 
514  SINOSBusTiming m_CycleTiming;
515  //; Used to store the "bus timing"
516  SINOSBusPostTiming m_CyclePostTiming;
517  //; Used to store the "bus post timing"
518 
519  // allow dynamic handling
520  DECLARE_DYNAMIC(SINOSBusInfo);
521 };
526 struct SBusSleeper {
527  enum EReservedCounts {
528  eAlreadySignaled = 0
529  };
530  SBusSleeper(uint32 auBusTicks, bool abClocked = false);
536  uint32 m_uBusTicks;
542  static uint64 s_uClockedTickCount;
545  static void AddSleeper(SBusSleeper& aNewSleeper, SBusSleeper*& apFirstSleeper);
548  static void RemoveSleeper(SBusSleeper& aNewSleeper, SBusSleeper*& apFirstSleeper);
554  static void HandleSleepers(SBusSleeper*& apFirstSleeper);
555 };
556 //
557 //------------------------------------------------------------------------------
558 // class definition
559 //------------------------------------------------------------------------------
560 //
561 struct SINOSBusPort;
562 class CINOSBusPort;
563 class CINOSBusModule;
564 class CINOSBus : public CINOSTask
565 {
566  friend void _INI_0299_CINOSBus();
567 
568  //--- user interface ---------------------------------------------------
569 
570  // public member functions
571  public :
572  virtual uint32 ContactModule(uint32 auAddress, uint32 auData);
573  //; contact module with 'aAddress'
574  virtual CINOSBusModule* Find(char* apName);
575  //; return pointer to module with name 'apName'
576  virtual CINOSBusModule* Find(uint32 auNumber);
577  //; return pointer to module 'auNumber' (if pointer = 0 -> last reached)
578  virtual CINOSBusModule* FindFromAddress(uint32 auAddress);
579  //; return pointer to module with given address
580  virtual CINOSBusModule* FindFromBusNr(uint32 auBusNr);
581  //; return pointer to module with given address
582  virtual uint8 GetBusNr(uint32 auVirtualAddress)
583  { return (uint8) auVirtualAddress;};
585  virtual bool IsBusTask(CINOSTask* apTask)
586  { return apTask == this; };
587  //; return true if given task is a bus relevant task
588  inline bool IsSimulated()
589  { return m_pDesc && (m_pDesc->m_uOptions & DF_INOS_BUS_OPTION_SIMULATED); };
590  //; return true if given task is a bus relevant task
591  CINOSBusModule* FindFromDigInp(const char* apName);
592  //; return pointer to module handling the digital input 'apName'
593  CINOSBusModule* FindFromDigOut(const char* apName);
594  //; return pointer to module handling the digital output 'apName'
595  CINOSBusJob* FindJob(uint32 auTraAddress);
596  //; find job with trans address auTraAddress
597  static CINOSBus* FindBus(char* apName);
598  //; return pointer to inos bus with name 'apName'
599  static CINOSBus* FindBus(uint32 auId);
600  //; return pointer to inos bus with id 'auId'
601  static CINOSBusPort* FindPortFromInp(uint32 auNumber);
602  //; get bus port handling digital input 'auNumber
603  static CINOSBusPort* FindPortFromOut(uint32 auNumber);
604  //; get bus port handling digital output 'auNumber
606  inline static CINOSBus* GetFirstBus() {
607  return s_pFirstBus;
608  }
610  static uint8 GetFirstBusId();
612  static void AddBus(uint32 auId, CINOSBus* apBus);
613  static void SetTargetError();
614  //; will be called on a target error (e.g. trap, assert, etc.). will stop
615  //; the bus if ActualTak() is a bus task and the failure is 'assert'.
616  virtual void Start(uint32 auState = DF_INOS_BUS_STAT_RUN){};
617  //; start up field bus
618  virtual void Stop(){};
619  //; stop field bus
620  virtual void Reset(){};
621  //; reset field bus
622  virtual void RegisterOversampling(uint32 auCycleTimeNs, uint8 auOversampling);
623  //; register oversampling factor for auCycleTime
624  //; NOTE: Generally, auCycleTime must be provided in microseconds,
625  //; but some subclasses (Like GinLink, but not COPBus) may
626  //; support nanoseconds as well.
627 
641  virtual uint32 RegisterHook(uintid& auHookId, void* apHandler, void* apObject = 0,
642  uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
643  int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
644  uint32 auFlags = CINOSBusHook::eFlgEnabled);
645 
659  virtual uint32 RegisterPostHook(uintid& auHookId, void* apHandler, void* apObject = 0,
660  uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
661  int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
662  uint32 auFlags = CINOSBusHook::eFlgEnabled);
663 
673  uint32 RegisterErrorHook(uintid& auHookId, void* apHandler, void* apObject = 0);
674 
679  virtual uint32 UnRegisterHook(uintid auHookId);
680 
685  virtual uint32 UnRegisterPostHook(uintid auHookId);
686 
691  uint32 UnRegisterErrorHook(uintid auHookId);
692 
697  uint32 EnableHook(uintid auHookId);
698 
703  uint32 DisableHook(uintid auHookId);
704 
709  void* GetHookHandler(uintid auHookId);
710 
716  uint32 SetHookHandler(uintid auHookId, void* apHandler);
717 
722  uint8 GetHookCycleNumber(uintid auHookId);
723 
728  uint32 GetHookCycleTime(uintid auHookId);
729 
730  virtual const char* GetCategoryName(
731  const uint32 auCategory) const;
732  //; \return The name of the task for the category. The returned
733  //; pointer is guaranteed to be valid, as long as the bus exists
734  //; (and can therefore directly be used to be registered in the
735  //; INCOtree)
736  virtual const CINOSTask* GetCategoryTask(
737  const uint32 auCategory) const;
738  //; \return The pointer to the task handling the category
739  uint32 GetState()
740  { return m_uState;};
741  //; get bus state
742  uint32 GetActCycle()
743  { return m_iActCycle; };
744  //; return actual sub cycle
745  virtual uint16* GetActCycleAdr(uint8 auCategory)
746  { return (uint16*) &m_iActCycle; };
747  //; return sub cycle address
748  virtual uint16 GetActCycleId()
749  { return 0xffff; };
750  //; return actual cycle id (this method only delivers correct
751  //; results if called from within a bus hook)
752  uint32 GetHeartBeat()
753  { return m_uHeartBeat;};
754  //; get bus heart beat
755  uint32 GetSubCycles()
756  { return m_uSubCycles;};
757  //; get bus heart beat
758  virtual void SetErrorCounter(uint32 auErrorCounter)
759  { m_uErrorCounter = auErrorCounter;};
760  //; set bus error counter
761  virtual uint32 GetErrorCounter()
762  { return m_uErrorCounter;};
763  //; get bus error counter
764  void SetOverrunCounter(uint32 auOverrunCounter)
765  { m_Info.m_uOverrunCounterReported = m_Info.m_uOverrunCounter = auOverrunCounter;};
766  //; set overrun counter. also sets "overrun counter reported" to
767  //; the same value. this avoids that an error will be reported,
768  //; when the counter is e.g. reset to 0.
769  uint32 GetOverrunCounter()
770  { return m_Info.m_uOverrunCounter;};
771  //; get overrun counter
772  void SetPostOverrunCounter(uint32 auPostOverrunCounter)
773  { m_Info.m_uPostOverrunCounter = auPostOverrunCounter;};
774  //; set post overrun counter
775  uint32 GetPostOverrunCounter()
776  { return m_Info.m_uPostOverrunCounter;};
777  //; get post overrun counter
778  virtual void DiagnosticOn();
779  //; switch to diagnostic mode
780  virtual void DiagnosticOff();
781  //; switch back to run mode
783  const char* GetType() {
784  if (m_pDesc) return m_pDesc->m_cType; else return nullptr;
785  }
786  virtual uint16 GetOffset(bool abReal = true) { if (m_pDesc) return (uint16)m_pDesc->m_uOffset; else return 0; }
787  //; return bus offset
788  uint8 GetId() { if (m_pDesc) return m_pDesc->m_uId; else return 0; }
789  //; return bus id
790  uint32 GetOptions() { if (m_pDesc) return m_pDesc->m_uOptions; else return 0; }
791  //; return bus options
792  uint16 GetOptionsEx() { if (m_pDesc) return m_pDesc->m_uOptionsEx; else return 0; }
793  //; return bus extended options
794  void SetOptionsEx(uint16 auOptions)
795  { if (m_pDesc) m_pDesc->m_uOptionsEx |= auOptions; }
796  //; set extended options
797  void ClrOptionsEx(uint16 auOptions)
798  { if (m_pDesc) m_pDesc->m_uOptionsEx &= (uint16) ~auOptions; }
799  //; clear extended options
800  uint64 GetTickCount();
801  //; return actual bus tick counter
802  uint64* GetTickCountAdr()
803  //; return bus tick counter address
804  { return &m_uTickCount; };
805  void SetTickCount(uint64 auTicks);
806  //; set actual bus tick counter
807  virtual uint32 GetTickTime() { return m_uSubCycleTime; }
808  //; return number of us one bus tick takes
809  virtual uint32 GetTickTimeNs()
810  {
811  if (m_uSubCycleTimeNs)
812  return m_uSubCycleTimeNs;
813  else
814  return m_uSubCycleTime*1000;
815  }
816  //; return number of ns one bus tick takes
817  uint32 GetMainCycleTime() { return m_uMainCycleTime; }
818  //; return number of us a main cycle takes
819  uint32 GetMainCycleTimeNs()
820  {
821  if (m_uMainCycleTimeNs)
822  return m_uMainCycleTimeNs;
823  else
824  return m_uMainCycleTime*1000;
825  }
826  //; return number of ns a main cycle takes
827  virtual uint32 GetSubCycleTime(uint8 auCategory=0) { return m_uSubCycleTime; }
828  //; return number of us a sub cycle takes
829  virtual uint32 GetSubCycleTimeNs(uint8 auCategory=0) { return GetTickTimeNs(); }
830  //; return number of ns a sub cycle takes
831  uint32 GetError() { return m_uError; };
832  //; return actual bus errors
833  void SetErrorMask(uint32 auMask) { m_uErrorMask = auMask;};
834  //; set error mask and return old mask
835  uint32 GetErrorMask() { return m_uErrorMask;};
836  //; get actual error mask
837  void AcceptError(uint32 auError = 0xffffffff);
838  //; accept error
839  uint8 GetScanIncludeModuleName() { return m_pDesc->m_uScanIncludeModuleName; }
840  //; return value of flag 'm_uScanIncludeModuleName'
841  uint16 GetScanMaxWaitForBus() { return m_pDesc->m_uScanMaxWaitForBus; }
842  //; return value of 'm_uScanMaxWaitForBus'
843  uint16 GetScanMaxWaitForModules() { return m_pDesc->m_uScanMaxWaitForModules; }
844  //; return value of 'm_uScanMaxWaitForModules'
845  virtual uint32 GetParam(const char* apName, real64& arResult);
846  //; universal get parameter with aName to aResult and return error code
847  virtual void ResetMeasure();
848  //; reset cpu load measurement
849  virtual void SyncBus(uint32 auCmdOffset);
850  //; sync bus to given offset
851  virtual void Accelerate(){};
852  //; accelerate bus cycle
853  virtual void Decelerate(){};
854  //; decelerate bus cycle
855  virtual void Exactelerate(){};
856  //; exactelerate bus cycle
857  real64 GetTimebase(uint32 auHigh, uint32 auLow);
858  //; return CPU timebase [ms] at bus tick auHigh|auLow
859  virtual uint8 GetCategory(CINOSBusPort* apPort);
860  //; get category number apPort belongs to
861  virtual uint8 GetFastestCategory()
862  { return 0;};
863  //; get fastest category number
864  uint32 GetCategoryNs(CINOSBusPort* apPort);
865  //; get category ns of apPort
866  virtual uint8 GetCategory(SINOSBusPort* apPort);
867  //; get category number apPort belongs to
868  uint8 GetCategory(uint32 auCycleTimeNs, bool abAssertOnError = true);
869  //; get category of auCycleTime
870  uint32 GetCategoryNs(uint8 auCategory);
871  //; get ns of auCategory
872  uint16 GetCycleId(CINOSBusPort* apPort);
873  //; get cycle id of the port
874  uint8 GetPage(CINOSBusPort* apPort);
875  //; get page number apPort belongs to
876  uint8 GetPage(uint32 auCycleTimeNs);
877  //; get page number auCycleTimeNs belongs to
878  uint32 ConvertToNs(uint32 auValue);
879  //; convert auValue to Ns (if the value is <= 1000, we assume us if
880  //; it is > 1000 we assume ns)
881  virtual uint16 GetCycleId(const char* apName);
882  //; get cycle id of process image channel named apName
883  virtual uint32 GetCycleTimeNs(const char* apName);
884  //; get cycle time [ns] of process image channel named apName
885  virtual void Sleep(uint32 auBusTicks)
886  { ASSERT_ALWAYS(0 && "Not implemented for this bus type"); }
887  //; let the caller task sleep for auBusTicks bus ticks. If a
888  //; bus has several categories (such as ginlink), 1 bus tick
889  //; equals to the highest active category.
890  //; \param auBusTicks The amount of bus ticks to elapse until
891  //; the function returns. If a bus tick immediately occurs
892  //; after start waiting, the caller will be woken up. IOW:
893  //; if passing a value of 1 and the bus cycle time is 250us
894  //; the caller will sleep between 0..250us.
895  virtual void SleepClocked(uint32 auBusTicks)
896  { ASSERT_ALWAYS(0 && "Not implemented for this bus type"); }
897  //; let the caller task sleep until the bus tick counter
898  //; reaches a multiple of auBusTicks. If a
899  //; bus has several categories (such as ginlink), 1 bus tick
900  //; equals to the highest active category.
901  //; This can be used for simple time slice mechanisms where
902  //; e.g. every iteration of a loop is expected to take equally
903  //; long. IOW:
904  //; if passing a value of 1 and the bus cycle time is 250us
905  //; the caller will sleep between 0..250us, and more precisely
906  //; will wake up at the next 250us tick.
907 
908  virtual void FlushCache(uint8 auCategory) {};
909  //; flush cache. useful for post hooks under special conditions
910 
911  virtual CINCOObject* GetRegister();
912  //; do inco registration and return pointer to it
913 
917  virtual CINCOObject* GetModulesObj() {
918  // ensure it is created
919  GetRegister();
920  return m_pModules;
921  }
922 
927  uint8 GetCoreCount() const {
928  return m_uCores;
929  }
930 
952  INOS_INLINE void AtomicGatherEnter(uint32& ouToken) {
953  ouToken = m_uAtomicGather;
954  INOSOptimizationBarrier();
955  }
956  INOS_INLINE bool AtomicGatherExit(uint32 auToken) {
957  if (ActualTask()->GetTskType() != CINOSTask::eTskTypeRealtime) {
958  INOSOptimizationBarrier();
959  return (auToken == m_uAtomicGather) && !(m_uAtomicGather & 0x000000FF);
960  } else {
961  // never block a bus task, especially not yourself
962  return true;
963  }
964  }
965 
970  bool IsWatchdogPending(uint8 auCategory)
971  {
972  // yes if watchdog count >= watchdog level
973  return m_CatInfo[auCategory].m_uWatchdogCount >= m_CatInfo[auCategory].m_uWatchdogLevel;
974  }
975 
976  //--- internals --------------------------------------------------------
977 
978  friend class CINOSBusJob;
979  friend class CINOSBusModule;
980  friend class CINOSBusChannelHandler;
981  friend class CINOSBits;
982  friend class CINOSAdcChannels;
983  friend class CINOSDacChannels;
984  friend class CINOSPosChannels;
985  friend class CINOSProcessImageChannel;
986  friend class CINOSTaskEx;
987  friend class CGINModuleIMP;
988  friend void _INI_0399_CINOSBus();
989  friend void _INI_0500_CINOSBus();
990 
991  // protected members
992  protected :
993  SINOSBus* m_pDesc; // pointer to bus descriptor
994  uint32 m_uState; // bus state
995  uint32 m_uError; // bus errors
996  uint32 m_uErrorMask; // bus error mask
997  uint32 m_uHeartBeat; // bus heart beat
998  char m_cStateMsg[32]; // bus state message
999  uint32 m_uMainCycleTime; // main cycle time [us]
1000  uint32 m_uMainCycleTimeNs; // main cycle time [ns]
1001  uint32 m_uSubCycleTime; // sub cycle time [us]
1002  uint32 m_uSubCycleTimeNs; // sub cycle time [ns]
1003  uint16 m_uSubCycles; // number of sub cycles
1004  int16 m_iActCycle; // number of actual cycle
1006  uint8 m_uCores = 1;
1007  uint32 m_uErrorCounter; // field bus error counter
1008  CINOSBusModule* m_pFirst; // pointer to first module in list
1009  uint32 m_uJobs; // number of jobs in array of job pointers
1010  uint32 m_uJobsMax; // max. number of jobs in array of job pointers
1011  CINOSBusJob** m_pJobs; // pointer to array of job pointers
1012  uint32 m_uIndexes; // number of vertical indexes
1013  uint16* m_pIndexes; // pointer to 2 dim array of job indexes
1014  uint16 m_uVirtualCycleIndex; // actual virtual cycle index
1018  class CINOSBusChannelHandler* m_pChnHnd = nullptr;
1019 
1020  // inco registration
1021  static CINCOObject* m_pFieldBus; // inco registration 'FieldBus'
1022  CINCOObject* m_pRegister; // inco registration 'Bus'
1023  CINCOObject* m_pModules; // inco registration 'Bus.Modules'
1024  CINCOObject* m_pTiming; // inco registration 'Bus.Timing'
1025  CINCOObject* m_pHooks{}; // inco registration 'Bus.hooks'
1026 
1027  CINOSTask* m_pPostTask;
1028  enum {
1029  eMainHooks = 0,
1030  ePostHooks = 1,
1031  eErrorHooks = 2,
1032  };
1033  CINOSBusHooks m_Hooks{eMainHooks};
1034  CINOSBusHooks m_PostHooks{ePostHooks};
1035  CINOSBusHooks m_ErrorHooks{eErrorHooks};
1036 
1037  // eeprom handling
1038  void* m_pEepromBuffer; // pointer to eprom buffer (with size
1039  // of m_uMaxEepromSize bytes)
1040  // contact module
1041  uint32 m_uContactAdr; // contact module address
1042  uint32 m_uContactDat; // contact module data
1043  uint32 m_uContactRet; // contact module return value
1044 
1045  // additional bus info
1046  SINOSBusInfo m_Info{};
1047  // additional bus per category. The array lenght is the "longer" of
1048  // DF_INOS_BUS_MAX_SUB_CYCLES and DF_INOS_BUS_MAX_CATEGORY, as the
1049  // array is used by both, category based and subcycle based busses,
1050  // such as GinLink and InfoLink.
1052 
1053  // pointer to list of rec bus handlers (single core)
1054  SINOSBusHandlerBuffer* m_pRecHnd[DF_INOS_BUS_MAX_CATEGORY];
1055  // pointer to list of rec bus handlers (multi core)
1056  SINOSBusHandlerBuffer* m_pRecHndM[DF_INOS_MAX_CORES][DF_INOS_BUS_MAX_CATEGORY][DF_INOS_BUS_MAX_CYCLE_NUMBER];
1057  // pointer to list of tra bus handlers (single core)
1058  SINOSBusHandlerBuffer* m_pTraHnd[DF_INOS_BUS_MAX_CATEGORY];
1059  // pointer to list of rec bus handlers (multi core)
1060  SINOSBusHandlerBuffer* m_pTraHndM[DF_INOS_MAX_CORES][DF_INOS_BUS_MAX_CATEGORY][DF_INOS_BUS_MAX_CYCLE_NUMBER];
1061 
1062  // ticks
1063  uint64 m_uTickCount; // actual tick count
1064  uint64 m_uTimebase; // actual cpu timebase at last tick
1065 
1066  // virtual address handling
1067  CINOSMutex m_VirtualAddressMutex;
1068  uint32 m_uVirtualAddressMask[8] = {0};
1069  uint8 m_uVirtualAddressCounter = DF_INOS_BUS_MOD_VADDR_MIN;
1070 
1071 
1072  friend class CINOSMcTargetKernelLogger;
1073  // tasklog trigger for overruns
1074  enum {
1075  eTskLogTriggerOverrun = 0x01,
1076  eTskLogTriggerPostOverrun = 0x02,
1077  };
1078  uint8 m_uTasklogTriggerFlags{};
1079  uint8 m_uTasklogTriggerPercent{50};
1080  void EnableTasklogTriggerOverrun(uint8 auPercent)
1081  {
1082  m_uTasklogTriggerFlags |= eTskLogTriggerOverrun;
1083  m_uTasklogTriggerPercent = auPercent;
1084  }
1085  void DisableTasklogTriggerOverrun()
1086  {
1087  m_uTasklogTriggerFlags &= ~eTskLogTriggerOverrun;
1088  }
1089  void EnableTasklogTriggerPostOverrun(uint8 auPercent)
1090  {
1091  m_uTasklogTriggerFlags |= eTskLogTriggerPostOverrun;
1092  m_uTasklogTriggerPercent = auPercent;
1093  }
1094  void DisableTasklogTriggerPostOverrun()
1095  {
1096  m_uTasklogTriggerFlags &= ~eTskLogTriggerPostOverrun;
1097  }
1098 
1099  // bus syncing
1100  enum {
1101  eBusSyncOff,
1102  eBusSyncOk,
1103  eBusSyncAccelerate,
1104  eBusSyncDecelerate
1105  } m_eBusSync = eBusSyncOff;
1106  enum EBusSyncType {
1107  eBusSyncNone = 0,
1108  eBusSyncMaster = 1,
1109  eBusSyncToMaster = 2,
1110  eBusSyncToUTC = 3
1111  } m_eBusSyncType = eBusSyncNone;
1112  enum {
1113  eBusSyncFilterLength = 16,
1114  eBusSyncFilterShift = 4,
1115  eBusSyncFilterMask = eBusSyncFilterLength-1,
1116  };
1118  uint8 m_uBusSyncIndex = 0;
1120  int32 m_iBusSyncFilter[eBusSyncFilterLength] = {0};
1121  int32 m_iBusSyncFilterSum = 0;
1122  int32 m_iBusSyncDelta = 0;
1123  uint32 m_uBusSyncOffset = 0;
1124  int32 m_iBusSyncTolerance = DF_INOS_BUS_SYNCTOLERANCE_DEFAULT;
1126  uint32 m_uBusSyncOk = 0;
1132  static uint64 m_uBusSyncMaster;
1133  void SyncBusOn();
1134  void SyncBusOff();
1135 
1137  uint8 VirtualAddressAlloc();
1139  void VirtualAddressFree(uint8 auAddress);
1141  bool VirtualAddressCheck(uint8 auAddress);
1142 
1143  // creation
1144  public :
1145  explicit CINOSBus(SINOSBus* apDesc);
1146  //; inos bus constructor
1147  virtual ~CINOSBus();
1148 
1149  // public members but just for internal use)
1150  public :
1151  virtual uint32 SetState(uint32 auState);
1152  //; set bus state and state message and return stae before
1153  void SetHeartBeat(uint32 auHeartBeat)
1154  {m_uHeartBeat = auHeartBeat;};
1155  //; set bus heart beat
1156  uint32 GetVirtualCycleIndex();
1157  //; return auto generated virtual cycle index
1158  virtual void Add(CINOSBusModule* apModule);
1159  //; add inos bus module
1160  virtual void Remove(CINOSBusModule* apModule);
1161  //; remove inos bus module
1162  virtual void RemoveAll();
1163  //; remove all modules
1164  virtual void Scan(){};
1165  //; scan field bus
1166  virtual void Prepare();
1167  //; prepare field bus jobs
1168  virtual void PostPrepare();
1169  //; called after field bus prepare
1170  virtual void Initialyse();
1171  //; initialyse field bus
1172  virtual bool InitDone();
1173  //; return true if initialisation of bus is done
1174  virtual bool IsDynamic()
1175  { return false;};
1176  //; return true if startup sequence is dynamic
1177  virtual bool IsCategoryBased()
1178  { return false;};
1179  //; return true if bus is category based (e.g. ginlink)
1180 
1181  // protected member functions
1182  protected :
1183  uint32 GetRealCycleIndex(uint32 auVirtualCycle);
1184  //; return real cycle index of virtual index auVirtualCycle
1185  void SortJobs();
1186  //; do job sort
1187 
1188  // eeprom handling routines
1189 
1190  void* RequestEepromBuffer();
1191  //; get pointer to eeprom buffer
1192  void ReleaseEepromBuffer(void* apBuffer);
1193  //; release pointer to eeprom buffer
1194 
1195  void HandleDownSampling();
1196  //; handle down sampling
1197  SINOSBusHandlerBuffer* HandlerBufferPrepare(SINOSBusHandlerBuffer*& apBuffer);
1198  //; prepare buffer handler
1199  void HandlerBufferDone(SINOSBusHandlerBuffer*& apBuffer, SINOSBusHandlerBuffer* apNew);
1200  //; set new handler buffer pointer
1201  bool HandlerBufferEqualContent(SINOSBusHandlerBuffer* apBuffer1, SINOSBusHandlerBuffer* apBuffer2);
1202  //; compare two buffers
1203  void HandlerBufferSetup();
1204  //; setup all rec and tra handler lists
1205  void HandlerBufferSetupRec(uint8 auCategory=0);
1206  //; setup receive data
1207  ICACHE void HandleRecData(uint8 auCategory=0);
1208  //; handle receive data
1209  void HandlerBufferSetupRecM(uint16 auCycleId);
1210  //; setup receive data (multicore)
1211  ICACHE void HandleRecDataM(uint16 auCycleId);
1212  //; handle receive data (multicore)
1213  void HandlerBufferSetupTra(uint8 auCategory=0);
1214  //; setup trans data
1215  ICACHE void HandleTraData(uint8 auCategory=0);
1216  //; handle trans data
1217  void HandlerBufferSetupTraM(uint16 auCycleId);
1218  //; setup trans data (multicore)
1219  ICACHE void HandleTraDataM(uint16 auCycleId);
1220  //; handle trans data (multicore)
1221  static void HandleRecBuffer(SINOSBusHandlerBuffer* apHnd);
1222  //; handle rec port handler list
1223  static void HandleTraBuffer(SINOSBusHandlerBuffer* apHnd);
1224  //; handle tra port handler list
1225  ICACHE void HandleHooks(uint8 auCategory = 0);
1226  //; handle inos bus hooks
1227  ICACHE void HandlePostHooks(uint8 auCategory = 0, bool abWakeupPostTask = true);
1228  //; handle inos bus post hooks
1229  void iHandlePostHooks();
1230  //; handle inos bus post hooks
1231  virtual uint32 iRegisterHook(uintid& auHookId, CINOSBusHooks& aHooks, void* apHandler, void* apObject,
1232  uint32 auCycleTime, uint16 auCycleId, int32 aiOrder, uint32 auFlags);
1233  virtual void iiHandlePostHooks();
1234  //; handle inos bus post hooks
1235 
1236  // cpu load measurement
1237  void Measure();
1238  //; measure cpu load (from task Resume till now)
1239 
1240  void SetError(uint32 auErrors);
1241  //; set bus error (and call error hook if nessecary)
1242 
1243  void RegisterHooks();
1244 
1250  // increment task and update counter
1251  INOS_ADD(m_uAtomicGather, 0x00000101);
1252  }
1253  INOS_INLINE void AtomicGatherEndUpdate() {
1254  // decrement task counter
1255  INOS_ADD(m_uAtomicGather, -0x00000001);
1256  }
1257 
1258  // protected members
1259  protected :
1269  uint32 m_uAtomicGather = 0x00000000;
1270 
1271  // public members but just for internal use)
1272  public :
1274  uint32 GetChannelBase(uint16 auAddress);
1276  uint32 GetBitBase(uint16 auAddress);
1277 
1278  // processimage channel conflict supervision
1279  protected :
1283  static bool m_bChkEnabled;
1285  static bool m_bChkPermanent;
1287  static uint8 m_uChkBusId;
1289  struct SCheck {
1290  uint32 m_uMin;
1291  uint32 m_uMax;
1292  CINOSTask* m_pTsk;
1293  };
1294  static SCheck m_Chk[DF_INOS_BUS_MAX_NUMBER];
1296  static void EnbCheck(bool abEnable)
1297  { m_bChkEnabled = abEnable; };
1299  static void ModSetup(uint8 auBusId);
1301  static void ChnCreate(uint32 auNumber);
1303  static void ConflictCheck();
1305  static void PermanentCheck()
1306  { m_bChkPermanent = true; };
1307 };
1308 
1309 //------------------------------------------------------------------------------
1310 // class CINOSBusRegister
1311 //------------------------------------------------------------------------------
1312 
1313 typedef CINOSBus* (*TCreateBus)(SINOSBus* apDesc);
1314 
1316 {
1317  friend void _INI_0000_CINOSBusRegister();
1318 
1319  //--- internals --------------------------------------------------------
1320 
1321  // private members
1322  private:
1323  // pointer to the first registered inos bus
1324  static CINOSBusRegister* m_pFirst;
1325  // pointer to the next inos bus
1326  CINOSBusRegister* m_pNext;
1327  // create funtion for the inos bus
1328  TCreateBus m_pCreate;
1329  // bus type name
1330  const char* m_pBusType;
1331  // database table name
1332  const char* m_pDatabaseTable;
1333 
1334  //--- user interface ---------------------------------------------------
1335 
1336  public:
1337  // register a new inos bus of type apType
1338  CINOSBusRegister(TCreateBus apCreate, const char* apBusType,
1339  const char* apDatabaseTable);
1340 
1341  // create and return a new inos bus instance
1342  static CINOSBus* GetBus(SINOSBus* apDesc);
1343  // create all registered busses
1344  static void CreateAll();
1345 };
1346 
1347 //------------------------------------------------------------------------------
1348 // class CINOSDeviceMap
1349 //------------------------------------------------------------------------------
1350 
1352 {
1353  #ifdef INOSV
1354  friend uint32 _INI_0201_CDEVICE_MAP_();
1355  #else
1356  friend void _INI_0201_CDEVICE_MAP_();
1357  #endif
1358  public:
1359 
1360  // Type declaration
1361 
1363  enum EError {
1364  eErrOk = 0,
1365  eErrDeviceNotFound = 1,
1366  eErrDeviceTypeNotSupported = 2,
1367  eErrResultBufferTooSmall = 3,
1368  eErrDeviceNoAddress = 4,
1369  eErrDeviceNoName = 5,
1370  };
1371 
1374  eDevDontCare = 0,
1375  eDevGin,
1376  eDevTypeLast
1377  };
1378 
1379 
1380  static EError GetDeviceAddress(const char* apName, char* apResult, uint32 auBufferLength);
1381  static EError GetDeviceAddress(const char* apName, uint32& auResult);
1382  static EError GetDeviceName(uint32 auAddress, char* apResult, uint32 auBufferLength);
1383  static EError GetDeviceNode(const char* apName, XMLNode& axResult);
1384  static EError GetDeviceNode(uint32 auAddress, XMLNode& axResult);
1385 
1386  static EError GetDeviceUid(uint64 auMacAddress, uint32 auDeviceAddress, uint32& auUid);
1387  static EError GetDeviceUid(XMLNode& aNode, uint64 auMacAddress, uint32 auDeviceAddress, uint32& auUid);
1388  static EError GetDeviceUid(uint64 auMacAddress, uint32 auProductCode, uint8 auIndex, uint32& auUid);
1389  static EError GetDeviceUid(XMLNode& aNode, uint64 auMacAddress, uint32 auProductCode, uint8 auIndex, uint32& auUid);
1390  static EError GetDevicePathByUid(uint32 auUid, char* apResult, uint32 auBufferLength);
1391 
1392  static EError GetDeviceName(XMLNode& aNode, uint32 auUid, char* apResult, uint32 auLength);
1393 
1394  private:
1395  static XMLNode m_sxDevices;
1396 
1397 };
1398 
1399 //
1400 //------------------------------------------------------------------------------
1401 // class CINCOpercent
1402 //------------------------------------------------------------------------------
1403 template <typename T>
1404 class CINCOpercent : public CINCOdouble
1405 {
1406  // constructor
1407  public:
1408  CINCOpercent(char* apName, T* apData)
1409  : CINCOdouble(apName, apData, 0, 0, "%", defCharShowFix + SHOW_DIGIT(2) + defCharReadOnly)
1410  {
1411  }
1412 
1413  // public member functions
1414  public:
1415  // item address = (long) pData + aIndex*sizeof(item) + aOffset
1416  virtual long Get(void* apDest, long& maxLength, long aIndex, long aOffset) override {
1417  // do we have already a pointer
1418  if (!pData) {
1419  // no
1420  *((double *) apDest) = 0;
1421  return 0;
1422  }
1423  else {
1424  // convert ticks to us
1425  T* pTiming = (T*) ((uintptr) pData + aIndex*GetConfig()->GetSize() + aOffset);
1426  double p = double(pTiming->m_uMax * 100) / double(pTiming->m_uAllowed);
1427  *((double *) apDest) = p;
1428  }
1429 
1430  // ok
1431  return 0;
1432  // end CINCOpercent::Get
1433  }
1434 };
1435 
1443 void SleepBusTicks(uint32 auBusTicks, uint32 auBusId = 0);
1444 
1445 //
1446 //------------------------------------------------------------------------------
1447 // global variables
1448 //------------------------------------------------------------------------------
1449 //
1450 extern CINOSBus* g_pBus[DF_INOS_BUS_MAX_NUMBER];
1451 extern CINOSBus* g_pBus2[DF_INOS_BUS_MAX_NUMBER];
1452 extern uint32 g_uBusIndex;
1453 //
1454 //------------------------------------------------------------------------------
1455 // end of file
1456 //------------------------------------------------------------------------------
1457 
1458 #endif // INC_CINOSBUS_H
CINOSDacChannels
Definition: cinosdacchannels.h:76
CINOSBus::m_uBusSyncOk
uint32 m_uBusSyncOk
bus sync ok counter
Definition: cinosbus.h:1126
CINOSMutex
Definition: cinosmutex.h:35
CINOSBus
Definition: cinosbus.h:564
CINOSBus::ModSetup
static void ModSetup(uint8 auBusId)
inform the system about a bus module setup
ActualTask
CINOSTask * ActualTask()
cinosbushooks.h
The CINOSBusHook class.
SINOSBusHandlerPort
Definition: cinosbus.h:284
SINOSCatInfo::m_uCycleTimeCat
uint32 m_uCycleTimeCat
cycletime category
Definition: cinosbus.h:489
CINOSBus::ChnCreate
static void ChnCreate(uint32 auNumber)
inform the system about a process image channel creation
CINOSBus::PermanentCheck
static void PermanentCheck()
switch on permanent check
Definition: cinosbus.h:1305
SINOSBus
Definition: cinosbus.h:204
CINOSBusHooks
Definition: cinosbushooks.h:478
SINOSBusHandlerBuffer::m_uTemporary
uint32 m_uTemporary[2]
temporary data
Definition: cinosbus.h:398
SINOSBusHandler
Definition: cinosbus.h:276
SINOSBusHandlerCall::m_uParam
uint32 m_uParam
parameter
Definition: cinosbus.h:297
CINOSBus::m_uBusSyncMaster
static uint64 m_uBusSyncMaster
master sync time stamp
Definition: cinosbus.h:1132
DF_INOS_MAX_CORES
#define DF_INOS_MAX_CORES
Definition: inosdefine.h:164
SINOSBusInfoHook
Definition: cinosbus.h:411
CINOSDeviceMap::EDeviceType
EDeviceType
Error type.
Definition: cinosbus.h:1373
SINOSBusHandlerCall
Definition: cinosbus.h:290
CINOSBus::AddBus
static void AddBus(uint32 auId, CINOSBus *apBus)
Add a new bus to the handled busses.
SINOSBusPostTiming
Definition: cinosbus.h:468
DF_INOS_BUS_INFO_MAX_HOOKS
#define DF_INOS_BUS_INFO_MAX_HOOKS
Definition: inosdefault.h:526
CINOSBus::ConflictCheck
static void ConflictCheck()
check for possible conflicts
CINOSBus::VirtualAddressAlloc
uint8 VirtualAddressAlloc()
allocate virtual module address
INOS_INLINE
#define INOS_INLINE
Definition: inosdefine.h:60
CINOSBits
Definition: cinosbits.h:72
CINOSBus::EnableHook
uint32 EnableHook(uintid auHookId)
Enable hook with given id.
DF_INOS_BUS_HOOK_ORDER_DEFAULT
#define DF_INOS_BUS_HOOK_ORDER_DEFAULT
bus hook order 'default'
Definition: cinosbus.h:139
CINOSBus::UnRegisterPostHook
virtual uint32 UnRegisterPostHook(uintid auHookId)
Unregister post hook with given id.
SINOSBusInfo
Definition: cinosbus.h:501
CINOSBus::m_uBusSyncAccelerate
uint32 m_uBusSyncAccelerate
bus sync accelerate counter
Definition: cinosbus.h:1128
CINOSDeviceMap
Definition: cinosbus.h:1351
SleepBusTicks
void SleepBusTicks(uint32 auBusTicks, uint32 auBusId=0)
CINOSBus::UnRegisterHook
virtual uint32 UnRegisterHook(uintid auHookId)
Unregister hook with given id.
SINOSBusTiming
Definition: cinosbus.h:426
CINOSBus::RegisterHook
virtual uint32 RegisterHook(uintid &auHookId, void *apHandler, void *apObject=0, uint32 auCycleTime=0, uint16 auCycleId=(0xffff), int32 aiOrder=20, uint32 auFlags=CINOSBusHook::eFlgEnabled)
Register hook and return hook id. The registered function will be called in the context of the corres...
CINOSPosChannels
Definition: cinosposchannels.h:81
SINOSBusHandlerPort::m_uAddress
uintptr m_uAddress
pointer to port
Definition: cinosbus.h:287
CINOSAdcChannels
Definition: cinosadcchannels.h:77
CINOSTaskEx
Definition: cinostaskex.h:965
CINOSBus::GetHookCycleTime
uint32 GetHookCycleTime(uintid auHookId)
Get cycle time of given hook.
CINOSBus::m_ChnCheck
static CINOSMutex m_ChnCheck
check mutex
Definition: cinosbus.h:1281
DF_INOS_BUS_MOD_VADDR_MIN
#define DF_INOS_BUS_MOD_VADDR_MIN
min. allowed virtual address
Definition: cinosbusmoduledef.h:40
SINOSBusHandlerCall::m_pMethod
void * m_pMethod
pointer to method
Definition: cinosbus.h:295
CINOSBus::VirtualAddressFree
void VirtualAddressFree(uint8 auAddress)
free virtual module address
CINOSBus::AtomicGatherEnter
INOS_INLINE void AtomicGatherEnter(uint32 &ouToken)
Definition: cinosbus.h:952
SBusSleeper::m_bClocked
bool m_bClocked
Definition: cinosbus.h:538
SBusSleeper::m_uBusTicks
uint32 m_uBusTicks
Definition: cinosbus.h:536
CINOSBus::m_iBusSyncFilter
int32 m_iBusSyncFilter[eBusSyncFilterLength]
bus sync delta [ns]
Definition: cinosbus.h:1120
SBusSleeper::AddSleeper
static void AddSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
CINOSBus::s_pFirstBus
static CINOSBus * s_pFirstBus
Pointer to first valid bus, cached for faster access of "g_pBus[0]".
Definition: cinosbus.h:1016
CINOSBus::m_uBusSyncIndex
uint8 m_uBusSyncIndex
bus sync index
Definition: cinosbus.h:1118
SINOSBusHandlerBuffer
Definition: cinosbus.h:300
INOS_ADD
#define INOS_ADD(variable, value)
Definition: inosmacro.h:220
CINOSBus::GetModulesObj
virtual CINCOObject * GetModulesObj()
Return root registration object of modules.
Definition: cinosbus.h:917
SBusSleeper::m_pSync
CINOSSync m_pSync
Definition: cinosbus.h:533
CINOSBus::m_uAtomicGather
uint32 m_uAtomicGather
Definition: cinosbus.h:1269
CINOSDeviceMap::EError
EError
Error type.
Definition: cinosbus.h:1363
CINOSBus::GetBitBase
uint32 GetBitBase(uint16 auAddress)
get bit channel base number of module auAddress
SINOSBusHandler::m_uCommand
uint8 m_uCommand
command
Definition: cinosbus.h:279
CINOSBus::GetType
const char * GetType()
Get bus type, used for consistency checks.
Definition: cinosbus.h:783
CINOSBus::GetCoreCount
uint8 GetCoreCount() const
Definition: cinosbus.h:927
SINOSBusHandlerBuffer::m_uWriteIndex
uint32 m_uWriteIndex
actual write buffer
Definition: cinosbus.h:396
SINOSBusTiming::m_uCatActCycle
uint16 m_uCatActCycle
category based act cycle
Definition: cinosbus.h:428
CINOSBus::GetChannelBase
uint32 GetChannelBase(uint16 auAddress)
get channel base number of module auAddress
CINOSBus::RegisterErrorHook
uint32 RegisterErrorHook(uintid &auHookId, void *apHandler, void *apObject=0)
Register error hook and return hook id. The registered function will be called in the context of the ...
SINOSCatInfo::m_uWatchdogLevel
uint32 m_uWatchdogLevel
watchdog level
Definition: cinosbus.h:495
CINOSBus::m_uCores
uint8 m_uCores
actual number of cores used
Definition: cinosbus.h:1006
CINOSProcessImageChannel
Definition: cinosprocessimagechannel.h:110
CINOSBus::SetHookHandler
uint32 SetHookHandler(uintid auHookId, void *apHandler)
Set handler of given hook.
CINOSBus::VirtualAddressCheck
bool VirtualAddressCheck(uint8 auAddress)
check virtual module address
CINOSBus::m_pChnHnd
class CINOSBusChannelHandler * m_pChnHnd
pointer to bus channel handler (if any)
Definition: cinosbus.h:1018
CINOSBus::IsWatchdogPending
bool IsWatchdogPending(uint8 auCategory)
Return true if fieldbus watchdog pending of the given category.
Definition: cinosbus.h:970
CINOSBus::IsBusTask
virtual bool IsBusTask(CINOSTask *apTask)
get bus number of module with given address
Definition: cinosbus.h:585
CINOSBus::GetFirstBusId
static uint8 GetFirstBusId()
Return the id of the first valid bus, or 0 if none available.
CINOSTask::GetTskType
INOS_INLINE ETskType GetTskType()
Get task type.
Definition: cinostask.h:201
SBusSleeper::RemoveSleeper
static void RemoveSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
CINOSBus::GetHookHandler
void * GetHookHandler(uintid auHookId)
Get handler of given hook.
SBusSleeper::s_uClockedTickCount
static uint64 s_uClockedTickCount
Definition: cinosbus.h:542
CINOSBus::EnbCheck
static void EnbCheck(bool abEnable)
enable/disable channel check
Definition: cinosbus.h:1296
CINOSBus::GetHookCycleNumber
uint8 GetHookCycleNumber(uintid auHookId)
Get cycle number of given hook.
CINOSBus::SCheck
bus min/max channel numbers
Definition: cinosbus.h:1289
CINOSBus::GetFirstBus
static CINOSBus * GetFirstBus()
Return first valid bus (aka "g_pBus[0]").
Definition: cinosbus.h:606
INOS_CYCLEID_DONT_CARE
#define INOS_CYCLEID_DONT_CARE
don't care cycle id
Definition: cinosbus.h:174
CINOSSync
Definition: inos_syn.h:66
SINOSBusHandlerCall::m_pObject
void * m_pObject
pointer to object
Definition: cinosbus.h:293
CINOSBus::AtomicGatherBeginUpdate
INOS_INLINE void AtomicGatherBeginUpdate()
Definition: cinosbus.h:1249
CINCOpercent
Definition: cinosbus.h:1404
CINOSBus::m_uChkBusId
static uint8 m_uChkBusId
current bus id
Definition: cinosbus.h:1287
SINOSBusTiming::m_uHooks
std::atomic< uint32 > m_uHooks
number of bus hook
Definition: cinosbus.h:439
CINOSBus::RegisterPostHook
virtual uint32 RegisterPostHook(uintid &auHookId, void *apHandler, void *apObject=0, uint32 auCycleTime=0, uint16 auCycleId=(0xffff), int32 aiOrder=20, uint32 auFlags=CINOSBusHook::eFlgEnabled)
Register post hook and return hook id. The registered function will be called in the context of the c...
SBusSleeper
Definition: cinosbus.h:526
CINOSBus::DisableHook
uint32 DisableHook(uintid auHookId)
Enable hook with given id.
CINOSBus::m_bChkEnabled
static bool m_bChkEnabled
check active
Definition: cinosbus.h:1283
SINOSCatInfo::m_uWatchdogCountMax
uint32 m_uWatchdogCountMax
watchdog counter max
Definition: cinosbus.h:493
CINOSBusRegister
Definition: cinosbus.h:1315
SBusSleeper::m_pNext
SBusSleeper * m_pNext
Definition: cinosbus.h:540
CINOSBus::m_uBusSyncDecelerate
uint32 m_uBusSyncDecelerate
bus sync decelerate counter
Definition: cinosbus.h:1130
CINOSBus::UnRegisterErrorHook
uint32 UnRegisterErrorHook(uintid auHookId)
Unregister error hook with given id.
SINOSBusHandlerBuffer::m_cData
char m_cData[0x4000-3 *sizeof(uint32)]
Definition: cinosbus.h:404
DF_INOS_BUS_MAX_SUB_CYCLES
#define DF_INOS_BUS_MAX_SUB_CYCLES
Definition: inosdefault.h:383
SINOSBusPostTiming::m_uPostHooks
uint32 m_uPostHooks
number of bus post hooks
Definition: cinosbus.h:477
ASSERT_ALWAYS
#define ASSERT_ALWAYS(f)
Definition: inosmacro.h:696
SINOSCatInfo
Definition: cinosbus.h:487
SINOSCatInfo::m_uWatchdogCount
uint32 m_uWatchdogCount
watchdog counter
Definition: cinosbus.h:491
SBusSleeper::HandleSleepers
static void HandleSleepers(SBusSleeper *&apFirstSleeper)
CINOSBus::m_bChkPermanent
static bool m_bChkPermanent
permanent check
Definition: cinosbus.h:1285
CINOSTask
Definition: cinostask.h:51
SINOSBusHandler::m_uReserved
uint8 m_uReserved[sizeof(uintptr) -1]
reserved
Definition: cinosbus.h:281