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