Basic design question for first time using (Free)RTOS

Hi, I’ve never used an RTOS before so I’m curious how to design the task flow.

My goal is a motor application, where if a task receives a command, it starts to move the motor until it arrives at the destination which could takes up to 30 seconds. In that time, if another command is received it should stop / reverse.

So if a task, regardless of its priority, sits in a tight while(1) like loop, does FreeRTOS have the ability to wrestle away the CPU to another task? Or is it assumed that all tasks must play nice and voluntarily yield the CPU via “vTaskDelay()”

In my case, I was thinking the task would look like:

  1. wait for queue command
  2. start motor moving
  3. Continuously check position and stop when reached OR stop when new queue command is received

I’m wondering if the monitoring of the position would starve all other tasks? Any suggestions on the proper or better way of doing this?

I’d propose to get in touch with the RTOS fundamentals and maybe other FreeRTOS docs 1st and I’m sure things get clearer for you and help you to come up with a suitable design.

If you are doing it in a tight loop in a high priority task without ever relinquishing the CPU, it will starve other tasks. Would it not work if you check the position periodically?

Let me make a few comments.

“Continuously check position” isn’t the sort of thing you want to do in a real-time program, as that requires dedicating the processor to that task. Thus you should think a bit what you really need to do here, but also, think about the next question.

What does “Start motor moving” mean. This depends a LOT on the type of motor you have. Is it a DC motor, a Brushless DC Motor (where you need to handle the commutation), a Stepper Motor, or something else.
Does the processor need to control the motor, or is this really just a Run/Stop (with Direction) control. If it is just a run/stop, is the stopped position important (or does it run into a stop).

If you are actually controlling the motor as it moves, that control loop often needs to know the position to bring the motor to a stop at the desired position, at which point, your third steps is part of that control loop.

The motor is a bldc, and fortunately there’s dedicated circuitry to do the commutation. However the optical encoder is needed to make sure the CPU stops the motor precisely when the target position is reached.

After much experimenting , it seems calling vTaskDelay(1) whenever close to the target position, causes the motor to stop too late. The SPI time it takes to get the position from the encoder might also be at play.

As a though experiment, if the system were to have a CPLD/FPGA that could clock in the position continuously, and interrupt the CPU when the target is near…

could FreeRTOS be configured in such a way to

  1. Wiat for a command
  2. Start motor and periodically monitor/report position using vTaskDelay
  3. When the CPLD/FPGA interrupt the cpu (or a new command is received) the CPU takes action?

Your rough architecture can easily be done with FreeRTOS.
One method would xQueueReceive to wait for a command with a timeout. The timeout will allow you to update the status.

If you are doing a position control system, you probably want to run a high priority servo loop task that reads the position and adjusts the speed. This task can control the motion parameters of the system (acceleration, velocity, etc) and by slowing the motor down as it approaches the target position, you can ensure minimal overshoot. Since overshoot is a concern, you will need to adjust the system design to keep it under control.

The details depend upon your system.

Good Luck

1 Like