Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Timing in digital signals.

Xenon02

Full Member level 3
Joined
Nov 12, 2022
Messages
157
Helped
0
Reputation
0
Reaction score
0
Trophy points
16
Activity points
2,205
Hello !

I've wanted to ask for a need teaching help. I wanted to learn more about digital circuits itself, so I've been playing around with STM32 nucleo boards.
The things I was pretty much lost was about signal timings and timing itself, I'll try to describe it as best as I can, if there are any problems please give let me know I'll try to clarify everything I want to ask, also I want to add that there won't be any code, basically theoretical stuff I wanted to understand or know the place where I can read about it.
First of all is timing in digital signals, I've stumbled in this timing thing in some places and didn't understand how do they affect to each other sometimes. One of these occurance happened while trying to find out why my ESP8266 didn't work as I2C slave (which has been resolved), one user said that the I2C standard speed is like 100kHz and the ESP chip has a clock of 80MHz and he somehow calculated that the chip has like 5us time ??? This is the first thing which confused me in man ways in the way that I didn't know what one frequency had something to do with another frequency but okey. I found out that timing can be pretty helpfull in some situations, but didn't know how to approach this topic, I can imagine some stuff but couldn't find the conflicts in it or this "gap" of free time.

Second thing is maybe a bit weird to ask but okey.
I also have a hard time imagining how fast are some protocols/functions/communication lines etc. like it is in ms,us, ns. Some say it is fast or not but it is less than a second and I find it sometimes hard to say whether it is fast or not ...
Also I just found out practicing programming that the amount of code doesn't say whether the whole code is proceeded slower, or faster, even small code can be proceeded slower than the longer code.
But basically I had a problem understanding like the communication lines like UART or I2C, and not in concept. I know that UART uses RX and TX lines and sends data using start byte, data, parity byte etc ... and I know how I2C works as well. The problem lies somewhere else, to be more specific and to give an example, I have 2 devices, one is STM and the other is let's say a Bluetooth device. I have to initialize in both deviced UART pins. But here is the thing what if STM32 will initialize his ports faster than Bluetooth device, and will start sending data, in this situation the bluetooth shouldn't even receive or store any data that was sent by STM32 because his pins didn't initialize yet (I know weird example). Why did I think about it like that ? I don't know how each functions are proceeded how fast are they proceeded ! if function starts and finishes in us or ns is unknown for me so I don't know which device will be faster (I know it always works so why bother).
Or another example which still occupies my mind, Let's say we have STM32 which first transmits data (HAL_UART_Transmit), and after that function he calls (HAL_UART_Receive). The device on the other end is already sending data after (HAL_UART_Transmit) call, and (HAL_UART_Receive) is being processed, so data comes while function is still being processes, the data comes with 9600 baud rate, so will the function finishes it's stuff before the full 8 bits will arrive ? How fast will the function finishes it's stuff ? there are other faster speeds/bigger baud rates or faster communication lines like I2C or SPI or CAN (I haven't learned how CAN work yet), USB, PCI-Express.

Those are very random and maybe no one thinks about it but I found it confusing and couldn't find answers to it, so I wanted to ask here if maybe someone know the answers. I am not an expert in those stuff because I know some basics and was having fun with STM32, but these stuff came in mind while setting I2C in both devices and didn't know which one will initialize faster, usually I had a device which didn't require from me to set it's pins to work as I2C or UART, so I wondered how do these people know it will initialize fast enough or something ...

Thanks for reading this long post, have a nice night !
 
How about the example I have given ?
It is a bit different because It's not about I have to wait untill the whole data comes to me like in blocking function.
What I tried to say is how do I know that the function will get to the point of waiting the RX flag ? The data is already transmitted that is one thing and the function is still being processed. It reads the function, and is not waiting to check the RX flag, I know it is blocking but like I said what if he doesn't get in time of checking the RX flag like in my example ? It may get in time for 9600 baud rate, but for higher speeds ? Or with different interface like I2C or SPI ?

What you've explained I kinda get it now I think, but my question and pictures were to ask something else ? Did I fail ?
 
How about the example I have given ?
It´s totally wrong - at least what I understand.

***

1) inside HAL ...Transmit
* this blocking function has to be called from main()
* is nothing you can (or should) modify inside. There is no "if (flag..."
* All it does is waiting for each byte to be sent and put another byte to the UART_periferal. 99.9% waiting. Uselessly consuming processing power.
* The time is lost. During this time the processor is not able to perform any other job.
* "if (flag ...) " belongs to your own written MAIN()

****

2) inside HAL ...Receive
* this blocking function has to be called from main()
* is nothing you can (or should) modify inside. There is no "if (flag..."
* All it does is waiting for byte(s) to be received. And if it recieves no data via UART ... it will wait forever (unless there is a timeout). Waiting, waiting. Uselessly consuming processing power.
* The time is lost. During this time the processor is not able to perform any other job.
* "if (flag ...) " belongs to your own written MAIN()

3) totally wrong.
The UART hardware of the microcontrollers I used .. all of them .. have no access/control/feedback to bit wise UART status.
This means the software has no information whether the UART received 0, 3, 7, 9 .... bits. The UART hardware reacts when all 10 bits are received and treat this bytewise only. (assuming 8N1)
The software does nothing - really nothing - bitwise. Thus a bitwise discussion makes no sense at all.

***

Postbox with flag.
There is no "half a letter has arrived" flag.
Either the letter is here or not.

Klaus
 
2) inside HAL ...Receive
* this blocking function has to be called from main()
* is nothing you can (or should) modify inside. There is no "if (flag..."
* All it does is waiting for byte(s) to be received. And if it recieves no data via UART ... it will wait forever (unless there is a timeout). Waiting, waiting. Uselessly consuming processing power.
* The time is lost. During this time the processor is not able to perform any other job.
* "if (flag ...) " belongs to your own written MAIN()

It has some flags

1705748055150.png


So like it checks them before reading data from RX buffer (I don't know in which place because this code isn't as clear to me or rather I am not experienced ...)

Like in my example, the data is being transferred to the RX buffer but the software/HAL_UART_Receive() function is still not ready to read RX flag that the buffer is full. It is not in stand by mode (not waiting for the flag before the full 10 bits will fill the buffer).

3) totally wrong.
The UART hardware of the microcontrollers I used .. all of them .. have no access/control/feedback to bit wise UART status.
This means the software has no information whether the UART received 0, 3, 7, 9 .... bits. The UART hardware reacts when all 10 bits are received and treat this bytewise only. (assuming 8N1)
The software does nothing - really nothing - bitwise. Thus a bitwise discussion makes no sense at all.

Yes rather if the full data has been received/buffer is full.
So like a said above, it reads the code while the data is being transferred to him, he still reads code and is not in stand by mode, while data is being received to the buffer. You know what do I mean ?

PS.
In the transmit there is also code to process that is not only TX flag that he has sent the full data, but only Receive TX is worrying me, in this context like I said above. What if it was a lot of faster ? What if it was I2C and not UART, it is a lot faster than UART, or SPI or PCI Express or USB etc. What if the full data comes before 5ns, and the code reads RX flag or other flag for other interfaces after 10us/10ns/100ns, because it has so many code in it and i has execute every line of that code, so it takes time to read and execute each code before reading a flag that says the buffer is full.
 
It has some flags
Yes, it has. Read what I wrote.
It´s not the flags that belong to your main() code (Ive explained before) and the HAL_UART functions should not be modified by you.

Usually there is no need to read the code inside the HAL_functions. But it´s not wrong to do so. But don´t stress yourself with this.
Better read the documentation and use it as described.
Like in my example, the data is being transferred to the RX buffer but the software/HAL_UART_Receive() function is still not ready to read RX flag that the buffer is full. It is not in stand by mode (not waiting for the flag before the full 10 bits will fill the buffer).
this whole statement makes no sense to me.

example: "function is not ready to read RX flag" ... a flag is always ready to be checked.
And a function simply will check flags.. and their result will be TRUE or FALSE. There is no third state like "not ready".
So like a said above, it reads the code while the data is being transferred to him, he still reads code and is not in stand by mode, while data is being received to the buffer. You know what do I mean ?
No, I don´t know what you mean. What is this "stand by mode" you are talking about?
What does "it reads code" mean? "it" = the microcontroller? "reads" = processes? --> The microcontroller processes code?

In the transmit there is also code to process that is not only TX flag that he has sent the full data, but only Receive TX is worrying me
What code do you talk about. The shown above?
We don´t know whether this is the Rx code, the Tx code, blocking, interrupt, DMA ... and in case of interrupt there are several pieces of conde involved.
* the functions you call (HAL_...) (maybe several)
* the ISRs (maybe several)
* the ISR callback to the user code (where you can place your own additional code to the exisitng HAL_ISR)

***
We are on a point of a lot of misunderstandings. Either on my side or on your side.
As already mentioned: I expect you to draw a somehow useful flow chart for your application (UART part).

Incomplete code snippets will lead to more confusion than help.

Klaus
 
this whole statement makes no sense to me.

example: "function is not ready to read RX flag" ... a flag is always ready to be checked.
And a function simply will check flags.. and their result will be TRUE or FALSE. There is no third state like "not ready".

Sure, I'll try to explain myself.
It is true that the code is executed from top to bottom, step by step, instruction after instruction right ?
Each line of code takes some time to be executed.
There are many lines of code and it also takes some time.

Now when does the function check the RX flag whether the RX buffer is full and ready to be taken ? At the beginning ? Probably no. At the end ? maybe ?
What am I trying to say is that looking at the screen with black background of the HAL_UART_Receive() function code inside. It checks some flags before getting to the "while" statement which checks whether the RX buffer if full or not.

There are thing that can happen.

What if the data came to fast to the RX buffer that it's flag was set on "1" and calling HAL_UART_Receive() hasn't yet read the "while" part of the code because it reads from top to bottom. Hence if new data comes it can overwrite the old data, and we have overflow.

What did I read by "not ready" is that executing this particular function HAL_UART_Receive(), hasn't yet got to read this while statement part of the code because it reads from top to bottom. It could stop on one of these flags because proceeding each line of code can take ms/us/ns and the speed of data that comes can be a lot faster.
No, I don´t know what you mean. What is this "stand by mode" you are talking about?
What does "it reads code" mean? "it" = the microcontroller? "reads" = processes? --> The microcontroller processes code?
1. Microcontroller
2. Stand by => repeating the while loop until the timeout happens or the flag will be on.

We are on a point of a lot of misunderstandings. Either on my side or on your side.
As already mentioned: I expect you to draw a somehow useful flow chart for your application (UART part).

Incomplete code snippets will lead to more confusion than help.

Probably both sides when it comes to confusion, because sometimes I had a tutorial on how UART works :D
I was just simple trying to understand timings in how fast the "function" that is called reads and proceeds every single line of code. In HAL_UART_Receive or HAL_I2C_Receive etc. can be crucial. Why ? How do I know that the called function proceeded it's lines of code fast enough to get to the line of code that checks the flag that the data is received and ready to read and read fast before new data comes.

Speed of reading the called function and the speed of transferred data to the device that used the function to read data can have very different speeds. Which can lead to the point in which data that comes is faster than executing the code that is responsible to read the data that was received which will lead to overflow not only in UART but in many interfaces. UART was used only because it was the easiest and the slowest ones.

I believe it now explains my confusion better, if not sorry for your time and let me know I'll try harder.
PS. I understand your explanation about post boxes but my question was about something different I feel or perhaps I am blockhead :}
 
This is not your application flow chart. (I asked for)

This is not showing a main() loop. not showing an ISR.

This is not using interrupts. And not using interrupts means "blocking" and "blocking" is no option for good performance.
This is not what I explained the whole time.

Klaus
 
This is not your application flow chart. (I asked for)

This is not showing a main() loop. not showing an ISR.

This is not using interrupts. And not using interrupts means "blocking" and "blocking" is no option for good performance.
This is not what I explained the whole time.

Hmmm I use theory to be honest, or rather a problem understanding something about timings. So I don't have any main program or so.
It was just simple use of two functions. without any ISR. It doesn't matter if it's blocking or not. It was about hmmmmmmm.

Okey I have an idea.
C:
#include <stdio.h>
int main() { 

    int number1, number2, sum;
  
    printf("Enter two integers: ");
    scanf("%d %d", &number1, &number2);

    // calculate the sum
    sum = number1 + number2;   
  
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}

Okey check this out. First he reads this part of the main function :
C:
#include <stdio.h>
int main() { 

    int number1, number2, sum; <---------- program reads this line of the code first it takes some time
  
    printf("Enter two integers: ");
    scanf("%d %d", &number1, &number2);

    // calculate the sum
    sum = number1 + number2;   
  
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}

Then this line of the code :
C:
#include <stdio.h>
int main() { 

    int number1, number2, sum;
  
    printf("Enter two integers: "); <---------- program reads this line of the code first it takes some time
    scanf("%d %d", &number1, &number2);

    // calculate the sum
    sum = number1 + number2;   
  
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}

And this line of the code :
C:
#include <stdio.h>
int main() { 

    int number1, number2, sum;
  
    printf("Enter two integers: ");
    scanf("%d %d", &number1, &number2); <---------- program reads this line of the code first it takes some time

    // calculate the sum
    sum = number1 + number2;   
  
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}

Each line takes some time right ? It's not instant it takes time like 5us or less I don't know.

Same goes with HAL_UART_Receive or HAL_UART_Receive_IT doesn't matter, it has to read each line of the code and it takes time.
Now my confusion was : The data comes from the device, the STM/Arduino/ESP receives this data, and the HAL_UART_Receive is called and being executed. This function (HAL_UART_Receive or HAL_UART_Receive_IT), has to read each line of the code literally each line before checking this last line which says read the flag and if buffer is full take the data. Now here is the problem ? What is the problem ? Is the function HAL_UART_Receive fast enough ? What do I mean ? Is the STM/Arduino/ESP fast enough to read each line of the code inside of HAL_UART_Receive function before the buffer will be full ?

It is true that data is being sent to the STM/Arduino/ESP while STM/Arduino/ESP is executing/reading/processing each line of the code of that function that receives data. It is not ready, not ready mean it didn't read the line of code that is meant to read the status of the buffer flag whether it is full or not. If he doesn't read it (read what ? read the last line of the code that says about rx buffer or I2C buffer or SPI buffer doesn't matter), before new data comes ...

I am not meaning about the wasted time of using blocking function because, yes he will wait untill he reads the whole data while he could just do other stuff in this time.

Yes I haven't provided the flow chart, because I don't know what to add in it, I don't have the physical code, I only used 2 function calls one after another trying to understand how fast he will read his lines of code before he reads the line of code that says about the buffer status before new data will overwrite it. And it has to read each lines of code for blocking and non blocking. They have lines of codes it is not that non blocking doesn't have lines of codes.

I also know it is convenient because it takes data automatically and pull ISR call, I am just puzzled with how fast he reads the lines of code. I don't know how to describe it, its the timing thing.

For example let's say UART is fast enough to send 10 bits after 50 ns, and the HAL_UART_Receive takes 200ns or 1us to read each line of code, and takes another 100ns to read this one line of the code that says about reading RX buffer and if it's 1 take data. Data was being sent while the HAL_UART_Receive was proceeding every line of code. after 5us first bit came but HAL_UART_Receive hasn't even done reading his lines of code, and after 50 ns, HAL_UART_Receive hasn't even read the line of code that says to check the RX flag.
 
Last edited:
Each line takes some time right ? It's not instant it takes time like 5us or less I don't know.
OK. Lets focus on this.

Each line takes some time? --> no.
Code:
#include <stdio.h>
int main() {

    int number1, number2, sum;
Neither of the lines above necessarily take time in the meaning of processing power.

Okey check this out. First he reads this part of the main function :
Try to be clear.
Who is "he"?
* the compiler: yes. It somehow reads line by line of the source code. But not necessrily the microcontroller run time.
* the microcontroller: No. The microcontroller processes machine code, generated by the compiler. It does not know about the source code.
A line of C code may cause no machine code, may cause small machine code, may cause a lot of machine code.
It depends on so many things like:
* used compiler
* compiler settings (like optimisation setting)
* other code around
* microcontroller type
* the code line itself
On one microcontroller it ma take zero processing time, on the other maybe several 10s of microseconds


The data comes from the device, the STM/Arduino/ESP receives this data, and the HAL_UART_Receive is called and being executed.
it´s so vague, that I `m not sure what all this means.
What do you mean with "the data".
"from which device"?
Who calls the HAL_UART...function? If you think it is called because the UART periferal received a byte, then you are wrong.
The HAL_UART function is called from somewhere in the main loop.
Since it is a blocking function, no one knows how long this function takes to return to the main() loop.
It waites. It waits for n bytes to be received by the UART periferal. It may be 10us, it may be a day...

This is totally different with the HAL..IT function. It returns very fast. It does not wait for UART data to be received. So it may be in the range of 1us ..10us. No noticable delay.

*****
I understand that you don´t want to draw a flow chart, nor a timing diagram.
For me It´s too time consuming and too vague and too prone for misunderstandings to discuss with text only. We are at post#30 now, but I can´t see any progress.
Thus you need to find a different person for these kind of discussions.

Klaus
 
OK. Lets focus on this.

Each line takes some time? --> no.
Neither of the lines above necessarily take time in the meaning of processing power.
What ? okey ?
Try to be clear.
Who is "he"?
* the compiler: yes. It somehow reads line by line of the source code.
* the microcontroller: No. The microcontroller processes machine code, generated by the compiler. It does not know about the source code.
A line of C code may cause no machine code, may cause small machine code, may cause a lot of machine code.
It depends on so many things like:
* used compiler
* compiler settings (like optimisation setting)
* other code around
* microcontroller type
* the code line itself
On one microcontroller it ma take zero processing time, on the other maybe several 10s of microseconds

Hmmmmm,

The frequency of the microcontroler also influences this but I get what you mean.
By he yes I was meaning the microcontroller.

The C code is translated into machine code which is Assembler. So the microcontroller reads each line of the Assembler code or rather the binary "1" and "0".
it´s so vague, that I `m not sure what all this means.
What do you mean with "the data".
"from which device"?
Who calls the HAL_UART...function? If you think it is caeed becaus the UART periferal received a byte, then you are wrong.
The HAL_UART function is called somewhere in the main loop.
Since it is a blocking function, no one knows how long this function takes.
It waites. It waits for n bytes to be received by the UART periferal. It may be 10us, it may be a day...

This is totally different with the HAL..IT function. It returns very fast. It does not wait for UART data. So it may be in the range of 1us ..10us. No noticable delay.

I didn't know the context would give enough information providing also pictures, description etc.
Because it is not about how long the whole function takes. It is how long it takes the function to get to the point to check this one flag, one very particular.

Well, data I don't know some 10 bit, it is data right ? From one device to the other that's why I said device and STM/ESP/Arduino or even any other fancy microcontroller, so we have now 2 devices one is named just device, but okey let's call it MP3 device why not.
So MP3 and the STM32, is it more clear ?

Okey, so I don't know ... This still confuses me because I really tried to give the most detail description because I don't have a program.
It is just a dilemma I cannot understand why these interfaces work properly when it comes to timing.

Okey I'll try again,
Imagine, the data (10 bit information coming from MP3 to STM32) that is being transferred to the STM32 from MP3, the STM32 buffer received the first bit of that information (physical buffer), it has not signalized that the buffer is full, that's logical.
Now take a look at this dilemma.
STM32 finished the HAL_UART_Transmit function which was blocking. After that function we call HAL_UART_Receive. Yes ? Okey, so now the microcontroler has to process each instruction right ? Every single instruction. The first instruction isn't checking the flag of RX right ? It is something else, like setting the variables, or checking the leght of something (I don't know what exactly), and at the very end he checks the RX flag.
Now the data (10 bit information from MP3 to STM32) is being transfered to the STM32 while the STM32 itself is executing each line of the code. You see the problem ? The data is coming and is stored in the buffer but the STM32 is still executing/processing the function call which is HAL_UART_Receive, he reads each line of the code but he has NOT read yet the line which says to check the RX flag because it is at the end.

Which one will be faster ? The data (10 bit information from MP3 to STM32) that will faster be stored in the RX buffer or will the HAL_UART_Receive function which STM32 microcontroller executes the call, will be fast enough to read all lines of code and read to wait for the RX flag before the overflow occures ? I am not saying that he finishes he whole function and exits the HAL_UART_Receive. No no no, completelly no, what I am saying is will the microcontroller be "fast" enough to read each line to get to the line which waits for RX flag before 10 bits will arive or before new data overdrive the old one.

This is the dilemma ?
It waites. It waits for n bytes to be received by the UART periferal. It may be 10us, it may be a day...

it is not about when microcontroller exits the HAL_UART_Receive function, it is about how fast the microcontroller will read each line of the code before the buffer will be full or overflowed



I understand that you don´t want to draw a flow chart, nor a timing diagram.
For me It´s too time consuming and too vague and too prone for misunderstandings to discuss with text only. We are at post#30 now, but I can´t see any progress.
Thus you need to find a different person for these kind of discussions.

The amount of posts should be the problem though.
The thing is a thing of misunderstanding, because you want to tell me about how much time it takes to exit a function.
Like I see what you've been trying to tell me, but it is about how fast the function is exited :D
My dilemma was a bit different, I hope it is more clearer.

I don't know if I get a better answers though, AI doesn't know, I didn't know how to search for the answer on the internet so I was left more like here ;> Susan gave me a good ideas. But it still confuses me and the conversation was around a thing I think wasn't about what I asked or wasn't about what I've shown. And I really believed it was more clear with pictures/illustrations with pointing at certain lines with arrows etc.

Still thank you.
 
Firstly I think you are worrying about nothing - if the HAL worked the way you think it does then t would be totally useless. The fact is that it does NOT work like that at all.

Mainly because you are confusing what happens in hardware and in the code.

The hardware does all of the work of reading the input (or driving the output) line. It does this without any software being involved (other than to write to the appropriate hardware registers to set things going).

Regarding the code that you show in post #23 and the flowchart - all of those tests are for flags that are within the HAL software and control blocks and NOT the hardware. They are simply setting things up for when the read completes.

The ONLY time the code looks at the hardware is the last line of code in Post #23 you show - the 'UART_WaitOnFlagUntilTimeout()'. All that code does is to block until the UART says that it has completely read a character. If no character has been received by the time this function is called then it will block until one has been completely received (but see below). If it happens that a character is available then it will return. The code that you don't show after that will then actually do the reading of the character from the hardware buffer.

One of the problems you are having is that you are trying to understand the HAL code when you don't understand the basics of serial communication. Also by looking at the code, you are getting confused by the complexity of that code which is trying to cover all possible uses of the UART whereas you are doing something very simple. (This is actually one of the big complaints about code such as the HAL which tries to abstract away the hardware - it makes things very complex when they needn't be in most situation.)

This is a classic case in fact. Note the ''...UntilTimeout' part of the function name? One of the options that you can set for the UART in the HAL is to return if you don't get a character within a specified period of time. You have not shown us your code to call the 'HAL_UART_Receive()' function but the classic usage is to set the timeout to HAL_MAX_DELAY so that you wait forever until a character is received.

Bottom line - read the documentation for the various functions you are using. Trust the coders of the HAL that they know the hardware and their complicated abstraction later better than you do. Write your code and only start to worry if it does not do what you want it to do. Don't get caught up in the weeds.

Susan
 
Firstly I think you are worrying about nothing - if the HAL worked the way you think it does then t would be totally useless. The fact is that it does NOT work like that at all.

I've read something in the mean time. And maybe I have found the answer.

I've looked it this way. I have for example 115200 baud rate which is 115200 bits per second. So 1 bit will come after 520 uS, and 10 bits will come after 5.2mS (mili seconds).

Now microcontroller has 5.2mS to read each line of the code, which are these flags that what you have mentioned are software flags, but still he has to read it right ? What microcontroller reads are not C code but machine code so checking one flag can have many machine instructions.
But yea, this HAL_UART_Receive can have a lot of instructions, and the last instructions are UART_WaitOnFlag, which he checks if the flag is ON, but take a look how much he has to read and process before he checks the flag, and have in mind that it takes time and the data is still incoming. Yes the hardware will store it but if he passes the time new data will come.
But if we have a fast clock like 40MHz = 40 000 000 instructions per second, so after 5.2ms it will read 3 467 instructions. Is it enough ? I don't know but maybe ? I don't know how much instructions does HAL_UART_Receive has, but if it has 1000 instructions then yea it will get on time before the data comes.

But maybe this shows more what I tried to say. It has to read each line of the code/execute each instruction, 1 line of code can have more or less instruction machine code. So if it is able to read all of those instructions before 5.2mS passes then sure it works.

I don't know how it works for different faster interfaces like I2C or SPI which are faster than UART and can send faster than 5.2mS data.

I've heard of faster UART baud rate but I don't know if it will shorten the amount of instructions it will read. Which will lead to the problem like I said, we called the instruction and it didn't get on time to check the flag.
 
I'm confused about exactly which part you can't understand. The concept of how long each line of code takes is perhaps being confused with how long each serial bit takes to read. The UART bit reading is done in hardware, not software so it reads the start bit, data bits and stop bits (and maybe parity bit too) in a hardware shift register quite independently of the software. Only when all the bits are read and assembled back into a parallel byte does it signal that data is received.

Brian.
 
I'm confused about exactly which part you can't understand. The concept of how long each line of code takes is perhaps being confused with how long each serial bit takes to read. The UART bit reading is done in hardware, not software so it reads the start bit, data bits and stop bits (and maybe parity bit too) in a hardware shift register quite independently of the software. Only when all the bits are read and assembled back into a parallel byte does it signal that data is received.

Brian.

When the hardware receives all 10 bits, then the microcontroller has to take this 10 bits, so software has to read the RX flag if it's full. Hence if the microcontroller won't read all instructions of that receive function in time which means he won't read all the instructions till he sees the instruction to check the RX flag, the data in hardware uart can be lost/overwritten etc. because reading the function took to much time. But I have said everything in last post.
 
You are still confusing the things done in hardware with the things done in software. The hardware will do the processing while your code is executing - there is no interaction until the UART has received a complete value, and even then all it does is set a bit in a status register and carries on.
Also while the UART will see 10 bits (assuming 8N1 which means 8 data bits, no parity and 1 stop bit which, together with the start bit, makes the 10 bits you refer to), your program will only ever see the 8 bits. Also it will see them all at once as a single value in a register that you will copy to somewhere else for your program to work on.
When the hardware has received a complete value, it will set the flag in the status register to let the program know this. However that flag will stay set until the program reads the value. There is not timing issue here at all. If for some extremely unusual situation (which will certainly relate to your code and not the HAL) you have not read a value before the next one is received and the buffer becomes full, the hardware will raise another flag - the buffer overflow flag (which the HAL code also checks for and lets you know).
Trust me (and all of the others) - the HAL_UART_Receive() function will not be holding you up. It will easily handle BAUD rates well above any you have mentioned (such as 115200).
Susan
 
When the hardware has received a complete value, it will set the flag in the status register to let the program know this. However that flag will stay set until the program reads the value. There is not timing issue here at all. If for some extremely unusual situation (which will certainly relate to your code and not the HAL) you have not read a value before the next one is received and the buffer becomes full, the hardware will raise another flag - the buffer overflow flag (which the HAL code also checks for and lets you know).

Yea that's the thing I was saying, what if new data comes.
For 115200 baud rate it is 115200 bits per second so 1 bit comes after 8.6 uS, and 10 bits will come after 86 uS.
Let's say clock of the microcontroller is 40MHz, so 1 instruction per 25nS. The Hardware will only set the flag ON and go on like you've mentioned I get it. So it will accumulate new data (UART physical buffer) while the microcontroller will read each lines of the machine code of that function that does all the stuff and at the end will reads flag responsible to check if buffer is full or not. So 3440 instruction after 86 uS, is it enough ? dunno

If I had

HAL_UART_Transmit();
//do other stuff, like read pins, set pins etc.

HAL_UART_Receive();

There is no chance that 3440 instruction will be enough. Nobody know how many instruction has this particular function. What if 3440 instruction after 86 uS wasn't enough and now it set and overflow ?
Even for normal case like here :

// one call after another
HAL_UART_Transmit();
HAL_UART_Receive();

Also thought about whether he will read all these lines of codes before the buffer overflows, lines takes times and the data isn't stop comming from the device.
You are still confusing the things done in hardware with the things done in software. The hardware will do the processing while your code is executing - there is no interaction until the UART has received a complete value, and even then all it does is set a bit in a status register and carries on.

Where do I exactly mix them ?
I only mentioned that the function reads the flag that is set by the peripheral.
It is all about how fast is the microcontroller before the data comes (full data).
Trust me (and all of the others) - the HAL_UART_Receive() function will not be holding you up. It will easily handle BAUD rates well above any you have mentioned (such as 115200).
Susan

Okey perhaps yea, but for I2C and SPI ? they are a lot faster than UART and HAL is somehow managing it.
I know there is DMA, but it has it's own set of instruction and has to execute them like microcontroller and I have to also remember that I2C and SPI are faster so I have to read these HAL commands (transfered into machine code), a lot faster or perhaps different set of instruction.


I mean it usually works I see it but I just couldn't understand why though, I was thinking about timing the moment when I had to set I2C in both devices to communicate with each other. Didn't turn on because I baked my WiFi but this let me think how it worked with timing.
 
. So 3440 instruction after 86 uS, is it enough ? dunno

If I had

HAL_UART_Transmit();
//do other stuff, like read pins, set pins etc.

HAL_UART_Receive();

There is no chance that 3440 instruction will be enough. Nobody know how many instruction has this particular function. What if 3440 instruction after 86 uS wasn't enough and now it set and overflow ?
Even for normal case like here :

// one call after another
HAL_UART_Transmit();
HAL_UART_Receive();
Have you tried this? On real hardware? I assume not because that is a very common way to work a blocking function. If that didn't work then the STM32 chipset (and just about ever other chip set as well) would be totally dead in the water.
If you have tried this and it is not working then please show us all of your code so we can see where you are going wrong.
Susan
 
Although the description of software role in UART operation by Xenon02 is partly wrong, I agree in so far, that UART receive as well as I2C and SPI slave operation involve a potential risk of overflow and data loss if software is busy with other tasks while multiple serial characters arrive.

Therefore you have a set of interrupt driven routines like HAL_UART_Receive_IT().
 
Trust me (and all of the others) - the HAL_UART_Receive() function will not be holding you up. It will easily handle BAUD rates well above any you have mentioned (such as 115200).
Susan
To clarify:
* the blocking HAL_Receive will be fast enough to perform high baud rates of UART communication.
* the problem is that it does only UART receive, nothing else.
* so it won´t hold up UART receive ... but it will stall all other activity

UART operation is asynchron. This means you will never know at which time a byte comes in (received). (Unless the protocol sets some timing specifications).
So while you transmit 10 bytes .... there is (theoretically) the time to recieve 10 bytes.
So during a blocking UART_write you can not reliably receive anything on the UART (reliably: max 1 byte)

It is well known (and discussed here) that blocking functions are ineffective.
It is well known that blocking functions stop any other software activity. (besides ISRs)

Thus - as already written - one should avoid blocking functions and just use the IT (interrupt) functions.
Then you are able to write high baud rate UART data .... and in the same time the UART sends ... you are able to receive high baud rate UART data. With relatively low processing power. (all written before)
And if you want it even more effective: You may use the DMA technique.
Where you may send 256 bytes (example) with let´s say 10MBaud and at the same time receive 256 bytes with 10MBaud .. while using zero processing power.
...and at the same time you have plenty of processing power to do other stuff.

****
thus I ask myself. Knowing all this. Knowing all problems of blocking funcions.
--> Why do you insist in those (problematic) blocking functions.
* when one knows how to avoid problems. Why you don´t even try to talk about it? It seems you like those problems.

****
Conclusion:
I personally avoid blocking functions if possible.
Maybe I use a blocking UART_transmit during the boot time of the device ... but not while my application (main loop) is running.

Klaus
--- Updated ---

***********
but indeed I find these "what if" and "theoretically" discussions rather useless.

The reality is:
* either you do communication according standards. Like MODBUS ...
* or you do your (proprietary) communication and you can set up your own standards.

****
According standards:
* read the specification. Read the timing. And write the software accordingly.

Your own:
* you have all options available. If you think you are stressed with 1MBaud, then go down to 9600 baud.
* if you need high baud rate then you still have options like flow_control, framing, half duplex instead of full duplex ...
You are the one (to create the problems), to detect the problems, to solve the problems ... often just by deciding your own standards.

****
So - for me - there is no "what if".
* The standards clearly tell you what is allowed and you have to adjust on them.
* or you decide your own standards

****
All design starts with proper investigation of the requirements. Not with "guessing". It also does not start with coding.

Klaus
 
Last edited:

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top