Hello In my project I should read two usart input ports without losing my input data.Each input should gets a string's length of 120 each 10ms.How can I handle both of them?
I think I can do with two thread such as this diagram obrazki.elektroda.pl/7019832800_1473252743.png (does it possible easily or not?)
Or can do it with a simple approach instead of using multi-threading?
Thanks
"For something so trivial, DMA seems like a massive overkill."
This depends on what other tasks the program should perform. The main reason for using DMA is if the program needs to do something where you get too big latencies to extract the data before you get a FIFO overflow. DMA also give better option to decide when to take the cost of clearing out the data since the DMA memory buffer can be seen as a huge FIFO.
In this case, each UART receives 120 characters per 10ms or 12000 characters/second. So with a 16-character FIFO the program must manage a worst-case response time of about 1ms for each UART. So a normal interrupt handler should be fast enough - even without FIFO if no other interrupt handler blocks for too long.
Thank you Per Westermark,Westonsupermare Pier,A Person I'm going to use DMA as Per Westermark said, because I have some other tasks to do.
is it possible to increase FIFO of usart of stm32f10x MCU?
You don't need DMA because you have other things to do. Interrupt handlers are run 'below' the scheduling of the tasks. So they can pick up the data and store in buffers and then signal to the proper tasks that there is data to process in the buffers.
Almost all newer processors have FIFO support so they don't need service for every single character received, but can instead cache a number of characters and issue an interrupt when the FIFO watermark is reached or after timeout.
While there are normally many ways to do things, it's usually best to aim for the simplest solution that is good enough. Save your time for the parts of the program that really needs all attention.
By the way - what do you mean by increase FIFO? The size of the FIFO is locked in hardware. But it's often possible to configure the send and receive watermarks. How empty/full the FIFO should be before interrupts are flagged.
To simulate really huge FIFO, you would need DMA where you register a block of normal RAM and have the hardware pick up received characters and store in the RAM buffer. But it's seldom needed for "slow" UART communications unless there are very special needs that must be accounted for.
The design only has a single holding register for each of the transmit and receive paths, so no FIFO. You'd need to create your own buffering behind the hardware, either with IRQ or DMA, depending on the rates, and your appreciation of how to manage/solve the problem. Given the situation, I think you should keep things simple until you have a grasp of the relative complexities, and benefits.
Using DMA with the Tx paths, either with chains or scatter-gather lists, would be most viable.
Thank you for your good explanation As matter of fact my MCU should do different jobs such as Ethernet and serial communication and some other jobs. a)At the first I thought about using USART IRQ interrupts but I see it wastes my cpu time to collect each receiving bytes (is there any way to buffer 120 characters in a buffer and after it receives all data it arise an interrupt flag? not for each chars) b)on the second thought I want to use different threads but it gets more flash volume for cmsis_os library and it's commands.In addition it gets too complex c)According to "Per Westermark" and "Westonsupermare Pier" posts I think the best way is USART with DMA.
what do you think? is there any simple way that I didn't think about it?
"The design only has a single holding register for each of the transmit and receive paths, so no FIFO."
I haven't seen any CPU mentioned.
With FIFO you would often manage maybe one interrupt per 10 characters - it's quite common with around 16 character long FIFO. Without, you need to pick up every character one-by-one one and has less margin to overrun where a character is lost.
With DMA, it's the buffer size that decides how often you need to react and chain in a new buffer. A traditional DMA implementation runs doublebuffered so you get an interrupt when the DMA channel switched to the second buffer. Then you can pick up the data from the first buffer and relink it as third buffer.
"In addition it gets too complex"
Having one protocol thread per channel doesn't complicate things. It helps to keep the logic simple. You need to sleep before sending a response? Just sleep. The other threads will manage their own tasks.
"I haven't seen any CPU mentioned."
"is it possible to increase FIFO of usart of stm32f10x MCU?"
Ah. I missed that.
Thanks for your help I started DMA with USART successfully. I was wondering if I set input buffer to(for example a packet)100 chars and I receive 50 chars instead of 100 chars (because of any disconnection).After that it will add the new packet with the old one and the arise an interrupt.(half from the old connection and half from new connection)
I think to use an interrupt to detect the start bit of USART communication and then initialize DMA but as I see my CPU should check each input byte and active dma (it's too boring)
what's your idea to save DMA's advantages and prevent the above problem?
DMAStruc.DMA_PeripheralBaseAddr=(uint32_t) &USART1->DR; DMAStruc.DMA_MemoryBaseAddr=(uint32_t) buffer; DMAStruc.DMA_DIR=DMA_DIR_PeripheralSRC; DMAStruc.DMA_BufferSize=sizeof(buffer)-1; DMAStruc.DMA_PeripheralInc=DMA_PeripheralInc_Disable; DMAStruc.DMA_MemoryInc = DMA_MemoryInc_Enable; DMAStruc.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; DMAStruc.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte; DMAStruc.DMA_Mode=DMA_Mode_Circular; DMAStruc.DMA_Priority=DMA_Priority_High; DMAStruc.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5,&DMAStruc); USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); DMA_ITConfig(DMA1_Channel5, DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_Cmd(DMA1_Channel5, ENABLE);
Hello You assume I connect to board to each other with a long wire and under usart communication.
Now you assume we send a string with this format
[Start char][98 chars , don't contain start and stop char][Stop char]
and we can rely on our buffer value by checking start and stop chars. Now we suppose In receiver we lost one char from 98 chars therefore we get DMA interrupt when it fill up the buffer variable such as this new string [Start char][97 chars , don't contain start and stop char][Stop char][Start char] so we check start and stop chars and finally we ignore this packet and other packets ( because their first and end chars position have changed in all strings) if we don't use DMA we can fill up the buffer with incoming chars and check start and stop chars and also string length and ignore fault string without any effect on other input strings.
Do not assume that your messages will be aligned with the DMA buffers - you can't simply count characters since the user may connect the cable in the middle of a transfer or one side may reboot. So your receiving side must always be self-synchronizing. That should be a minimum requirement of a communications software.
Your program needs to either respond to transfer timeouts - i.e. transfer pauses after the end of one message and the start of a new - and to also be able to split the data depending on the actual data formattting (magical start and/or stop characters or other markup in the data).
So what was your view after having read this document? www.st.com/.../CD00256689.pdf
I have to assume that you have spent time digging through the processor documentation and also available application notes.
www.keil.com/.../ http://www.keil.com/forum/17145/
Not directly related to this thread, but maybe the OP would be interested.
-- It have been a long time, I did not become an excellent programmer. The discussion of the second URL is still too difficult to me. I am still far behind the skill level of our experts. I am a good programmer (I hope), just not excellent. The world is changing, I got another laid-off on this May, now I am working on the PIC16F platform.
Failed to post some sentences.
[ Problems were detected with the information submitted. Please correct these issues and re-submit the form.
Messages cannot contain the spam word "". ]
There are designs of mine mentioned, my designs are not good but as a reference. (Passed the censor.)