0:09
hello and welcome to controllers Tech
0:12
in the previous video I covered how to
0:14
use the hardware semaphore for core
0:16
notification and synchronization
0:19
today we will see how to use the shared
0:22
memory to transfer the data between the
0:25
to do so we will use the open amp
0:28
framework along with the remote
0:32
you can find more info in the document
0:37
this document specifically covers the
0:40
inter-process communication
0:42
let's see why we need inter process
0:45
communication in the first place
0:47
we can use it for event notification
0:49
where One Core can be used to monitor
0:52
the event and it can send the
0:54
notification to the second core to wake
0:56
up and process the event
0:58
we can use it to ask for the remote
1:01
service where the cores will have to
1:03
make the request via the IPC Channel if
1:05
it wants to use a certain resource
1:08
we can also use it for the payload
1:10
processing where One Core can be used to
1:13
collect the data from the sensor and
1:15
another core can process the data
1:17
shared Memories One way to transfer the
1:20
data easily between the cores
1:23
here you can see in the H7 series mcus
1:26
pretty much all the memories are
1:28
accessible by both the cores using one
1:32
so in a way we can use any memory region
1:35
as the shared memory for both the cores
1:38
but to keep things simple I will go with
1:41
the sram-4 region which is available in
1:46
the main reason is that since the memory
1:49
is in the D3 domain it will remain
1:51
accessible to both the cores even if the
1:54
D1 and D2 domains are in the low power
1:58
the sram-4 region is widely used as the
2:01
shared memory for the message exchange
2:03
so we will use the same
2:06
there are different ways to notify the
2:09
they include the hardware semaphores the
2:12
XD interrupts and the send event
2:16
we will again use the hardware semaphore
2:21
for the communication Channel we have
2:23
the open amp which stands for open
2:25
asymmetric multi-processing along with
2:28
the remote processor messaging RP
2:31
open amp is a framework that provides
2:34
the software components for the
2:36
development of the applications for the
2:38
asymmetric multi-processing system
2:41
on the other hand rpmessage is a
2:43
component of the open amp framework
2:45
which allows the communication between
2:47
applications running on different cores
2:51
the RP message library is based on
2:53
Virtual IO which actually does the
2:58
so this is our last layer of
3:00
communication on top of it we have the
3:02
RP message and then the topmost layer is
3:05
open amp for which we will actually
3:08
just like open amp and RP message we can
3:11
also use the free rtos along with the
3:14
stream buffer for the inter process
3:18
we are not going to cover this for now
3:21
then there are some Hardware resources
3:23
also like Hardware semaphores XD
3:26
controller and send event instruction
3:30
I have covered the hardware semaphores
3:32
in the previous video and the rest of
3:35
these channels will be covered in the
3:38
today we will focus on the open amp in
3:42
the open amp framework One Core acts as
3:45
the master whereas another core acts as
3:49
master and slave both initialize the
3:51
open amp individually
3:53
then the master creates a new service
3:56
and an endpoint whereas the slave only
3:59
creates the end point
4:01
the master sends the data the slave
4:04
receives the notification and the
4:07
the slave can then process data or it
4:10
can send something back to the master
4:13
a detailed instruction is given here on
4:15
the very next page but we will follow it
4:18
while writing the code
4:21
we also need to modify the Linker file
4:24
in our project for this to work
4:26
so let's start and create a new project
4:37
stm32h745 discovery board
4:39
give some name to the project and click
4:43
let me clear the pin outs first
4:46
we will start with the clock setup and
4:49
it will be the same as what we did in
5:00
now the first thing we need to do is
5:02
enable the hardware semaphore interrupts
5:15
now go to middleware open amp for the M4
5:21
I am making the M4 as the slave the rest
5:24
of the configuration is kept as default
5:27
the M7 core has automatically become the
5:31
the master will send the data to the
5:33
slave and then the slave will send it to
5:37
the board has the virtual com Port
5:39
connected to the pins pb10 and pb11
5:46
these are the TX and RX pins of the
5:54
so I am enabling the uart3 for the slave
5:57
core that is cortex M4
6:04
now let's configure the mpu
6:10
we will start with enabling the cache
6:14
let's also enable the mpu
6:17
let's see the memory configuration first
6:23
here I have the reference Manual of the
6:31
here in the D3 domain we have the sram-4
6:39
this is connected to the bdma
6:41
is also connected to the D2 domain via
6:54
and also to the D1 domain via another
6:59
so all the domains can access the sram-4
7:02
and since it is in a separate domain it
7:05
can still work even if the other domains
7:07
are in low power mode
7:09
let's check the memory organization
7:15
here you can see the start address of
7:17
the SRAM 4 is at 38 million hex
7:24
in the mpu configuration we will set
7:27
this region as non-cachable So to avoid
7:32
the Ram size is 64 kilobytes
7:36
if you don't understand this check out
7:38
the mpu configuration videos in the M7
7:45
that's all the setup we need click save
7:48
to generate the project
7:51
let's build the main files once before
7:58
here you can see a separate folder for
8:01
open amp has been created under both the
8:07
I am going to start with the M4 core
8:13
here I have defined the RP message
8:17
the variable message receive will be
8:19
used to indicate if the message has been
8:23
received data will contain the actual
8:27
the RP endpoint is the RP message
8:30
endpoint structure next we have the RP
8:33
message receive callback which will be
8:36
called when a new message arrives
8:38
then we have the receive message
8:40
function which we will write to receive
8:44
we will write the Callback and the
8:46
receive message function later
8:48
now inside the main function after all
8:51
the initialization has been done we will
8:53
write the code for the open amp let's
8:56
understand this as per the instructions
8:58
given in the document
9:00
right now I am writing for the slave
9:05
we need to First initialize the mailbox
9:13
then initialize the open amp and check
9:17
if the status is not okay the error
9:20
function will be called
9:22
here we are doing the same
9:25
the function takes the RP message role
9:27
as the parameter which in this case is
9:30
RP message remote the slave
9:32
the second parameter is to bind the new
9:35
service but since the service is created
9:37
by the master here we will just pass the
9:41
the next step is to create the endpoint
9:47
here we will pass the address of the RP
9:49
message endpoint structure that we
9:51
defined in the beginning
9:58
the next is the name which is also
10:01
then the destination which is set to any
10:06
then the Callback which we defined
10:08
earlier and finally the unbind Callback
10:12
which will be null since the service is
10:14
not being created by the slave
10:17
now after creating the endpoint the main
10:19
Loop begins where we receive the data
10:22
from the master once the mail Loop is
10:25
done we can de-initialize the open amp
10:29
here for the main Loop we will receive
10:31
the data then convert it to the string
10:33
format and then send it to the uart
10:36
let's define this data array to store
10:39
the data in the character format
10:45
finally we will de-initialize the open
10:48
amp we still need to write the Callback
10:51
function and the receive message
10:57
in the Callback function we will first
10:59
type cast the data to the unsigned int
11:02
since this is the format of our variable
11:05
after the data has been stored in the
11:07
variable set the message received
11:09
variable to 1 indicating that the data
11:13
this received data variable contains the
11:16
actual data and we are converting the
11:19
data stored in it to the character
11:22
since the data type is unsigned int we
11:25
need to use the appropriate format
11:28
all right now the function to receive
11:32
while a message received variable is
11:34
zero we will keep checking for the data
11:38
open amp check for message is used to
11:40
Poll for the incoming message
11:43
once the data is received the message
11:45
received callback will be called the
11:48
variable will be set to 1 and it will
11:50
break out of this Loop
11:56
here the code is written to receive the
11:59
data only once and after receiving the
12:02
open amp will be de-initialized
12:04
later in the video we will set it to
12:07
receive infinitely in a while loop
12:12
I haven't defined the status variable
12:14
let's define it here
12:18
all right we have some errors but they
12:21
are related to the Linker file so we
12:23
will fix them in the end
12:25
let's write the code for the M7 core
12:35
here we have the similar defines that we
12:40
this time I have defined the RP message
12:42
channel name and it is the same open amp
12:47
the message variable is the actual
12:49
message that we will send via the open
12:52
amp this is an integer value and after
12:55
receiving it the M4 core will convert it
12:58
to the character format before sending
13:01
we have the similar variables here the
13:04
message received is used to indicate if
13:06
the message has been received
13:09
similarly the service created will be
13:12
set to 1 once the service has been
13:14
created by the master
13:16
received data variable will contain the
13:19
actual data received by the master
13:22
and the RP endpoint is the endpoint
13:24
structure we have similar functions for
13:27
the message received callback and for
13:30
receiving the message
13:31
other than them we also have the
13:34
Callback functions for the service
13:36
created in service destroyed these
13:39
callbacks will be called when a new
13:41
service is created or destroyed
13:43
we will write these functions in a while
13:45
let's write the main code first
13:48
let's take a look at the document again
13:51
and understand this code
13:56
here we are not using the rtos so this
14:01
after initializing the mailbox we need
14:04
to also initialize the RP message
14:08
note that we are only initializing the
14:10
endpoint it will be created later
14:13
next initialize the open amp the role is
14:17
the master and this time we need to bind
14:19
the new service callback here
14:22
this is because the service is created
14:24
by the master and once the service is
14:26
successfully created the respective
14:29
callback will be called
14:31
inside the Callback we will create the
14:38
so here we will wait for the endpoint to
14:42
now once the end point is ready send the
14:44
message using openamp send function
14:50
now wait for the service to be destroyed
14:53
and then de-initialize the open amp
14:59
let's write the function we defined
15:04
here is the message received callback
15:06
and this is similar to what we did for
15:10
although the master is not going to
15:12
receive any data in today's video we
15:15
will use this function in the next one
15:17
when the remote endpoint is destroyed
15:20
the service destroyed callback will be
15:22
called and here we will simply set the
15:26
similarly when the service created
15:28
callback is called we will create the
15:35
here the name and destination is fetched
15:38
from the new service callback
15:41
we have to pass the message received
15:43
callback and the service unbind callback
15:53
basically once the open amp is
15:55
initialized the new service callback
15:59
then the end point will be created
16:02
finally we can send the message to the
16:09
all right let's edit the Linker file now
16:12
we will start with the M7 file first
16:25
copy this part from the document and
16:28
paste it in the link of file
16:33
we still need to add one more line for
16:37
now scroll down and add the section part
16:39
below the user Heap stack
16:51
we need to do the same for the cortex M4
17:13
that's it let's build the code for both
17:22
the M7 core will send the integer
17:25
message the M4 will receive the message
17:27
convert it to the character format and
17:30
then send it to the uart
17:32
let's Flash the code to the board
17:35
I am fast forwarding this part as this
17:38
is already covered in previous videos
17:41
I am using the Hercules for the serial
17:49
here you can see the number
17:52
1234 has been printed on the monitor
17:55
this value was sent by the M7 core to
17:58
the M4 core which then converted it to
18:01
the character format and sent to the
18:04
let's reset the board
18:06
the value has been printed again
18:09
whenever I reset the board the value
18:14
so we can say the open amp is working
18:17
well with the shared memory
18:19
now let's assume the master wants to
18:21
continuously send the message to the
18:24
Here I Am incrementing the value and
18:27
let's set the start value at 1.
18:35
here I am putting a while loop which
18:38
will run until the message value reaches
18:45
let's add a 500 millisecond delay
18:48
between two consecutive cents
18:52
we also need to modify the M4 code so
18:55
that it can receive the message
18:58
so we will put this much part in the
19:00
while loop and comment out the
19:02
de-initialization for now
19:04
let's build and Flash the code into the
19:10
let me reset the board
19:12
you can see the message values are being
19:15
printed every 500 milliseconds and they
19:17
only print up to 14. so we saw how to
19:21
send some integral value between the
19:24
in the next video we will use free rtos
19:27
with open amp and we will transfer a
19:30
string rather than just some value
19:32
I hope you understood the open amp setup
19:35
and how to use it to transfer data
19:39
the link to download the code is in the
19:43
leave comments in case of any doubt
19:46
keep watching and have a nice day ahead