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