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#if defined(INOS_BUS_HOOKS)
189#include <cinosbushooks.h>
190#endif
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 #if defined(INOS_BUS_HOOKS)
244 uint8 m_uCoreId;
245 //; base core id (virtual core id of first core)
246 uint32 m_uMaxHooks;
247 //; max. number of hooks supported
248 #endif
249 uint8 m_uScanIncludeModuleName;
250 //; include module name in process image channel name (0-no, 1-yes)
251 uint32 m_uOptionsEx;
252 //; Bit 0 : 1-optimized port handling
253 uint32 m_uMaxChannelsPerModule;
254 //; max. number of 32 bit channels per bus module
255 uint32 m_uMaxBitsPerModule;
256 //; max. number of bit channels per bus module (e.g. digital inputs/outputs)
257 uint32 m_uCycleTimeCat[DF_INOS_BUS_MAX_CATEGORY];
258 //; requested categoy cycle times
259 uint8 m_uCycleTimePage[DF_INOS_BUS_MAX_CATEGORY];
260 //; requested page number per category
261 uint8 m_uCycleTimeOversampling[DF_INOS_BUS_MAX_CATEGORY];
262 //; requested oversampling per category
263 uint32 m_uErrorMask;
264 //; error mask: defines which errors shall be reported and which shall
265 //; be ignored.
266 uint8 m_uSyncType;
267 //; syncing type(0-none, 1-master, 2-sync to master, 3- sync to time)
268 uint32 m_uSyncOffset;
269 //; syncing offset [ns] within a 1ms cycle (0xffffffff -> don't care)
270 uint32 m_uSyncTolerance;
271 //; syncing tolerance [ns] within a 1ms cycle (default = 2000)
272 uint32 m_uWatchdogLevel;
273 //; number of missing frames till category watchdog (default = 4)
274};
275//
277 // IMPORTANT : m_pNext HAS TO BE the first entry !!!
278 SINOSBusHook* m_pNxt;
279 //; pointer to next hook in list
280 SINOSBusHook* m_pPrv;
281 //; pointer to previous hook in list
282 SINOSBusHook* m_pPartner;
283 //; pointer to partner hook in other list
284 SINOSBusHook* m_pNxtRem;
285 //; pointer to next hook in list of hooks to be removed
286 void* m_pHandler;
287 //; pointer to handler funtion
288 void* m_pObject;
289 //; pointer to handler object
290 uintid m_uId;
291 //; hood id (== pointer to first hook in partner list)
292 uint16 m_uFlags;
293 //; hook flags
294 uint8 m_uCoreId;
295 //; core id this hook has to run on
296 uint8 m_uCat;
297 //; category this hook belongs to
298 uint8 m_uCycleNumber;
299 //; cyclenumber this hook runs in
300 int16 m_iOrder;
301 //; hook order
302 uint16 m_uMainCycles;
303 //; hook has to be called every 'm_uMainCycles' main cycle
304 uint32 m_uCycleTime;
305 //; requested hook cycletime
306
307 // allow dynamic handling
309};
310//
312{
316 uint8 m_uReserved[sizeof(uintptr)-1];
317};
318//
320{
322 uintptr m_uAddress;
323};
324//
326{
332 uint32 m_uParam;
333};
334//
336{
337 enum {
338 eSize16 = 0x00000001,
339 eSize32 = 0x00000000,
340 eSizeMask = 0x00000001
341 };
342 enum {
343 eCmdPort = 0x00,
344 eCmdCall = 0x01
345 };
346 // add port read 16
347 void AddPort16(volatile void* apAddress)
348 {
349 // avoid buffer overflows
351 // ensure no address conflict
352 ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
353 // set values
355 p->m_uCommand = eCmdPort;
356 p->m_uAddress = (uintptr) apAddress + eSize16;
357 // adjust write index
359 }
360 // add port read 32
361 void AddPort32(volatile void* apAddress)
362 {
363 // avoid buffer overflows
365 // ensure no address conflict
366 ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
367 // set values
369 p->m_uCommand = eCmdPort;
370 p->m_uAddress = (uintptr) apAddress + eSize32;
371 // adjust write index
373 }
374 #if defined(INOS_PORTS_64BIT)
375 // add port read 64
376 void AddPort64(volatile void* apAddress)
377 {
378 // avoid buffer overflows
380 // ensure no address conflict
381 ASSERT_ALWAYS(((uintptr)apAddress & eSizeMask) == 0);
382 // set values
384 p->m_uCommand = eCmdPort;
385 // not yet supported
386 ASSERT_ALWAYS(0);
387 // adjust write index
389 }
390 #endif
391 // add call
392 void AddCall(void* apObject, void* apMethod, uint32 auParam = 0)
393 {
394 // avoid buffer overflows
396 // method pointer needs to be valid
397 ASSERT_ALWAYS(apMethod != nullptr);
398 // set values
400 p->m_uCommand = eCmdCall;
401 p->m_pObject = apObject;
402 p->m_pMethod = apMethod;
403 p->m_uParam = auParam;
404 // adjust write index
406 }
407 // return true if buffer is empty
408 bool IsEmpty()
409 {
410 // check write index
411 return m_uWriteIndex==0;
412 }
413 // return true if buffer is empty
414 void Reset()
415 {
416 // reset write index
417 m_uWriteIndex = 0;
418 // temporary data
419 memset(m_uTemporary, 0, sizeof(m_uTemporary));
420 // and the whole buffer
421 memset(m_cData, 0, sizeof(m_cData));
422 }
423
424 // constructor
426 {
427 // reset buffer
428 Reset();
429 }
433 uint32 m_uTemporary[2];
436 #if defined(INOS_64)
437 char m_cData[0x8000-3*sizeof(uint32)];
438 #else
439 char m_cData[0x4000-3*sizeof(uint32)];
440 #endif
441 // allow dynamic handling
443};
447 void* m_pHandler;
448 //; pointer to hook handler
449 void* m_pObject;
450 //; pointer to hook object
451 uint32 m_uTimeBase;
452 //; global time base
453
454 // allow dynamic handling
456};
464 uint32 m_uOverrunCounter{};
465
466 uint32 m_uAct{};
467 uint32 m_uMin{};
468 uint32 m_uMax{};
469 uint32 m_uAllowed{};
470 uint32 m_uOverrunCounterDisabled{};
471 bool m_bOverrunDetectedByIrq{};
472
474 std::atomic<uint32> m_uHooks{};
475
476 #ifdef INOS_ADDITIONAL_BUS_TIME_MEASUREMENTS
478 bool m_bWtgLastTicksValid{};
479 uint32 m_uWtgLastTicks{};
480 uint32 m_uWtgDeltaAct{};
481 uint32 m_uWtgDeltaMin{};
482 uint32 m_uWtgDeltaMax{};
483
485 #endif
486
487 // allow dynamic handling
489};
504 uint32 m_uPostOverrunCounter;
505 bool m_bValid;
506 uint32 m_uSuspendTicks;
507 int32 m_uAct;
508 uint32 m_uMax;
509 uint32 m_uAllowed;
510
513
514 #ifdef INOS_ADDITIONAL_BUS_TIME_MEASUREMENTS
516 #endif
517
518 // allow dynamic handling
520};
521//
531
532 SINOSBusTiming m_CycleTiming[DF_INOS_MAX_CORES]; // array of bus timing
533 SINOSBusPostTiming m_CyclePostTiming[DF_INOS_MAX_CORES]; // array of bus 'post' timing
534};
535//
537
538 uint32 m_uOverrunCounter;
539 //; overrun counter
540 uint32 m_uOverrunCounterReported;
541 //; overrun counter as reported by calling SetError. It's required to
542 //; avoid that "the same overrun count" is reported multiple times when
543 //; the according error is being accepted.
544 //; This member is currently not used by the "category specific info"
545 //; instances, but it has been added here non the less (as adding new
546 //; members to CINOSBus is always a bit risky due to INFOLink.s)
547 uint32 m_uPostOverrunCounter;
548
549 SINOSBusTiming m_CycleTiming;
550 //; Used to store the "bus timing"
551 SINOSBusPostTiming m_CyclePostTiming;
552 //; Used to store the "bus post timing"
553
554 // allow dynamic handling
556};
562 enum EReservedCounts {
563 eAlreadySignaled = 0
564 };
565 SBusSleeper(uint32 auBusTicks, bool abClocked = false);
577 static uint64 s_uClockedTickCount;
580 static void AddSleeper(SBusSleeper& aNewSleeper, SBusSleeper*& apFirstSleeper);
583 static void RemoveSleeper(SBusSleeper& aNewSleeper, SBusSleeper*& apFirstSleeper);
589 static void HandleSleepers(SBusSleeper*& apFirstSleeper);
590};
591//
592//------------------------------------------------------------------------------
593// class definition
594//------------------------------------------------------------------------------
595//
596struct SINOSBusPort;
597class CINOSBusPort;
598class CINOSBusModule;
599class CINOSBus : public CINOSTask
600{
601 friend void _INI_0299_CINOSBus();
602
603 //--- user interface ---------------------------------------------------
604
605 // public member functions
606 public :
607 virtual uint32 ContactModule(uint32 auAddress, uint32 auData);
608 //; contact module with 'aAddress'
609 virtual CINOSBusModule* Find(char* apName);
610 //; return pointer to module with name 'apName'
611 virtual CINOSBusModule* Find(uint32 auNumber);
612 //; return pointer to module 'auNumber' (if pointer = 0 -> last reached)
613 virtual CINOSBusModule* FindFromAddress(uint32 auAddress);
614 //; return pointer to module with given address
615 virtual CINOSBusModule* FindFromBusNr(uint32 auBusNr);
616 //; return pointer to module with given address
617 virtual uint8 GetBusNr(uint32 auVirtualAddress)
618 { return (uint8) auVirtualAddress;};
620 virtual bool IsBusTask(CINOSTask* apTask)
621 { return apTask == this; };
622 //; return true if given task is a bus relevant task
623 inline bool IsSimulated()
624 { return m_pDesc && (m_pDesc->m_uOptions & DF_INOS_BUS_OPTION_SIMULATED); };
625 //; return true if given task is a bus relevant task
626 CINOSBusModule* FindFromDigInp(const char* apName);
627 //; return pointer to module handling the digital input 'apName'
628 CINOSBusModule* FindFromDigOut(const char* apName);
629 //; return pointer to module handling the digital output 'apName'
630 CINOSBusJob* FindJob(uint32 auTraAddress);
631 //; find job with trans address auTraAddress
632 static CINOSBus* FindBus(char* apName);
633 //; return pointer to inos bus with name 'apName'
634 static CINOSBus* FindBus(uint32 auId);
635 //; return pointer to inos bus with id 'auId'
636 static CINOSBusPort* FindPortFromInp(uint32 auNumber);
637 //; get bus port handling digital input 'auNumber
638 static CINOSBusPort* FindPortFromOut(uint32 auNumber);
639 //; get bus port handling digital output 'auNumber
641 inline static CINOSBus* GetFirstBus() {
642 return s_pFirstBus;
643 }
645 static uint8 GetFirstBusId();
647 static void AddBus(uint32 auId, CINOSBus* apBus);
648 static void SetTargetError();
649 //; will be called on a target error (e.g. trap, assert, etc.). will stop
650 //; the bus if ActualTak() is a bus task and the failure is 'assert'.
651 virtual void Start(uint32 auState = DF_INOS_BUS_STAT_RUN){};
652 //; start up field bus
653 virtual void Stop(){};
654 //; stop field bus
655 virtual void Reset(){};
656 //; reset field bus
657 virtual void RegisterOversampling(uint32 auCycleTimeNs, uint8 auOversampling);
658 //; register oversampling factor for auCycleTime
659 //; NOTE: Generally, auCycleTime must be provided in microseconds,
660 //; but some subclasses (Like GinLink, but not COPBus) may
661 //; support nanoseconds as well.
662
663 #if defined(INOS_BUS_HOOKS)
677 virtual uint32 RegisterHook(uintid& auHookId, void* apHandler, void* apObject = 0,
678 uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
679 int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
680 uint32 auFlags = CINOSBusHook::eFlgEnabled);
681
695 virtual uint32 RegisterPostHook(uintid& auHookId, void* apHandler, void* apObject = 0,
696 uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
697 int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
698 uint32 auFlags = CINOSBusHook::eFlgEnabled);
699 #else
713 virtual uint32 RegisterHook(uintid& auHookId, void* apHandler, void* apObject = 0,
714 uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
715 int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
716 bool abEnabled = true);
717
731 virtual uint32 RegisterPostHook(uintid& auHookId, void* apHandler, void* apObject = 0,
732 uint32 auCycleTime = 0, uint16 auCycleId = INOS_CYCLEID_DONT_CARE,
733 int32 aiOrder = DF_INOS_BUS_HOOK_ORDER_DEFAULT,
734 bool abEnabled = true);
735 #endif
736
746 uint32 RegisterErrorHook(uintid& auHookId, void* apHandler, void* apObject = 0);
747
752 virtual uint32 UnRegisterHook(uintid auHookId);
753
758 virtual uint32 UnRegisterPostHook(uintid auHookId);
759
764 uint32 UnRegisterErrorHook(uintid auHookId);
765
770 uint32 EnableHook(uintid auHookId);
771
776 uint32 DisableHook(uintid auHookId);
777
782 void* GetHookHandler(uintid auHookId);
783
789 uint32 SetHookHandler(uintid auHookId, void* apHandler);
790
795 uint8 GetHookCycleNumber(uintid auHookId);
796
801 uint32 GetHookCycleTime(uintid auHookId);
802
803 #if !defined(INOS_BUS_HOOKS)
804 void ChangeHookId(uintid auOldHookId, uintid auNewHookId);
805 //; set handler of hook 'auHookId'
806 #endif
807
808 virtual const char* GetCategoryName(
809 const uint32 auCategory) const;
810 //; \return The name of the task for the category. The returned
811 //; pointer is guaranteed to be valid, as long as the bus exists
812 //; (and can therefore directly be used to be registered in the
813 //; INCOtree)
814 virtual const CINOSTask* GetCategoryTask(
815 const uint32 auCategory) const;
816 //; \return The pointer to the task handling the category
817 uint32 GetState()
818 { return m_uState;};
819 //; get bus state
820 uint32 GetActCycle()
821 { return m_iActCycle; };
822 //; return actual sub cycle
823 virtual uint16* GetActCycleAdr(uint8 auCategory)
824 { return (uint16*) &m_iActCycle; };
825 //; return sub cycle address
826 virtual uint16 GetActCycleId()
827 { return 0xffff; };
828 //; return actual cycle id (this method only delivers correct
829 //; results if called from within a bus hook)
830 uint32 GetHeartBeat()
831 { return m_uHeartBeat;};
832 //; get bus heart beat
833 uint32 GetSubCycles()
834 { return m_uSubCycles;};
835 //; get bus heart beat
836 #if !defined(INOS_BUS_HOOKS)
837 uint32 GetMainCycles()
838 { return m_uMainCycles;};
839 #endif
840 //; get bus heart beat
841 virtual void SetErrorCounter(uint32 auErrorCounter)
842 { m_uErrorCounter = auErrorCounter;};
843 //; set bus error counter
844 virtual uint32 GetErrorCounter()
845 { return m_uErrorCounter;};
846 //; get bus error counter
847 void SetOverrunCounter(uint32 auOverrunCounter)
848 { m_Info.m_uOverrunCounterReported = m_Info.m_uOverrunCounter = auOverrunCounter;};
849 //; set overrun counter. also sets "overrun counter reported" to
850 //; the same value. this avoids that an error will be reported,
851 //; when the counter is e.g. reset to 0.
852 uint32 GetOverrunCounter()
853 { return m_Info.m_uOverrunCounter;};
854 //; get overrun counter
855 void SetPostOverrunCounter(uint32 auPostOverrunCounter)
856 { m_Info.m_uPostOverrunCounter = auPostOverrunCounter;};
857 //; set post overrun counter
858 uint32 GetPostOverrunCounter()
859 { return m_Info.m_uPostOverrunCounter;};
860 //; get post overrun counter
861 virtual void DiagnosticOn();
862 //; switch to diagnostic mode
863 virtual void DiagnosticOff();
864 //; switch back to run mode
866 const char* GetType() {
867 if (m_pDesc) return m_pDesc->m_cType; else return nullptr;
868 }
869 virtual uint16 GetOffset(bool abReal = true) { if (m_pDesc) return (uint16)m_pDesc->m_uOffset; else return 0; }
870 //; return bus offset
871 uint8 GetId() { if (m_pDesc) return m_pDesc->m_uId; else return 0; }
872 //; return bus id
873 uint32 GetOptions() { if (m_pDesc) return m_pDesc->m_uOptions; else return 0; }
874 //; return bus options
875 uint16 GetOptionsEx() { if (m_pDesc) return m_pDesc->m_uOptionsEx; else return 0; }
876 //; return bus extended options
877 void SetOptionsEx(uint16 auOptions)
878 { if (m_pDesc) m_pDesc->m_uOptionsEx |= auOptions; }
879 //; set extended options
880 void ClrOptionsEx(uint16 auOptions)
881 { if (m_pDesc) m_pDesc->m_uOptionsEx &= (uint16) ~auOptions; }
882 //; clear extended options
883 uint64 GetTickCount();
884 //; return actual bus tick counter
885 uint64* GetTickCountAdr()
886 //; return bus tick counter address
887 { return &m_uTickCount; };
888 void SetTickCount(uint64 auTicks);
889 //; set actual bus tick counter
890 virtual uint32 GetTickTime() { return m_uSubCycleTime; }
891 //; return number of us one bus tick takes
892 virtual uint32 GetTickTimeNs()
893 {
894 if (m_uSubCycleTimeNs)
895 return m_uSubCycleTimeNs;
896 else
897 return m_uSubCycleTime*1000;
898 }
899 //; return number of ns one bus tick takes
900 uint32 GetMainCycleTime() { return m_uMainCycleTime; }
901 //; return number of us a main cycle takes
902 uint32 GetMainCycleTimeNs()
903 {
904 if (m_uMainCycleTimeNs)
905 return m_uMainCycleTimeNs;
906 else
907 return m_uMainCycleTime*1000;
908 }
909 //; return number of ns a main cycle takes
910 virtual uint32 GetSubCycleTime(uint8 auCategory=0) { return m_uSubCycleTime; }
911 //; return number of us a sub cycle takes
912 virtual uint32 GetSubCycleTimeNs(uint8 auCategory=0) { return GetTickTimeNs(); }
913 //; return number of ns a sub cycle takes
914 uint32 GetError() { return m_uError; };
915 //; return actual bus errors
916 void SetErrorMask(uint32 auMask) { m_uErrorMask = auMask;};
917 //; set error mask and return old mask
918 uint32 GetErrorMask() { return m_uErrorMask;};
919 //; get actual error mask
920 void AcceptError(uint32 auError = 0xffffffff);
921 //; accept error
922 uint8 GetScanIncludeModuleName() { return m_pDesc->m_uScanIncludeModuleName; }
923 //; return value of flag 'm_uScanIncludeModuleName'
924 uint16 GetScanMaxWaitForBus() { return m_pDesc->m_uScanMaxWaitForBus; }
925 //; return value of 'm_uScanMaxWaitForBus'
926 uint16 GetScanMaxWaitForModules() { return m_pDesc->m_uScanMaxWaitForModules; }
927 //; return value of 'm_uScanMaxWaitForModules'
928 virtual uint32 GetParam(const char* apName, real64& arResult);
929 //; universal get parameter with aName to aResult and return error code
930 virtual void ResetMeasure();
931 //; reset cpu load measurement
932 virtual void SyncBus(uint32 auCmdOffset);
933 //; sync bus to given offset
934 virtual void Accelerate(){};
935 //; accelerate bus cycle
936 virtual void Decelerate(){};
937 //; decelerate bus cycle
938 virtual void Exactelerate(){};
939 //; exactelerate bus cycle
940 real64 GetTimebase(uint32 auHigh, uint32 auLow);
941 //; return CPU timebase [ms] at bus tick auHigh|auLow
942 virtual uint8 GetCategory(CINOSBusPort* apPort);
943 //; get category number apPort belongs to
944 virtual uint8 GetFastestCategory()
945 { return 0;};
946 //; get fastest category number
947 uint32 GetCategoryNs(CINOSBusPort* apPort);
948 //; get category ns of apPort
949 virtual uint8 GetCategory(SINOSBusPort* apPort);
950 //; get category number apPort belongs to
951 uint8 GetCategory(uint32 auCycleTimeNs, bool abAssertOnError = true);
952 //; get category of auCycleTime
953 uint32 GetCategoryNs(uint8 auCategory);
954 //; get ns of auCategory
955 uint16 GetCycleId(CINOSBusPort* apPort);
956 //; get cycle id of the port
957 uint8 GetPage(CINOSBusPort* apPort);
958 //; get page number apPort belongs to
959 uint8 GetPage(uint32 auCycleTimeNs);
960 //; get page number auCycleTimeNs belongs to
961 uint32 ConvertToNs(uint32 auValue);
962 //; convert auValue to Ns (if the value is <= 1000, we assume us if
963 //; it is > 1000 we assume ns)
964 virtual uint16 GetCycleId(const char* apName);
965 //; get cycle id of process image channel named apName
966 virtual uint32 GetCycleTimeNs(const char* apName);
967 //; get cycle time [ns] of process image channel named apName
968 virtual void Sleep(uint32 auBusTicks)
969 { ASSERT_ALWAYS(0 && "Not implemented for this bus type"); }
970 //; let the caller task sleep for auBusTicks bus ticks. If a
971 //; bus has several categories (such as ginlink), 1 bus tick
972 //; equals to the highest active category.
973 //; \param auBusTicks The amount of bus ticks to elapse until
974 //; the function returns. If a bus tick immediately occurs
975 //; after start waiting, the caller will be woken up. IOW:
976 //; if passing a value of 1 and the bus cycle time is 250us
977 //; the caller will sleep between 0..250us.
978 virtual void SleepClocked(uint32 auBusTicks)
979 { ASSERT_ALWAYS(0 && "Not implemented for this bus type"); }
980 //; let the caller task sleep until the bus tick counter
981 //; reaches a multiple of auBusTicks. If a
982 //; bus has several categories (such as ginlink), 1 bus tick
983 //; equals to the highest active category.
984 //; This can be used for simple time slice mechanisms where
985 //; e.g. every iteration of a loop is expected to take equally
986 //; long. IOW:
987 //; if passing a value of 1 and the bus cycle time is 250us
988 //; the caller will sleep between 0..250us, and more precisely
989 //; will wake up at the next 250us tick.
990
991 virtual void FlushCache(uint8 auCategory) {};
992 //; flush cache. useful for post hooks under special conditions
993
994 virtual CINCOObject* GetRegister();
995 //; do inco registration and return pointer to it
996
1000 virtual CINCOObject* GetModulesObj() {
1001 // ensure it is created
1002 GetRegister();
1003 return m_pModules;
1004 }
1005
1010 uint8 GetCoreCount() const {
1011 return m_uCores;
1012 }
1013
1035 INOS_INLINE void AtomicGatherEnter(uint32& ouToken) {
1036 ouToken = m_uAtomicGather;
1037 INOSOptimizationBarrier();
1038 }
1039 INOS_INLINE bool AtomicGatherExit(uint32 auToken) {
1040 if (ActualTask()->GetTskType() != CINOSTask::eTskTypeRealtime) {
1041 INOSOptimizationBarrier();
1042 return (auToken == m_uAtomicGather) && !(m_uAtomicGather & 0x000000FF);
1043 } else {
1044 // never block a bus task, especially not yourself
1045 return true;
1046 }
1047 }
1048
1053 bool IsWatchdogPending(uint8 auCategory)
1054 {
1055 // yes if watchdog count >= watchdog level
1056 return m_CatInfo[auCategory].m_uWatchdogCount >= m_CatInfo[auCategory].m_uWatchdogLevel;
1057 }
1058
1059 //--- internals --------------------------------------------------------
1060
1061 friend class CINOSBusJob;
1062 friend class CINOSBusModule;
1063 friend class CINOSBusChannelHandler;
1064 friend class CINOSBits;
1065 friend class CINOSAdcChannels;
1066 friend class CINOSDacChannels;
1067 friend class CINOSPosChannels;
1068 friend class CINOSProcessImageChannel;
1069 friend class CINOSTaskEx;
1070 friend class CGINModuleIMP;
1071 friend void _INI_0399_CINOSBus();
1072 friend void _INI_0500_CINOSBus();
1073
1074 // protected members
1075 protected :
1076 SINOSBus* m_pDesc; // pointer to bus descriptor
1077 uint32 m_uState; // bus state
1078 uint32 m_uError; // bus errors
1079 uint32 m_uErrorMask; // bus error mask
1080 uint32 m_uHeartBeat; // bus heart beat
1081 char m_cStateMsg[32]; // bus state message
1082 uint32 m_uMainCycleTime; // main cycle time [us]
1083 uint32 m_uMainCycleTimeNs; // main cycle time [ns]
1084 uint32 m_uSubCycleTime; // sub cycle time [us]
1085 uint32 m_uSubCycleTimeNs; // sub cycle time [ns]
1086 uint16 m_uSubCycles; // number of sub cycles
1087 int16 m_iActCycle; // number of actual cycle
1088 #if !defined(INOS_BUS_HOOKS)
1089 uint16 m_uMainCycles; // number of main cycles
1090 int16 m_iActMainCycle; // number of actual main cycle
1091 #endif
1093 uint8 m_uCores = 1;
1094 uint32 m_uErrorCounter; // field bus error counter
1095 CINOSBusModule* m_pFirst; // pointer to first module in list
1096 uint32 m_uJobs; // number of jobs in array of job pointers
1097 uint32 m_uJobsMax; // max. number of jobs in array of job pointers
1098 CINOSBusJob** m_pJobs; // pointer to array of job pointers
1099 uint32 m_uIndexes; // number of vertical indexes
1100 uint16* m_pIndexes; // pointer to 2 dim array of job indexes
1101 uint16 m_uVirtualCycleIndex; // actual virtual cycle index
1105 class CINOSBusChannelHandler* m_pChnHnd = nullptr;
1106
1107 // inco registration
1108 static CINCOObject* m_pFieldBus; // inco registration 'FieldBus'
1109 CINCOObject* m_pRegister; // inco registration 'Bus'
1110 CINCOObject* m_pModules; // inco registration 'Bus.Modules'
1111 CINCOObject* m_pTiming; // inco registration 'Bus.Timing'
1112 #if defined(INOS_BUS_HOOKS)
1113 CINCOObject* m_pHooks{}; // inco registration 'Bus.hooks'
1114 #endif
1115
1116 CINOSTask* m_pPostTask;
1117 #if defined(INOS_BUS_HOOKS)
1118 enum {
1119 eMainHooks = 0,
1120 ePostHooks = 1,
1121 eErrorHooks = 2,
1122 };
1123 CINOSBusHooks m_Hooks{eMainHooks};
1124 CINOSBusHooks m_PostHooks{ePostHooks};
1125 CINOSBusHooks m_ErrorHooks{eErrorHooks};
1126 #else
1127 // hook handling
1128 CINOSMutex* m_pHookLock;
1129 SINOSBusHook** m_pHooks;
1130 SINOSBusHook** m_pPostHooks;
1131 SINOSBusHook* m_pErrorHooks;
1132 volatile SINOSBusHook* m_pToBeRemoved;
1133 static SINOSBusHook* s_pHooks[256];
1134 static std::atomic<uint8> s_uHooks;
1135 #endif
1136
1137 // eeprom handling
1138 void* m_pEepromBuffer; // pointer to eprom buffer (with size
1139 // of m_uMaxEepromSize bytes)
1140 // contact module
1141 uint32 m_uContactAdr; // contact module address
1142 uint32 m_uContactDat; // contact module data
1143 uint32 m_uContactRet; // contact module return value
1144
1145 // additional bus info
1146 SINOSBusInfo m_Info{};
1147 // additional bus per category. The array lenght is the "longer" of
1148 // DF_INOS_BUS_MAX_SUB_CYCLES and DF_INOS_BUS_MAX_CATEGORY, as the
1149 // array is used by both, category based and subcycle based busses,
1150 // such as GinLink and InfoLink.
1152
1153 // pointer to list of rec bus handlers (single core)
1154 SINOSBusHandlerBuffer* m_pRecHnd[DF_INOS_BUS_MAX_CATEGORY];
1155 // pointer to list of rec bus handlers (multi core)
1156 SINOSBusHandlerBuffer* m_pRecHndM[DF_INOS_MAX_CORES][DF_INOS_BUS_MAX_CATEGORY][DF_INOS_BUS_MAX_CYCLE_NUMBER];
1157 // pointer to list of tra bus handlers (single core)
1158 SINOSBusHandlerBuffer* m_pTraHnd[DF_INOS_BUS_MAX_CATEGORY];
1159 // pointer to list of rec bus handlers (multi core)
1160 SINOSBusHandlerBuffer* m_pTraHndM[DF_INOS_MAX_CORES][DF_INOS_BUS_MAX_CATEGORY][DF_INOS_BUS_MAX_CYCLE_NUMBER];
1161
1162 // ticks
1163 uint64 m_uTickCount; // actual tick count
1164 uint64 m_uTimebase; // actual cpu timebase at last tick
1165
1166 // virtual address handling
1167 CINOSMutex m_VirtualAddressMutex;
1168 uint32 m_uVirtualAddressMask[8] = {0};
1169 uint8 m_uVirtualAddressCounter = DF_INOS_BUS_MOD_VADDR_MIN;
1170
1171
1172 friend class CINOSMcTargetKernelLogger;
1173 // tasklog trigger for overruns
1174 enum {
1175 eTskLogTriggerOverrun = 0x01,
1176 eTskLogTriggerPostOverrun = 0x02,
1177 };
1178 uint8 m_uTasklogTriggerFlags{};
1179 uint8 m_uTasklogTriggerPercent{50};
1180 void EnableTasklogTriggerOverrun(uint8 auPercent)
1181 {
1182 m_uTasklogTriggerFlags |= eTskLogTriggerOverrun;
1183 m_uTasklogTriggerPercent = auPercent;
1184 }
1185 void DisableTasklogTriggerOverrun()
1186 {
1187 m_uTasklogTriggerFlags &= ~eTskLogTriggerOverrun;
1188 }
1189 void EnableTasklogTriggerPostOverrun(uint8 auPercent)
1190 {
1191 m_uTasklogTriggerFlags |= eTskLogTriggerPostOverrun;
1192 m_uTasklogTriggerPercent = auPercent;
1193 }
1194 void DisableTasklogTriggerPostOverrun()
1195 {
1196 m_uTasklogTriggerFlags &= ~eTskLogTriggerPostOverrun;
1197 }
1198
1199 // bus syncing
1200 enum {
1201 eBusSyncOff,
1202 eBusSyncOk,
1203 eBusSyncAccelerate,
1204 eBusSyncDecelerate
1205 } m_eBusSync = eBusSyncOff;
1206 enum EBusSyncType {
1207 eBusSyncNone = 0,
1208 eBusSyncMaster = 1,
1209 eBusSyncToMaster = 2,
1210 eBusSyncToUTC = 3
1211 } m_eBusSyncType = eBusSyncNone;
1212 enum {
1213 eBusSyncFilterLength = 16,
1214 eBusSyncFilterShift = 4,
1215 eBusSyncFilterMask = eBusSyncFilterLength-1,
1216 };
1220 int32 m_iBusSyncFilter[eBusSyncFilterLength] = {0};
1221 int32 m_iBusSyncFilterSum = 0;
1222 int32 m_iBusSyncDelta = 0;
1223 uint32 m_uBusSyncOffset = 0;
1224 int32 m_iBusSyncTolerance = DF_INOS_BUS_SYNCTOLERANCE_DEFAULT;
1226 uint32 m_uBusSyncOk = 0;
1232 static uint64 m_uBusSyncMaster;
1233 void SyncBusOn();
1234 void SyncBusOff();
1235
1239 void VirtualAddressFree(uint8 auAddress);
1241 bool VirtualAddressCheck(uint8 auAddress);
1242
1243 // creation
1244 public :
1245 explicit CINOSBus(SINOSBus* apDesc);
1246 //; inos bus constructor
1247 virtual ~CINOSBus();
1248
1249 // public members but just for internal use)
1250 public :
1251 virtual uint32 SetState(uint32 auState);
1252 //; set bus state and state message and return stae before
1253 void SetHeartBeat(uint32 auHeartBeat)
1254 {m_uHeartBeat = auHeartBeat;};
1255 //; set bus heart beat
1256 uint32 GetVirtualCycleIndex();
1257 //; return auto generated virtual cycle index
1258 virtual void Add(CINOSBusModule* apModule);
1259 //; add inos bus module
1260 virtual void Remove(CINOSBusModule* apModule);
1261 //; remove inos bus module
1262 virtual void RemoveAll();
1263 //; remove all modules
1264 virtual void Scan(){};
1265 //; scan field bus
1266 virtual void Prepare();
1267 //; prepare field bus jobs
1268 virtual void PostPrepare();
1269 //; called after field bus prepare
1270 virtual void Initialyse();
1271 //; initialyse field bus
1272 virtual bool InitDone();
1273 //; return true if initialisation of bus is done
1274 virtual bool IsDynamic()
1275 { return false;};
1276 //; return true if startup sequence is dynamic
1277 virtual bool IsCategoryBased()
1278 { return false;};
1279 //; return true if bus is category based (e.g. ginlink)
1280
1281 // protected member functions
1282 protected :
1283 uint32 GetRealCycleIndex(uint32 auVirtualCycle);
1284 //; return real cycle index of virtual index auVirtualCycle
1285 void SortJobs();
1286 //; do job sort
1287
1288 // eeprom handling routines
1289
1290 void* RequestEepromBuffer();
1291 //; get pointer to eeprom buffer
1292 void ReleaseEepromBuffer(void* apBuffer);
1293 //; release pointer to eeprom buffer
1294
1295 void HandleDownSampling();
1296 //; handle down sampling
1297 SINOSBusHandlerBuffer* HandlerBufferPrepare(SINOSBusHandlerBuffer*& apBuffer);
1298 //; prepare buffer handler
1299 void HandlerBufferDone(SINOSBusHandlerBuffer*& apBuffer, SINOSBusHandlerBuffer* apNew);
1300 //; set new handler buffer pointer
1301 bool HandlerBufferEqualContent(SINOSBusHandlerBuffer* apBuffer1, SINOSBusHandlerBuffer* apBuffer2);
1302 //; compare two buffers
1303 void HandlerBufferSetup();
1304 //; setup all rec and tra handler lists
1305 void HandlerBufferSetupRec(uint8 auCategory=0);
1306 //; setup receive data
1307 ICACHE void HandleRecData(uint8 auCategory=0);
1308 //; handle receive data
1309 void HandlerBufferSetupRecM(uint16 auCycleId);
1310 //; setup receive data (multicore)
1311 ICACHE void HandleRecDataM(uint16 auCycleId);
1312 //; handle receive data (multicore)
1313 void HandlerBufferSetupTra(uint8 auCategory=0);
1314 //; setup trans data
1315 ICACHE void HandleTraData(uint8 auCategory=0);
1316 //; handle trans data
1317 void HandlerBufferSetupTraM(uint16 auCycleId);
1318 //; setup trans data (multicore)
1319 ICACHE void HandleTraDataM(uint16 auCycleId);
1320 //; handle trans data (multicore)
1321 static void HandleRecBuffer(SINOSBusHandlerBuffer* apHnd);
1322 //; handle rec port handler list
1323 static void HandleTraBuffer(SINOSBusHandlerBuffer* apHnd);
1324 //; handle tra port handler list
1325 ICACHE void HandleHooks(uint8 auCategory = 0);
1326 //; handle inos bus hooks
1327 ICACHE void HandlePostHooks(uint8 auCategory = 0, bool abWakeupPostTask = true);
1328 //; handle inos bus post hooks
1329 void iHandlePostHooks();
1330 //; handle inos bus post hooks
1331 #if defined(INOS_BUS_HOOKS)
1332 virtual uint32 iRegisterHook(uintid& auHookId, CINOSBusHooks& aHooks, void* apHandler, void* apObject,
1333 uint32 auCycleTime, uint16 auCycleId, int32 aiOrder, uint32 auFlags);
1334 virtual void iiHandlePostHooks();
1335 //; handle inos bus post hooks
1336 #else
1337 virtual uint32 iRegisterHook(uintid& auHookId, SINOSBusHook** apHooks, void* apHandler, void* apObject,
1338 uint32 auCycleTime, uint16 auCycleId, int32 aiOrder, bool abEnabled);
1339 //; register requested hook in apHooks list
1340 void iUnRegisterHook(uintid auHookId, bool abDestroyFirst = true);
1341 //; unregister requested hook from its list
1342 void iInsertHook(SINOSBusHook** apList, SINOSBusHook* apHook);
1343 //; remove hook from according hook list
1344 void iRemoveHook(SINOSBusHook* apHook, bool abDestroy = true);
1345 //; remove hook from according hook list
1346 void iDeleteHook(SINOSBusHook* apHook);
1347 //; delete hook
1348 bool iToBeRemoved(uintid auHookId);
1349 //; mark hook as 'to be removed'. \return true upon success, false
1350 //; otherwise (e.g. if no valid hook id was passed)
1351 #if defined(INOS_TESTING)
1352 friend class CINOSBusHookTestMaster;
1353 #endif
1354 void iCleanupHooks(bool abDestroyFirst = true);
1355 //; delete all hooks of the 'to be removed' hooks list
1356 #endif
1357
1358 // cpu load measurement
1359 void Measure();
1360 //; measure cpu load (from task Resume till now)
1361
1362 void SetError(uint32 auErrors);
1363 //; set bus error (and call error hook if nessecary)
1364
1365 #if defined(INOS_BUS_HOOKS)
1366 void RegisterHooks();
1367 #endif
1368
1374 // increment task and update counter
1375 INOS_ADD(m_uAtomicGather, 0x00000101);
1376 }
1377 INOS_INLINE void AtomicGatherEndUpdate() {
1378 // decrement task counter
1379 INOS_ADD(m_uAtomicGather, -0x00000001);
1380 }
1381
1382 // protected members
1383 protected :
1393 uint32 m_uAtomicGather = 0x00000000;
1394
1395 // public members but just for internal use)
1396 public :
1398 uint32 GetChannelBase(uint16 auAddress);
1400 uint32 GetBitBase(uint16 auAddress);
1401
1402 // processimage channel conflict supervision
1403 protected :
1407 static bool m_bChkEnabled;
1409 static bool m_bChkPermanent;
1411 static uint8 m_uChkBusId;
1413 struct SCheck {
1414 uint32 m_uMin;
1415 uint32 m_uMax;
1416 CINOSTask* m_pTsk;
1417 };
1418 static SCheck m_Chk[DF_INOS_BUS_MAX_NUMBER];
1420 static void EnbCheck(bool abEnable)
1421 { m_bChkEnabled = abEnable; };
1423 static void ModSetup(uint8 auBusId);
1425 static void ChnCreate(uint32 auNumber);
1427 static void ConflictCheck();
1429 static void PermanentCheck()
1430 { m_bChkPermanent = true; };
1431};
1432
1433//------------------------------------------------------------------------------
1434// class CINOSBusRegister
1435//------------------------------------------------------------------------------
1436
1437typedef CINOSBus* (*TCreateBus)(SINOSBus* apDesc);
1438
1440{
1441 friend void _INI_0000_CINOSBusRegister();
1442
1443 //--- internals --------------------------------------------------------
1444
1445 // private members
1446 private:
1447 // pointer to the first registered inos bus
1448 static CINOSBusRegister* m_pFirst;
1449 // pointer to the next inos bus
1450 CINOSBusRegister* m_pNext;
1451 // create funtion for the inos bus
1452 TCreateBus m_pCreate;
1453 // bus type name
1454 const char* m_pBusType;
1455 // database table name
1456 const char* m_pDatabaseTable;
1457
1458 //--- user interface ---------------------------------------------------
1459
1460 public:
1461 // register a new inos bus of type apType
1462 CINOSBusRegister(TCreateBus apCreate, const char* apBusType,
1463 const char* apDatabaseTable);
1464
1465 // create and return a new inos bus instance
1466 static CINOSBus* GetBus(SINOSBus* apDesc);
1467 // create all registered busses
1468 static void CreateAll();
1469};
1470
1471//------------------------------------------------------------------------------
1472// class CINOSDeviceMap
1473//------------------------------------------------------------------------------
1474
1476{
1477 #ifdef INOSV
1478 friend uint32 _INI_0201_CDEVICE_MAP_();
1479 #else
1480 friend void _INI_0201_CDEVICE_MAP_();
1481 #endif
1482 public:
1483
1484 // Type declaration
1485
1487 enum EError {
1488 eErrOk = 0,
1489 eErrDeviceNotFound = 1,
1490 eErrDeviceTypeNotSupported = 2,
1491 eErrResultBufferTooSmall = 3,
1492 eErrDeviceNoAddress = 4,
1493 eErrDeviceNoName = 5,
1494 };
1495
1498 eDevDontCare = 0,
1499 eDevGin,
1500 eDevTypeLast
1501 };
1502
1503
1504 static EError GetDeviceAddress(const char* apName, char* apResult, uint32 auBufferLength);
1505 static EError GetDeviceAddress(const char* apName, uint32& auResult);
1506 static EError GetDeviceName(uint32 auAddress, char* apResult, uint32 auBufferLength);
1507 static EError GetDeviceNode(const char* apName, XMLNode& axResult);
1508 static EError GetDeviceNode(uint32 auAddress, XMLNode& axResult);
1509
1510 static EError GetDeviceUid(uint64 auMacAddress, uint32 auDeviceAddress, uint32& auUid);
1511 static EError GetDeviceUid(XMLNode& aNode, uint64 auMacAddress, uint32 auDeviceAddress, uint32& auUid);
1512 static EError GetDeviceUid(uint64 auMacAddress, uint32 auProductCode, uint8 auIndex, uint32& auUid);
1513 static EError GetDeviceUid(XMLNode& aNode, uint64 auMacAddress, uint32 auProductCode, uint8 auIndex, uint32& auUid);
1514 static EError GetDevicePathByUid(uint32 auUid, char* apResult, uint32 auBufferLength);
1515
1516 static EError GetDeviceName(XMLNode& aNode, uint32 auUid, char* apResult, uint32 auLength);
1517
1518 private:
1519 static XMLNode m_sxDevices;
1520
1521};
1522
1523//
1524//------------------------------------------------------------------------------
1525// class CINCOpercent
1526//------------------------------------------------------------------------------
1527template <typename T>
1528class CINCOpercent : public CINCOdouble
1529{
1530 // constructor
1531 public:
1532 CINCOpercent(char* apName, T* apData)
1533 : CINCOdouble(apName, apData, 0, 0, "%", defCharShowFix + SHOW_DIGIT(2) + defCharReadOnly)
1534 {
1535 }
1536
1537 // public member functions
1538 public:
1539 // item address = (long) pData + aIndex*sizeof(item) + aOffset
1540 virtual long Get(void* apDest, long& maxLength, long aIndex, long aOffset) {
1541 // do we have already a pointer
1542 if (!pData) {
1543 // no
1544 *((double *) apDest) = 0;
1545 return 0;
1546 }
1547 else {
1548 // convert ticks to us
1549 T* pTiming = (T*) ((uintptr) pData + aIndex*GetConfig()->GetSize() + aOffset);
1550 double p = double(pTiming->m_uMax * 100) / double(pTiming->m_uAllowed);
1551 *((double *) apDest) = p;
1552 }
1553
1554 // ok
1555 return 0;
1556 // end CINCOpercent::Get
1557 }
1558};
1559
1567void SleepBusTicks(uint32 auBusTicks, uint32 auBusId = 0);
1568
1569//
1570//------------------------------------------------------------------------------
1571// global variables
1572//------------------------------------------------------------------------------
1573//
1574extern CINOSBus* g_pBus[DF_INOS_BUS_MAX_NUMBER];
1575extern CINOSBus* g_pBus2[DF_INOS_BUS_MAX_NUMBER];
1576extern uint32 g_uBusIndex;
1577//
1578//------------------------------------------------------------------------------
1579// end of file
1580//------------------------------------------------------------------------------
1581
1582#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:1529
Definition cinosadcchannels.h:78
Definition cinosbits.h:73
Definition cinosbushooks.h:467
Definition cinosbus.h:1440
Definition cinosbus.h:600
INOS_INLINE void AtomicGatherEnter(uint32 &ouToken)
Definition cinosbus.h:1035
static CINOSMutex m_ChnCheck
check mutex
Definition cinosbus.h:1405
static uint8 GetFirstBusId()
Return the id of the first valid bus, or 0 if none available.
INOS_INLINE void AtomicGatherBeginUpdate()
Definition cinosbus.h:1373
virtual uint32 RegisterPostHook(uintid &auHookId, void *apHandler, void *apObject=0, uint32 auCycleTime=0, uint16 auCycleId=(0xffff), int32 aiOrder=20, bool abEnabled=true)
Register post hook and return hook id. The registered function will be called in the context of the c...
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:1103
static void EnbCheck(bool abEnable)
enable/disable channel check
Definition cinosbus.h:1420
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:1053
uint32 GetHookCycleTime(uintid auHookId)
Get cycle time of given hook.
virtual CINCOObject * GetModulesObj()
Return root registration object of modules.
Definition cinosbus.h:1000
int32 m_iBusSyncFilter[eBusSyncFilterLength]
bus sync delta [ns]
Definition cinosbus.h:1220
static CINOSBus * GetFirstBus()
Return first valid bus (aka "g_pBus[0]").
Definition cinosbus.h:641
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:1411
uint32 m_uBusSyncOk
bus sync ok counter
Definition cinosbus.h:1226
virtual bool IsBusTask(CINOSTask *apTask)
get bus number of module with given address
Definition cinosbus.h:620
uint32 DisableHook(uintid auHookId)
Enable hook with given id.
static bool m_bChkEnabled
check active
Definition cinosbus.h:1407
uint32 m_uAtomicGather
Definition cinosbus.h:1393
uint8 m_uBusSyncIndex
bus sync index
Definition cinosbus.h:1218
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:1232
uint32 m_uBusSyncAccelerate
bus sync accelerate counter
Definition cinosbus.h:1228
uint32 EnableHook(uintid auHookId)
Enable hook with given id.
class CINOSBusChannelHandler * m_pChnHnd
pointer to bus channel handler (if any)
Definition cinosbus.h:1105
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:1230
static void PermanentCheck()
switch on permanent check
Definition cinosbus.h:1429
uint8 m_uCores
actual number of cores used
Definition cinosbus.h:1093
void * GetHookHandler(uintid auHookId)
Get handler of given hook.
const char * GetType()
Get bus type, used for consistency checks.
Definition cinosbus.h:866
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 RegisterHook(uintid &auHookId, void *apHandler, void *apObject=0, uint32 auCycleTime=0, uint16 auCycleId=(0xffff), int32 aiOrder=20, bool abEnabled=true)
Register hook and return hook id. The registered function will be called in the context of the corres...
static bool m_bChkPermanent
permanent check
Definition cinosbus.h:1409
uint8 GetCoreCount() const
Definition cinosbus.h:1010
Definition cinosdacchannels.h:77
Definition cinosbus.h:1476
EDeviceType
Error type.
Definition cinosbus.h:1497
EError
Error type.
Definition cinosbus.h:1487
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:1413
Definition cinosbus.h:561
uint32 m_uBusTicks
Definition cinosbus.h:571
CINOSSync m_pSync
Definition cinosbus.h:568
static uint64 s_uClockedTickCount
Definition cinosbus.h:577
static void AddSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
static void RemoveSleeper(SBusSleeper &aNewSleeper, SBusSleeper *&apFirstSleeper)
SBusSleeper * m_pNext
Definition cinosbus.h:575
bool m_bClocked
Definition cinosbus.h:573
static void HandleSleepers(SBusSleeper *&apFirstSleeper)
Definition cinosbus.h:336
char m_cData[0x4000-3 *sizeof(uint32)]
Definition cinosbus.h:439
uint32 m_uWriteIndex
actual write buffer
Definition cinosbus.h:431
uint32 m_uTemporary[2]
temporary data
Definition cinosbus.h:433
Definition cinosbus.h:326
void * m_pMethod
pointer to method
Definition cinosbus.h:330
void * m_pObject
pointer to object
Definition cinosbus.h:328
uint32 m_uParam
parameter
Definition cinosbus.h:332
Definition cinosbus.h:320
uintptr m_uAddress
pointer to port
Definition cinosbus.h:322
Definition cinosbus.h:312
uint8 m_uCommand
command
Definition cinosbus.h:314
uint8 m_uReserved[sizeof(uintptr) -1]
reserved
Definition cinosbus.h:316
Definition cinosbus.h:276
Definition cinosbus.h:446
Definition cinosbus.h:536
Definition cinosbus.h:503
uint32 m_uPostHooks
number of bus post hooks
Definition cinosbus.h:512
Definition cinosbus.h:461
uint16 m_uCatActCycle
category based act cycle
Definition cinosbus.h:463
std::atomic< uint32 > m_uHooks
number of bus hook
Definition cinosbus.h:474
Definition cinosbus.h:206
Definition cinosbus.h:522
uint32 m_uWatchdogCountMax
watchdog counter max
Definition cinosbus.h:528
uint32 m_uWatchdogLevel
watchdog level
Definition cinosbus.h:530
uint32 m_uCycleTimeCat
cycletime category
Definition cinosbus.h:524
uint32 m_uWatchdogCount
watchdog counter
Definition cinosbus.h:526