У меня возникают некоторые проблемы, когда я пытаюсь сделать многопроцессорную программу на Raspberry Pi.
Существует только два процесса: один для чтения данных из аналого-цифрового преобразователя и другой процесс, который получает эти данные по каналу и отправляет их на ПК по протоколу UDP.
Обе программы были протестированы по отдельности, и они работают очень хорошо, проблема, с которой я сталкиваюсь, заключается в том, что при попытке выполнить их через многопроцессорную программу у меня возникает ошибка сбоя сегментации, которая не позволяет мне создавать два моих процесса. Ошибка появляется при вызове функции 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 - это созданная мною функция, которая запрашивает два параметра (значение с плавающей запятой и вектор символа) и преобразует значение с плавающей запятой в ASCII и сохраняет его в вектор.
Что касается функции addstringsADCv2, она просто получает несколько векторов символов и помещает их в один, который больше.
Заранее спасибо за любую возможную помощь.