 Hello, in this part I would like to present to you how to use queues to transfer a bit more complex data than a standard 8-bit without sign. And in this exercise we'll create the queue which would transfer some structures. So let's start with STM32Q by DE or QBemix. I have my ready workspace. I'm creating a new project, so file new STM32 project. I'm selecting my microcontroller. So this is STM32L476RG. So I just select part of this name. This is this one. And I press next. Name of this project would be for underscore queues and underscore items. I press finish. You can reuse as well previous exercises because in this case we will use again two senders and one receiver. I will start with a new project. This is my pinout. I'm selecting from system core and CIS debug interface the last option to have SWO line and SWD interface. And I'm changing the timebase source for hull libraries from CIS stick to timer 6 to do not have any conflict between my hull library and operating system. Then from middleware I'm selecting 3R2S in interface CMC version 2. And within this interface I will extend my hip size to 4KB. Then within timed tasks and queues I would rename my default task. Sender one task, priority normal. Stock size 256 and the entry function start sender 1. Then I would create two more tasks. So the next one would be sender 2, priority normal. 256 as stock size and start sender 2 as entry function name. And last task it would be a receiver. So task name, receiver, priority normal like before, 256 as a stock size. Please remember that it is given in words and the entry function would be a start receiver. That's it. Then we need to define a queue. So I press the same tab. So tasks and queues and part queues. I click on add. I will change the name of the queue to queue1. And queue size I would change to 8 to not use too much memory. And item size instead of inside int 16 I would just put data. Which would be my structure defined in the code. I press OK and now I'm ready to generate the code. So I can either use this icon or go to project generate code. This time I would use this icon. OK, code is generated. We can perform the code modifications. Within main.c file we can have a look at the location where we are defining the handlers for both sender, task and receiver and its attributes. And as well the location of defining the handler and attributes for the queue. Then within private variable section as line 71 we will define our data structure with it which we would like to pass over the queue. It will consist of two fields. One would be unsigned 16-bit value and the second one would be unsigned 8-bit source. So this would be value and the second one would be 8-bit unsigned source. The name of this structure, the name of this type of this structure would be data like specified within the configuration phase. After this we will create two instances of this type. Data to send one with two fields A and 1 and this would be sent by sender1 task and data to send two with fields B and 2 which would be sent by sender2 task. After this we can have a look on the location when the queue is created. So this is line 146 and we can see that it's eight component and the data size is taken from this really data. And so this is our, let's say, creation of the queue. And the next point would be to fill our sender1 and sender2 tasks functions body. So it will be very similar for both of them. So we will start from task action, so our sign of life. In case of sender1 it would be small s sent over ITM interface in our example. Then we will try to put some data into the queue. This data to send one, in fact. So we are using OS message queue put function. We can use this control space to have some help. The first argument is handler to the queue. The second one is an address set to our structure. So data to send one in this case. Then there is a message priority, which is not used. So we just put zero and the timeout. So that maximum time I would like to try to send this information, which is 200 milliseconds. After this we will send our task for two seconds to the blocked state. Similar code will prepare for our sender2 with the difference that this time the task action would be big s, capital S, capital letter. And we will send data to send two instead of data to send one. Then within the receiver we will replace the default OS delay one with a bit more complex function structure. But we will start with the initialization part with declaration of the temporary variable where we will store the data taken from the queue. So this would be data type red value variable. And then within the infinite loop we will send, let's say, the sign of life using ITM sent char this time. And it will be capital R letter without, let's say, sign of new line like we are using in task action. And then we will try to get some information from the queue. So using OS message queue get function. So again we can use the control space to remind ourselves what is the function name. And the same for argument. So the first argument is of course the handler for the queue one. Then there is pointer to the, let's say, to the, our storage area. So in our case this is our local variable red value which is declared. And then the priorities null was we are not using it. And the timeout which is the maximum time you would like to wait for the data in the queue would be OS wait forever. So we will wait till the data will really arrive in the queue. And as soon as we'll have this data in our red value we will analyze it and perform some actions according to what we just received. So we are using the if else loop here. And then we are checking what is the source of this data taken from the queue. So in case it is one, so it is sent by a sender one task we would like to turn on LED, this green LED. So we are using how GPIO write pin to this. And we can use our labels. So led green or we just can press control space after. So led green GPIO port as a port, led green pin as a pin. And the last argument would be GPIO pin set to turn on this green LED in case we received information from task, so from sender one. In other case, if we receive information from sender two we would like to turn off this LED. So we will use the same function GPIO write pin but with different last argument instead of set we will have reset. Okay, so this would be the reaction on sender ID and then we will send as well the data, the value data over itm interface using task action function. And in this case we are just taking value from the data structure to send it over task underscore action function. So this would be our start receiver code in this case. So as you can see, we will start from sending R then doing some action on LED if something will come and then send again something which we just received from the queue. And what we need to do else is to define our task underscore action function which is returning no value and it is accepting one argument, it's one hard argument and within this we will use itm data send send char function which is sending one character over itm interface. We will observe it later on within single wire viewer console during debug session. After this sending the single character we will send as well the sign of new line just to have each component one by one to have let's say better view within the console. We need of course to add the declaration of this function in let's say user code private function prototype and we are ready to build the code using the hammer icon what you can just see on the screen. Okay, there are no errors, we've got some warnings because I forgot to put the type of both variables. So let's try once again. Now it's much better, zero errors, zero warnings. Okay, so after successful compilation let's connect our ports and start the debug session so I click the back icon within the debugger I'm enabling the serial wire viewer and I'm changing the core clock to four megahertz which we are using then apply and okay. Take some time and after it see this I'm opening my SWD, the ITM data console which you can see on the screen. Then I'm using the configuration and enabling channel zero and start tracing with this red dot. After this I can just play the code execution and test positive and I can see the result like expected. So at the beginning I can see the receiver which is stopped, so this is the single R and then there is a small letter from sender1 which just passed the data to the queue. So this is the receiver and it blocks after this because it is waiting for the data in the queue. This is why we cannot see anything else. Then we've got small s, so this is sender1 which sent data to send one into the queue. After this we've got big s, so sending the data to send two into the queue and after this we can see a. So this is the continuity of execution of receiver in fact from line 318 and we'll say sending the data of our sender1 from the queue because it was the first one sent. After this we can see the next iteration of the receiver. This is why we've got this big R and the small b means that we are sending the data from our sender2. So this is it. Then we've got the third iteration of receiver. This is why this is the big R and after this there is a small s. Small s means that there is activity of sender1 again and after this we can see again the activity of sender2. This is big s just below the cursor. And the situation continues like this. So again we've got small a which is the first component within the queue and then we've got the next iteration of receiver. This is big R and then b because it received the second component from the queue sent by a sender2 and the story continues like we can see in the loop. Here we can see again what is done within the task sender1 task and in both cases we've got two seconds delay which send those tasks into the blocked state for two seconds. We can start terminated debug session. Thank you for watching this video.