-
Notifications
You must be signed in to change notification settings - Fork 249
/
multicore.txt
64 lines (54 loc) · 3.1 KB
/
multicore.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
MULTI-CORE SUPPORT
The Cortex-A7/-A53/-A72 CPU in the Raspberry Pi 2/3/4 has four identical cores.
With Circle they can be used to run four simultaneous threads of operation. The
user is responsible for assigning a specific working task to a core. Despite
from this all peripheral IRQs (and callbacks triggered by an IRQ, e.g. kernel
timer handler or USB completion routine) are handled on core 0.
Until now a (single-core) Circle application was implemented in the CKernel
class (including initialization). A multi-core application now uses at least two
application classes. CKernel runs on core 0 and does mostly the initialization
only. The main application function is implemented in a user-defined class which
is derived from CMultiCoreSupport. CMultiCoreSupport::Run() will be called on
each core with the core number (0-3) as parameter. Using this number one can
branch to a function which should run on the respective core.
ARM_ALLOW_MULTI_CORE must be defined in include/circle/sysconfig.h to use
CMultiCoreSupport. With this define execution may be a bit slower if only core 0
(single core) is used.
The system initialization runs on core 0 only. Multi-core support
(CMultiCoreSupport-derived class) has to be initialized at last in
CKernel::Initialize().
Some classes can be used concurrently (after initialization) from more than one
core:
* CScreenDevice
* CSerialDevice
* CLogger
* CTimer
* USB
* FAT file system (not from interrupt context)
* CDeviceNameService (not from interrupt context)
* CBcmPropertyTags (not from interrupt context)
* CBcmMailBox (not from interrupt context)
* CI2CMaster (not from interrupt context)
* CGPIOPin (multiple instances can be used concurrently, access to a specific
CGPIOPin instance is allowed from one core only at a time)
* CPWMOutput
* CBcmRandomNumberGenerator
If another class - not listed above - should be used concurrently this has to be
synchronized by the user. Synchronization in single-core applications was
normally done by EnterCritical(). From now on the class CSpinLock will be used.
EnterCritical() is only used if the thread running locally on one core should
not be interrupted by an IRQ (e.g. for timing purposes) or inter-processor
interrupt (IPI).
Core 0 is not halted until all secondary cores have been halted because it
handles the peripheral interrupts. This is ensured by Circle itself if using
halt(). In case of a system panic condition all cores are halted. This can be
changed by overloading CMultiCoreSupport::IPIHandler().
Please note that the USB frame scheduler for interrupt transfers in Circle is
very simple. If you generate heavy USB bulk traffic (by using storage devices or
the Ethernet device) this may cause problems with devices using interrupt
transfers (e.g. keyboard, mouse) which will respond very slowly in this case. If
you recognize such problems you should give the USB some time to relax by
continuously executing a short delay in your program flow from time to time.
The cooperative non-preemtive scheduler is intended to allow multiple threads of
operation on a single core. It cannot be used on more than one core at a time
and should always run on core 0.