프로세스 실행 사이의 시간이 너무 긴 경우가 있는데, 최대 시간을 어떻게 설정합니까? [폐쇄]

프로세스 실행 사이의 시간이 너무 긴 경우가 있는데, 최대 시간을 어떻게 설정합니까? [폐쇄]

SPI 포트를 통해 데이터를 가져오기 위해 Raspberry Pi를 사용하고 있습니다. SPI 포트에는 A/D에서 12.8kHz로 샘플링하고 256 길이 버퍼에 샘플을 저장하도록 프로그래밍된 PIC가 연결되어 있습니다. (일시 중지 및 실행 중인 Linux 프로세스에 대처)

SPI를 읽고 파일에 쓰는 Linux 프로그램이 있습니다. 초당 몇 번씩 데이터가 손실됩니다. Linux가 C 프로그램으로 돌아가는 데 너무 오랜 시간이 걸리기 때문이라고 생각합니다.

나는 Linux(Raspbian)가 실시간이 아니며 프로세스/프로그램이 언제든지 중단될 수 있다는 것을 알고 있습니다. 이것이 바로 이러한 중단을 극복하기 위해 PIC의 버퍼를 사용하는 이유입니다.

문제는 때때로 프로그램이 기다리는 지연이 너무 커서 일부 데이터가 손실된다는 것입니다. 이는 몇 초마다 발생할 수 있습니다.

시간을 줄이거나 적어도 프로세스가 실행되는 시간 조각 사이의 최대 시간을 설정하라는 제안을 받고 싶습니다.

나는 -15와 -20의 좋은 수준에서 실행해 보았습니다.

시간 조각을 줄이는 방법이 있습니까?

파일 쓰기가 문제인 경우를 대비하여 파일 쓰기를 시도할 수 있는 메모리 디스크가 Raspbian에 있습니까?

다음은 상단의 일부 출력입니다.

top - 14:01:23 up  2:25,  3 users,  load average: 1.91, 2.09, 2.18
Tasks:  76 total,   1 running,  75 sleeping,   0 stopped,   0 zombie
%Cpu(s):  7.6 us, 28.9 sy,  0.0 ni, 63.2 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem:    185732 total,   105708 used,    80024 free,    21112 buffers
KiB Swap:   102396 total,        0 used,   102396 free,    43916 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                  
  353 root      20   0     0    0    0 D  15.3  0.0  17:01.87 spi0                                                     
13296 root       5 -15  2652 1468 1344 D  12.1  0.8   0:09.21 a.out                                                    
13386 pi        20   0  4708 2500 2064 R   1.6  1.3   0:00.40 top                                                      
 4707 pi        20   0  4176 2572 1976 S   1.0  1.4   2:48.66 watch                                                    
11547 root      20   0     0    0    0 S   0.6  0.0   0:03.59 kworker/u2:1                                             
   16 root      20   0     0    0    0 S   0.3  0.0   0:05.60 kworker/0:1                                              
 2524 pi        20   0  9288 3296 2708 S   0.3  1.8   0:00.62 sshd                                                     
12448 root      20   0     0    0    0 S   0.3  0.0   0:02.98 kworker/u2:4                                             
    1 root      20   0  2168 1368 1260 S   0.0  0.7   0:02.22 init                                                     
    2 root      20   0     0    0    0 S   0.0  0.0   0:00.00 kthreadd                                                 
    3 root      20   0     0    0    0 S   0.0  0.0   0:06.88 ksoftirqd/0                                              
    5 root       0 -20     0    0    0 S   0.0  0.0   0:00.00  

위에서 보면 a.out 및 spi0 프로세스가 가장 많은 CPU 시간을 사용하고 있지만 최대치를 초과하지는 않은 것을 볼 수 있습니다. 여기에서 내 프로세스의 호감도가 -15임을 알 수 있습니다.

실행 중인 프로세스 중 하나가 방해하고 있는 것일까요?이것은 제가 실행 중인 프로세스이고 a.out은 SPI 리더입니다.

pi@raspberrypi ~/frd/src/raspi/xcodefrd $ ps -ae
  PID TTY          TIME CMD
    1 ?        00:00:02 init
    2 ?        00:00:00 kthreadd
    3 ?        00:00:07 ksoftirqd/0
    5 ?        00:00:00 kworker/0:0H
    7 ?        00:00:00 khelper
    8 ?        00:00:00 kdevtmpfs
    9 ?        00:00:00 netns
   10 ?        00:00:00 perf
   11 ?        00:00:00 khungtaskd
   12 ?        00:00:00 writeback
   13 ?        00:00:00 crypto
   14 ?        00:00:00 bioset
   15 ?        00:00:00 kblockd
   16 ?        00:00:06 kworker/0:1
   17 ?        00:00:00 rpciod
   18 ?        00:00:00 kswapd0
   19 ?        00:00:00 fsnotify_mark
   20 ?        00:00:00 nfsiod
   26 ?        00:00:00 kthrotld
   27 ?        00:00:00 VCHIQ-0
   28 ?        00:00:00 VCHIQr-0
   29 ?        00:00:00 VCHIQs-0
   30 ?        00:00:00 iscsi_eh
   31 ?        00:00:00 dwc_otg
   32 ?        00:00:00 DWC Notificatio
   34 ?        00:00:00 kworker/0:2
   35 ?        00:00:01 mmcqd/0
   36 ?        00:00:00 VCHIQka-0
   37 ?        00:00:00 SMIO
   38 ?        00:00:00 deferwq
   40 ?        00:00:00 jbd2/mmcblk0p6-
   41 ?        00:00:00 ext4-rsv-conver
  156 ?        00:00:00 udevd
  286 ?        00:00:00 udevd
  293 ?        00:00:00 udevd
  321 ?        00:00:00 cfg80211
  353 ?        00:18:14 spi0
  411 ?        00:00:00 kworker/0:1H
 1792 ?        00:00:06 ifplugd
 1795 ?        00:00:01 ifplugd
 1797 ?        00:00:01 ifplugd
 1800 ?        00:00:00 wpa_supplicant
 1877 ?        00:00:00 dhclient
 2246 ?        00:00:00 rsyslogd
 2248 ?        00:00:00 thd
 2296 ?        00:00:00 cron
 2326 ?        00:00:00 dbus-daemon
 2393 ?        00:00:01 ntpd
 2422 ?        00:00:00 sshd
 2513 tty1     00:00:00 getty
 2514 tty2     00:00:00 getty
 2515 tty3     00:00:00 getty
 2516 tty4     00:00:00 getty
 2517 tty5     00:00:00 getty
 2518 tty6     00:00:00 getty
 2519 ?        00:00:00 getty
 2520 ?        00:00:00 sshd
 2524 ?        00:00:04 sshd
 2525 pts/0    00:00:02 bash
 2545 ?        00:00:00 sshd
 2549 ?        00:00:39 sshd
 2550 ?        00:00:13 sftp-server
 2551 ?        00:00:00 sshd
 2555 ?        00:00:00 sshd
 2556 pts/1    00:00:01 bash
 2583 ?        00:00:00 sshd
 2587 ?        00:00:03 sshd
 2588 pts/2    00:00:01 bash
 4707 pts/2    00:02:56 watch
 8843 ?        00:00:06 kworker/u2:0
11547 ?        00:00:04 kworker/u2:1
12448 ?        00:00:03 kworker/u2:4
13186 ?        00:00:03 kworker/u2:2
13295 pts/0    00:00:00 sudo
13296 pts/0    00:01:09 a.out
13690 ?        00:00:01 kworker/u2:3
14083 pts/0    00:00:00 ps

이것이 내 데이터 흐름의 모습이며 SPI 읽기 대기 시간 비트를 확인할 수 있습니다.

데이터 흐름, 샘플 3850의 약 절반 기간 동안 누락된 데이터를 볼 수 있습니다.

물론 내 코드를 살펴보고 싶을 수도 있습니다. 다양한 버퍼 크기를 시도했습니다.

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <sys/timeb.h>
#include <time.h>
#include <sys/timeb.h>

#include "frdSPI.h"
#include "frdBuffer.h"

#define TRIGGERVAL 50

#define BUFF_SIZE 32

int main(void){

    unsigned char buffer[BUFF_SIZE];
    int i, sample, channel = 0 , triggerdifference, oldsample, qtytowriteout = 0;
    unsigned long int samplenumber=0;
    unsigned long int differencenumber=0;

    FILE *fp;
    char filename[100];

    struct timeb recordtime;


    // Following is test code to see how to make filename and use it to write a file.
    ftime( &recordtime );
    sprintf( filename, "/frd/data/%ld%03ld.startup", recordtime.time, recordtime.millitm);

    fp = fopen( filename ,"w" );
    fprintf( fp, "test and more %lu", samplenumber);
    fclose(fp);



    if ( wiringPiSPISetup (channel, 500000) < 0){
        fprintf (stderr, "SPI Setup failed! Check module is loaded and run app as root.\n");
        exit(-1);
    }

    while(1){
        wiringPiSPIDataRW ( channel, &buffer, BUFF_SIZE );

        for(i=0; i<BUFF_SIZE; i++){
            sample=parseSPIDataStream(buffer[i]);
            if( sample > -1 ){
                samplenumber++;
                oldsample = circularbufferreadwrite( sample );

                if( calculateDifferenceValue(sample, &triggerdifference))
                {
                    differencenumber++;
                    if( triggerdifference > TRIGGERVAL || triggerdifference < (-1 * TRIGGERVAL) ){
                        //printf("%d \n", triggerdifference);
                        if( qtytowriteout == 0 )
                        {
                            ftime( &recordtime );
                            sprintf( filename, "/tmp/%ld%03ld.csv", recordtime.time, recordtime.millitm);
                            fp = fopen(filename,"w");
                            samplenumber=0;
                        }
                        if( qtytowriteout < 4000 )
                            qtytowriteout = qtytowriteout + 12800;
                    }
                }

                if( qtytowriteout && (fp!=(FILE *)NULL))
                {
                    //printf("%lu,%d\n", samplenumber, oldsample);
                    fprintf(fp, "%lu,%d\n", samplenumber, oldsample);
                    qtytowriteout--;
                    if( qtytowriteout == 0 ){
                        fclose(fp);
                        printf("\b");
                    }
                }
            }
        }
    }
}

어떤 도움이나 조언이라도 미리 감사드립니다.

편집 방금 dd if=/dev/zero of=/dev/null을 실행하여 CPU 시간을 좀 소모하여 문제를 더욱 악화시켰기 때문에 올바른 방향으로 가고 있다고 생각하지만 어떻게 할 수 있는지에 대한 몇 가지 지침을 제공할 수 있습니다. 그것을 해결하기 위해. 다음은 더 많은 CPU 시간을 사용할 때의 데이터 그래프입니다.

여기에 이미지 설명을 입력하세요.

아래 설명은parseSPIDataStream을 쿼리하므로 여기에 포함합니다.

int parseSPIDataStream( char databyte ){

    static int state=0;
    static int result=0;
    static int ignorebytes=10;
    static int synced=FALSE;

    if( ignorebytes==0 )
    {

        switch( databyte )
        {
            case 0X7E:          //0x7E Filler and sync
                state=0;
                synced=TRUE;
                return(-1);

            case 0x7D:          //Next Char is escaped
                state=2;
                return(-1);

            default:
                break;
        }

        switch( state )
        {
            case 0:         //High Byte of result
                result = 256 * databyte;
                state=1;
                return(-1);

            case 1:         //Low byte of result
                result = result + databyte;
                state=0;
                if( synced )
                    return(result);
                else
                    return(-1);

            case 2:         //Escaped Low Byte
                result = result + 0x20 + databyte;
                state=0;
                if( synced )
                    return(result);
                else
                    return(-1);

            default:            //There is an error!!!
                return(-2);
        }

    }else{
        ignorebytes--;
        return(-3);
    }

}

관련 정보