我在尝试在Raspberry Pi中执行多进程程序时遇到了一些问题。 只有两个过程:一个是从模数转换器读取数据,另一个是通过管道接收此数据并通过UDP协议将其发送到PC的过程。 这两个程序都经过单独测试,并且运行良好,我遇到的问题是,当尝试通过多进程程序执行它们时,我遇到了Segmentation Fault错误,该错误使我无法创建两个进程。调用fork()函数时出现错误。
这是我要工作的代码:
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "ADS1256_DAC8532_lib.h"
#include "addstrings2.h"
#include "changetypes.h"
#include "ReadWriteSock.h"
#include "Socket.h"
int main(){
//Variables for the first program: reading the ADC
int32_t adc[3];
uint8_t ch_num;
//variables for the UDP protocol program
struct sockaddr_in Directionwrite;
int Descriptor,aux;
struct sockaddr_in Recv;
int RecvAddrSize=sizeof(Recv);
//General variables that are needed in all our programs
int variable;
float *servo=0;
float *pressure1=0;
float *position=0;
float *pressure2=0;
char SendDataADC[11];
char press1[5];
char press2[5];
char pos[5];
char cservo[5];
int ppres1[2];
int ppres2[2];
int ppos[2];
int pservo [2];
pipe(ppres1);
pipe(ppres2);
pipe(ppos);
pipe(pservo);
if(fork()){
//Father process
bcm2835_init();
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_LSBFIRST ); // The default
bcm2835_spi_setDataMode(BCM2835_SPI_MODE1); // The default
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192); // The default
bcm2835_gpio_fsel(SPICS, BCM2835_GPIO_FSEL_OUTP);//
bcm2835_gpio_write(SPICS, HIGH);
bcm2835_gpio_fsel(DRDY, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(DRDY, BCM2835_GPIO_PUD_UP);
ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_15SPS);
ADS1256_StartScan(1);
ch_num=3;
while(1){
while((ADS1256_Scan() == 0));
for (unsigned int i = 0; i < ch_num; i++){
adc[i] = ADS1256_GetAdc(i);
adc[i] = (adc[i] * 100) / 167;
switch(i){
case 0:
*position=adc[i]<<2;
passtochar(*position,pos);
write(ppos[1],pos,4);
break; //We multiply the ADC value of our position sensor by 4 beacuse we are going to have an electronical circuit that is going to amplify our signal by a factor of 0.25 so it can be read by our Rpi
case 1:
*pressure1=adc[i];
passtochar(*pressure1,press1);
write(ppres1[1],press1,4);
break; //The pressure sensors do not need to be a,plified i order to be read, thay are only going to have a filter to reduce the amount of noise read
case 2:
*pressure2=adc[i];
passtochar(*pressure2,press2);
write(ppres2[1],press2,4);
break;
default: break;
}
}
read(pservo[0],cservo,4);
*servo=passtofloat(cservo);
*servo=*servo/8; //Si c'est entre -10 et 10 le voltage au servo, on le regle pour 0 20 et apres on l'adjustera avec un circuit electronique. 20/4 sont 5v, notre limite(trop juste, et le programme peut faire erreurs de precision), on utilise 8 pour être secures.
Write_DAC8552(0x30, Voltage_Convert(5.0, *servo));
//printf("Bucle de ADC \r\n");
usleep(1000);
}
bcm2835_spi_end();
bcm2835_close();
}
else{
//Child process
Directionwrite.sin_family = AF_INET;
Directionwrite.sin_addr.s_addr=inet_addr("169.254.51.37");
Directionwrite.sin_port = htons(59212);
Descriptor = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
printf("\n Llego");
aux=connect(Descriptor, (struct sockaddr *)&Directionwrite, sizeof (Directionwrite));
printf("\n aux=%d, aux);
while(1){
printf("Dentro del bucle socket");
read(ppres1[0],press1,4);
read(ppres2[0],press2,4);
read(ppos[0],ppos,4);
write(pservo[1],cservo,4);
addstringsADCv2(SendDataADC,press1,press2,pos);
writeSocket(Descriptor,SendDataADC,strlen(SendDataADC));
//int b=readSocket(Descriptor,servo,5);
int b=recvfrom(Descriptor, cservo,5,0,(struct sockaddr *) &Recv, &RecvAddrSize);
cservo[4]='\0';
write(pservo[1],cservo,4);
printf("\n %d", b);
printf("\n Hemos recibido el valor: %s", cservo);
}
}
}
return 0;
}
对于程序中调用的某些函数,passtochar是我创建的函数,该函数要求两个参数(浮点值和char向量),并将浮点值转换为ASCII并将其存储到向量。 至于功能addstringsADCv2,它只获取几个char向量并将它们放入一个更大的向量中。 在此先感谢您提供任何可能的帮助。