3

I'm implementing a high frequency(>100kHz) Data acquisition system with an STM32F107VC microcontroller. It uses the spi peripheral to communicate with a high frequency ADC chip. I have to use an RTOS. How can I do this?

I have tried FreeRTOS but its maximum tick frequency is 1000Hz so I can't run a thread for example every 1us with FreeRTOS. I also tried Keil RTX5 and its tick frequency can be up to 1MHz but I studied somewhere that it is not recommended to set the tick frequency high because it increases the overall context switching time. So what should I do? Thanks.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • 1
    How much data do you receive at a rate of 100kHz? Is it just a 16 bit sample? What are you going to do with the data? Do you process it? Do you send it off via USB? If so, in its raw form or in aggregated form? – Codo Jul 20 '19 at 14:58
  • One more thing: What ADC chip are you using? Does it require a separate SPI communication for each sample, or can you transfer several samples at once? – Codo Jul 20 '19 at 15:01
  • 1
    You are confusing data acquisition frequency with OS tick frequency - they are not the same thing. To get a useful answer you will have to specify the ADC chip you are using. The SPI on STM32 supports DMA transfers. A practical solution will involve transferring a block of samples and processing one block while the next is being transferred. I have sampled three channels at 48ksps (total 96ksps) on that chip using blocks of 40samples, so a DMA interrupt interval of 833us, independent of the 100Hz RTOS tick. That used the on-chip ADC though. – Clifford Jul 29 '19 at 11:44
  • ">100KHz" is meaningless. Data acquisition is not meaured in Hz, but in terms of quantity of data over time. Do you mean samples-per-second? What size are the samples, what part is the ADC? What Besides that - how much greater? Do you in fact mean _at least_ 100Ksps? Why would you not use the on chip AD? It is capable of 1Msps and can use DMA. – Clifford Jul 31 '19 at 22:00

4 Answers4

5

You do not want to run a task at this frequency. As you mentioned, context switches will kill the performance. This is horribly inefficient.

Instead, you want to use buffering, interrupts and DMA. Since it's a high frequency ADC chip, it probably has an internal buffer of its own. Check the datasheet for this. If the chip has a 16 samples buffer, a 100kHz sampling will only need processing at 6.25kHz. Now don't use a task to process the samples at 6.25kHz. Do the receiving in an interrupt (timer or some signal), and the interrupt should only fill a buffer, and wake up a task for processing when the buffer is full (and switch to another buffer until the task has finished). With this you can have a task that runs only every 10ms or so. An interrupt is not a context switch. On a Cortex-M3 it will have a latency of around 12 cycles, which is low enough to be negligible at 6.25kHz.
If your ADC chip doesn't have a buffer (but I doubt that), you may be ok with a 100kHz interrupt, but put as little code as possible inside.

A better solution is to use a DMA if your MCU supports that. For example, you can setup a DMA to receive from the SPI using a timer as a request generator. Depending on your case it may be impossible or tricky to configure, but a working DMA means that you can receive a large buffer of samples without any code running on your MCU.

ElderBug
  • 5,926
  • 16
  • 25
3

I have to use an RTOS.

No way. If it's a requirement by your boss or client, run away from the project fast. If that's not possible, communicate your concerns in writing now to save your posterior when the reasons of failure will be discussed. If it's your idea, then reconsider now.

The maximum system clock speed of the STM32F107 is 36 MHz (72 if there is an external HSE quartz), meaning that there are only 360 to 720 system clock cycles between the ticks coming at 100 kHz. The RTX5 warning is right, a significant amount of this time would be required for task switching overhead.

It is possible to have a timer interrupt at 100 kHz, and do some simple processing in the interrupt handler (don't even think about using HAL), but I'd recommend investigating first whether it's really necessary to run code every 10 μs, or is it possible to offload something that it would do to the DMA or timer hardware.

  • Thanks a lot. Yes, RTOS is my own idea because it has to process an incremental encoder, drive a step motor, read from adc and send information to PC. It was my idea to use an RTOS for handling these tasks simultaneously. Do you have a better idea to implement this system? – Mostafa Ramazany Jul 20 '19 at 14:57
  • Timers can help a lot át encoder processing and motor control. Communication tasks can be supported by DMA. For each task, find out what the hardware can do. Go step by step, ask separate questions for each one when you get stuck. You might find that there is a lot less processing tó do in software as you have anticipated. – followed Monica to Codidact Jul 20 '19 at 18:50
  • @MostafaRamazany There's also a question whether you *actually* have to do all this at this frequency. At this speed, using as many already ready results will give you huge benefits, one example being using a much much slower task to process the encoder and ADC and then the timer to just drive the step motor. – J_S Jul 20 '19 at 22:04
  • @MostafaRamazany : For the system you describe, an RTOS may be entirely appropriate, (changing the tick rate however is not, and is unnecessary in any case). But you might replace the phrase _"I have to use an RTOS. How can I do this?"_ with _"How can I do this in a system having an RTOS?"_ That would invite less opinion about your constraints. – Clifford Jul 31 '19 at 22:45
2

Since you only have a few hundred cycles (instructions) between input, the typical solution is to use an interrupt to be alerted that data is available, and then the interrupt handler put the data somewhere so you can process them at your leisure. Of course if the data comes in continuously at that rate, you maybe in trouble with no time for actual processing. Depending on how much data is coming in and how frequent, a simple round buffer maybe sufficient. If the amount of data is relatively large (how large is large? Consider that it takes more than one CPU cycle to do a memory access, and it takes 2 memory accesses per each datum that comes in), then using DMA as @Elderbug suggested is a great solution as that consumes the minimal amount of CPU cycles.

2

There is no need to set the RTOS tick to match the data acquisition rate - the two are unrelated. And to do so would be a very poor and ill-advised solution.

The STM32 has DMA capability for most peripherals including SPI. You need to configure the DMA and SPI to transfer a sequence of samples directly to memory. The DMA controller has full and half transfer interrupts, and can cycle a provided buffer so that when it is full, it starts again from the beginning. That can be used to "double buffer" the sample blocks.

So for example if you use a DMA buffer of say 256 samples and sample at 100Ksps, you will get a DMA interrupt every 1.28ms independent of the RTOS tick interrupt and scheduling. On the half-transfer interrupt the first 128 samples are ready for processing, on the full-transfer, the second 128 samples can be processed, and in the 1.28ms interval, the processor is free to do useful work.

In the interrupt handler, rather then processing all the block data in the interrupt handler - which would not in any case be possible if the processing were non-deterministic or blocking, such as writing it to a file system - you might for example send the samples in blocks via a message queue to a task context that performs the less deterministic processing.

Note that none of this relies on the RTOS tick - the scheduler will run after any interrupt if that interrupt calls a scheduling function such as posting to a message queue. Synchronising actions to an RTOS clock running asynchronously to the triggering event (i.e. polling) is not a good way to achieve highly deterministic real-time response and is a particularly poor method for signal acquisition, which requires a jitter free sampling interval to avoid false artefacts in the signal from aperiodic sampling.

Your assumption that you need to solve this problem by an inappropriately high RTOS tick rate is to misunderstand the operation of the RTOS, and will probably only work if your processor is doing no other work beyond sampling data - in which case you might not need an RTOS at all, but it would not be a very efficient use of the processor.

Clifford
  • 88,407
  • 13
  • 85
  • 165