Recent

Author Topic: Prevent task interruption on Linux Raspberry  (Read 1187 times)

kupferstecher

  • Sr. Member
  • ****
  • Posts: 406
Prevent task interruption on Linux Raspberry
« on: November 09, 2017, 12:52:38 pm »
Hello,

currently I try to use a stepper motor on a raspberry pi with raspbian os.
The programm I write in Lazarus (of course:-)
As hardware driver I use a Adafruit stepper card, which contains a PWM driver for each motor connector, the PWM driver is accessed via I2C. I have trouble with lost steps and wonder if correct positioning is even possible in such a configuration. The first problem is that the change between pin-high and pin-low for each motor output is quite time consuming, even theoretically I can't even reach a speed of two revolutions per second (snails are faster...):

2 byte per channel for the on-time and 2 for the off-time = 4byte;
4byte * 4 channels = 16byte per step;
1 byte register address for each data byte:  = 32byte per step;
8bit per byte = 256 bit per step;
I2C-frequency 100000kb div 256 = 390 steps per second
Motor with 200 steps per revolution -> 1,95 revolutions per second

And these are idealized values as most of the time the outputs are in an intermediate state (always 2 outputs have to change in the same moment), which takes much reliability. Normally there should be delays in between each change. Increased I2C datarates resulted in transmission errors.

Now there is a further problem, the above calculation doesn't consider that the processing task may be interrupted by the OS.

And here comes my question:
Is it possible to temporary prevent to OS from interrupting the programm flow? So that at least both pins are switched directly one after another and don't stay in the intermediate pin state for too long?
Is it possible, if the hardware access is done in a seperate thread, that the thread is assigned to its own core on the raspi and thus may not be interrupted by the OS? the GUI, of course still has to work when the driver is busy.

In my tests (but with blocked gui) I nearly came to the 2 revolutions per second, so could be that this is no actual problem, but it doesn't seem like a robust design.

Thanks!
Regards

kupferstecher

  • Sr. Member
  • ****
  • Posts: 406
Re: Prevent task interruption on Linux Raspberry
« Reply #1 on: November 09, 2017, 05:48:48 pm »
I just tried to increase the priority of my working thread. Therefore I used a c-snipped that I found on the internet. Interfacing the c-unit was surprisingly easy, see below. When starting my programm with root, then the function result of the scheduler setting was zero, which means successfull. Nevertheless, there are still scratching noices when the motor is turning. Probably this is either due to the scheduler interrupts or due to transmission errors by the I2C interface.

Any succestions for improvement?


uScheduler.h:
Code: Diff  [Select][+][-]
  1. #ifndef USCHEDULER_H
  2. #define USCHEDULER_H
  3. #include <stdio.h>
  4. int SetTaskPriority(int prio);
  5. #endif

uScheduler.c:
Code: Diff  [Select][+][-]
  1. #include <stdio.h>
  2. #include <sched.h>
  3.  
  4. int SetTaskPriority(int prio){
  5.  const struct sched_param priority = {prio};
  6.  return sched_setscheduler(0, SCHED_FIFO, &priority);
  7. }

uScheduler.pas:
Code: Pascal  [Select][+][-]
  1. unit uScheduler;
  2. {$link uScheduler.o}
  3. {$linklib c}
  4. interface
  5. uses CTypes;
  6.  
  7. Function SetTaskPriority(APrio:ctypes.cint32): ctypes.cint32; cdecl; external;
  8.  
  9. implementation
  10. end.
Compile the uScheduler.c with the gcc (preinstalled on the raspberry):
"gcc -c uScheduler.c"
This generates a uScheduler.o. This file and the pascal has to be in the library path (project settings) then it works.

 

TinyPortal © 2005-2018