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
178#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//
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{
279 uint8 m_uReserved[sizeof(uintptr)-1];
280};
281//
283{
285 uintptr m_uAddress;
286};
287//
289{
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[0x8000-3*sizeof(uint32)];
401 #else
402 char m_cData[0x4000-3*sizeof(uint32)];
403 #endif
404 // allow dynamic handling
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
419};
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
441 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
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
476
477 #ifdef INOS_ADDITIONAL_BUS_TIME_MEASUREMENTS
479 #endif
480
481 // allow dynamic handling
483};
484//
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//
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
519};
525 enum EReservedCounts {
526 eAlreadySignaled = 0
527 };
528 SBusSleeper(uint32 auBusTicks, bool abClocked = false);
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//
559struct SINOSBusPort;
560class CINOSBusPort;
561class CINOSBusModule;
562class 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 };
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
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
1311typedef 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//------------------------------------------------------------------------------
1401template <typename T>
1402class 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
1441void SleepBusTicks(uint32 auBusTicks, uint32 auBusId = 0);
1442
1443//
1444//------------------------------------------------------------------------------
1445// global variables
1446//------------------------------------------------------------------------------
1447//
1448extern CINOSBus* g_pBus[DF_INOS_BUS_MAX_NUMBER];
1449extern CINOSBus* g_pBus2[DF_INOS_BUS_MAX_NUMBER];
1450extern uint32 g_uBusIndex;
1451//
1452//------------------------------------------------------------------------------
1453// end of file
1454//------------------------------------------------------------------------------
1455
1456#endif // INC_CINOSBUS_H
#define INOS_CYCLEID_DONT_CARE
don't care cycle id
Definition cinosbus.h:172
#define DF_INOS_BUS_HOOK_ORDER_DEFAULT
bus hook order 'default'
Definition cinosbus.h:137
void SleepBusTicks(uint32 auBusTicks, uint32 auBusId=0)
The CINOSBusHook class.
#define DF_INOS_BUS_MOD_VADDR_MIN
min. allowed virtual address
Definition cinosbusmoduledef.h:40
#define DECLARE_DYNAMIC(aClass)
Definition cinospartitionmemory.h:328
Definition cinosbus.h:1403
Definition cinosadcchannels.h:78
Definition cinosbits.h:73
Definition cinosbushooks.h:479
Definition cinosbus.h:1314
Definition cinosbus.h:563
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...
INOS_INLINE void AtomicGatherEnter(uint32 &ouToken)
Definition cinosbus.h:950
static CINOSMutex m_ChnCheck
check mutex
Definition cinosbus.h:1279
static uint8 GetFirstBusId()
Return the id of the first valid bus, or 0 if none available.
INOS_INLINE void AtomicGatherBeginUpdate()
Definition cinosbus.h:1247
void VirtualAddressFree(uint8 auAddress)
free virtual module address
static CINOSBus * s_pFirstBus
Pointer to first valid bus, cached for faster access of "g_pBus[0]".
Definition cinosbus.h:1014
static void EnbCheck(bool abEnable)
enable/disable channel check
Definition cinosbus.h:1294
virtual uint32 UnRegisterHook(uintid auHookId)
Unregister hook with given id.
bool IsWatchdogPending(uint8 auCategory)
Return true if fieldbus watchdog pending of the given category.
Definition cinosbus.h:968
uint32 GetHookCycleTime(uintid auHookId)
Get cycle time of given hook.
virtual CINCOObject * GetModulesObj()
Return root registration object of modules.
Definition cinosbus.h:915
int32 m_iBusSyncFilter[eBusSyncFilterLength]
bus sync delta [ns]
Definition cinosbus.h:1118
static CINOSBus * GetFirstBus()
Return first valid bus (aka "g_pBus[0]").
Definition cinosbus.h:604
uint8 GetHookCycleNumber(uintid auHookId)
Get cycle number of given hook.
uint32 GetChannelBase(uint16 auAddress)
get channel base number of module auAddress
static uint8 m_uChkBusId
current bus id
Definition cinosbus.h:1285
uint32 m_uBusSyncOk
bus sync ok counter
Definition cinosbus.h:1124
virtual bool IsBusTask(CINOSTask *apTask)
get bus number of module with given address
Definition cinosbus.h:583
uint32 DisableHook(uintid auHookId)
Enable hook with given id.
static bool m_bChkEnabled
check active
Definition cinosbus.h:1281
uint32 m_uAtomicGather
Definition cinosbus.h:1267
uint8 m_uBusSyncIndex
bus sync index
Definition cinosbus.h:1116
static void ChnCreate(uint32 auNumber)
inform the system about a process image channel creation
static void AddBus(uint32 auId, CINOSBus *apBus)
Add a new bus to the handled busses.
bool VirtualAddressCheck(uint8 auAddress)
check virtual module address
static void ModSetup(uint8 auBusId)
inform the system about a bus module setup
static uint64 m_uBusSyncMaster
master sync time stamp
Definition cinosbus.h:1130
uint32 m_uBusSyncAccelerate
bus sync accelerate counter
Definition cinosbus.h:1126
uint32 EnableHook(uintid auHookId)
Enable hook with given id.
class CINOSBusChannelHandler * m_pChnHnd
pointer to bus channel handler (if any)
Definition cinosbus.h:1016
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 ...
uint8 VirtualAddressAlloc()
allocate virtual module address
uint32 GetBitBase(uint16 auAddress)
get bit channel base number of module auAddress
static void ConflictCheck()
check for possible conflicts
uint32 m_uBusSyncDecelerate
bus sync decelerate counter
Definition cinosbus.h:1128
static void PermanentCheck()
switch on permanent check
Definition cinosbus.h:1303
uint8 m_uCores
actual number of cores used
Definition cinosbus.h:1004
void * GetHookHandler(uintid auHookId)
Get handler of given hook.
const char * GetType()
Get bus type, used for consistency checks.
Definition cinosbus.h:781
uint32 UnRegisterErrorHook(uintid auHookId)
Unregister error hook with given id.
virtual uint32 UnRegisterPostHook(uintid auHookId)
Unregister post hook with given id.
uint32 SetHookHandler(uintid auHookId, void *apHandler)
Set handler of given hook.
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...
static bool m_bChkPermanent
permanent check
Definition cinosbus.h:1283
uint8 GetCoreCount() const
Definition cinosbus.h:925
Definition cinosdacchannels.h:77
Definition cinosbus.h:1350
EDeviceType
Error type.
Definition cinosbus.h:1371
EError
Error type.
Definition cinosbus.h:1361
Definition cinosmutex.h:36
Definition cinosposchannels.h:82
Definition cinosprocessimagechannel.h:111
Definition inos_syn.h:67
Definition cinostaskex.h:966
Definition cinostask.h:52
INOS_INLINE ETskType GetTskType()
Get task type.
Definition cinostask.h:201
CINOSTask * ActualTask()
#define DF_INOS_BUS_INFO_MAX_HOOKS
Definition inosdefault.h:518
#define DF_INOS_BUS_MAX_SUB_CYCLES
Definition inosdefault.h:375
#define INOS_INLINE
Definition inosdefine.h:60
#define DF_INOS_MAX_CORES
Definition inosdefine.h:164
#define ASSERT_ALWAYS(f)
Definition inosmacro.h:696
#define INOS_ADD(variable, value)
Definition inosmacro.h:220
bus min/max channel numbers
Definition cinosbus.h:1287
Definition cinosbus.h:524
uint32 m_uBusTicks
Definition cinosbus.h:534
CINOSSync m_pSync
Definition cinosbus.h:531
static uint64 s_uClockedTickCount
Definition cinosbus.h:540
static void AddSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
static void RemoveSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
SBusSleeper * m_pNext
Definition cinosbus.h:538
bool m_bClocked
Definition cinosbus.h:536
static void HandleSleepers(SBusSleeper *&apFirstSleeper)
Definition cinosbus.h:299
char m_cData[0x4000-3 *sizeof(uint32)]
Definition cinosbus.h:402
uint32 m_uWriteIndex
actual write buffer
Definition cinosbus.h:394
uint32 m_uTemporary[2]
temporary data
Definition cinosbus.h:396
Definition cinosbus.h:289
void * m_pMethod
pointer to method
Definition cinosbus.h:293
void * m_pObject
pointer to object
Definition cinosbus.h:291
uint32 m_uParam
parameter
Definition cinosbus.h:295
Definition cinosbus.h:283
uintptr m_uAddress
pointer to port
Definition cinosbus.h:285
Definition cinosbus.h:275
uint8 m_uCommand
command
Definition cinosbus.h:277
uint8 m_uReserved[sizeof(uintptr) -1]
reserved
Definition cinosbus.h:279
Definition cinosbus.h:409
Definition cinosbus.h:499
Definition cinosbus.h:466
uint32 m_uPostHooks
number of bus post hooks
Definition cinosbus.h:475
Definition cinosbus.h:424
uint16 m_uCatActCycle
category based act cycle
Definition cinosbus.h:426
std::atomic< uint32 > m_uHooks
number of bus hook
Definition cinosbus.h:437
Definition cinosbus.h:204
Definition cinosbus.h:485
uint32 m_uWatchdogCountMax
watchdog counter max
Definition cinosbus.h:491
uint32 m_uWatchdogLevel
watchdog level
Definition cinosbus.h:493
uint32 m_uCycleTimeCat
cycletime category
Definition cinosbus.h:487
uint32 m_uWatchdogCount
watchdog counter
Definition cinosbus.h:489