예제 #1
0
파일: tftpserver.c 프로젝트: jdaheron/GHB
/**
  * @brief  Initializes the udp pcb for TFTP 
  * @param  None
  * @retval None
  */
void tftpd_init(void)
{
  err_t err;
  unsigned port = 69;

  /* create a new UDP PCB structure  */
  UDPpcb = udp_new();
  if (UDPpcb)
  {  
    /* Bind this PCB to port 69  */
    err = udp_bind(UDPpcb, IP_ADDR_ANY, port);
    if (err == ERR_OK)
    {    
      /* TFTP server start  */
      udp_recv(UDPpcb, recv_callback_tftp, NULL);
    }
    else
    {
      _CONSOLE(LogId, "can not bind pcb");
    }
  }
  else
  {
    _CONSOLE(LogId, "can not create new pcb");
  }
}
예제 #2
0
파일: Hygrometrie.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Hygrometrie_Management(void)
{
	// Verification periodique
	if (TSW_IsFinished(&This.TmrMngt) == FALSE)
	{
		return;
	}
	TSW_ReStart(&This.TmrMngt);


	if (This.Etat == Etat_INACTIF)
	{
		if ((TSW_IsRunning(&This.TmrTempo) == FALSE)
		&&	(Hygrometrie < This.Cfg_SeuilStart_Deg))
		{
			This.Etat = Etat_ACTIF;
		}
	}
	else
	{
		if (Hygrometrie >= This.Cfg_SeuilStop_Deg)
		{
			TSW_Start(&This.TmrTempo, 1000 * This.Cfg_TempoApresProd_s);
			This.Etat = Etat_INACTIF;
		}
	}

	// Maj de l'etat de la sortie
	if (GPIO_Get(This.GPIO) != This.Etat)
	{
		_CONSOLE(LogId, "GPIO Hygro = %d\n", This.Etat);
		GPIO_Set(This.GPIO, This.Etat);
		Logs_Data();
	}
}
예제 #3
0
void TempHygro_Read(void)
{
	int16_t Temp;
	uint16_t Humid;


	// Read Error
	if (AM23xx_Read(&Temp, &Humid) == FALSE)
	{
		TempHygro.NbReadError++;
		if (TempHygro.NbReadError >= TEMPHYGRO_NB_READ_ERROR_MAX)
		{
			TempHygro.NbReadError = TEMPHYGRO_NB_READ_ERROR_MAX;
			TempHygro.IsValide = FALSE;
		}
		_CONSOLE(LogId, "Read ERROR = %d\n", TempHygro.NbReadError);
	}
	// Read OK
	else
	{
		TempHygro.NbReadError = 0;
		TempHygro.IsValide = TRUE;

		TempHygro.TempAcquisition[TempHygro.iAcquisition] = Temp;
		TempHygro.HygroAcquisition[TempHygro.iAcquisition] = Humid;

		TempHygro.iAcquisition++;
		if (TempHygro.iAcquisition >= TEMPHYGRO_NB_ECH)
		{
			TempHygro.iAcquisition = 0;
		}
	}
}
예제 #4
0
void DatabaseEeprom_Display(DatabaseEeprom_Data_e DatabaseEeprom_Data, void* pData)
{
	DatabaseEeprom_s* pDB;
	uint8_t* pTxData;


	if (DatabaseEeprom_Data >= NB_DatabaseEeprom)
	{
		return;
	}

	//--------------------------------------
	// Preparation
	pDB = &DatabaseEeprom[DatabaseEeprom_Data];
	pDB->pData = pData;
	pTxData = (uint8_t*) pDB->pData;

	_CONSOLE(LogId, "StartAddress = 0x%04X\n",	pDB->StartAddress	);
	_CONSOLE(LogId, "Size         = %d\n",		pDB->Size			);
	_CONSOLE(LogId, "Num          = %d\n",		pDB->Num			);
	_CONSOLE(LogId, "Checksum     = 0x%02X\n",	pDB->Checksum		);
	_CONSOLE(LogId, "Data         = %02X ",		pTxData[0]			);

	for (int i=1; i<pDB->Size; i++)
	{
		_CONSOLE(NULL, "%02X ",  pTxData[i]);
	}
	_CONSOLE(NULL, "\n");
}
예제 #5
0
/**
 ***************************************************************************************************
 * @todo Validation
 */
Status_e
DatabaseEeprom_Write(
		DatabaseEeprom_Data_e	DatabaseEeprom_Data,	/**<[in] Index de la donnees dans la base.*/
		void*					pData					/**<[out] Pointeur vers les donnees a ecrire.*/
)
{
	DatabaseEeprom_s* pDB;

	if (DatabaseEeprom_Data >= NB_DatabaseEeprom)
		return Status_KO;

	//--------------------------------------
	// Preparation
	pDB = &DatabaseEeprom[DatabaseEeprom_Data];
	pDB->pData = pData;

	//--------------------------------------
	// Verif premiere lecture effectuee
	if(pDB->First_Read_Done == FALSE)
		DatabaseEeprom_Read(DatabaseEeprom_Data, pData);

	//--------------------------------------
	// Ecriture des donnees

	_CONSOLE(LogId, "DatabaseEeprom_Write\n");

	// Incrementation du numero de sauvegarde
	pDB->Num++;

	// Selection de l'emplacement de destination
	pDB->CurrentSpace++;
	if (pDB->CurrentSpace > 1)
		pDB->CurrentSpace = 0;

	_CONSOLE(LogId, "CurrentSpace=%d\n", pDB->CurrentSpace);

	// Enregistrement en EEPROM
	if ((pDB->CurrentSpace == 0) || (pDB->UseBkp == FALSE))
		WriteData(pDB->StartAddress, pDB);
	else
		WriteData(pDB->StartAddress + ALIGN_PAGE(pDB->Size), pDB);

	return Status_OK;
}
예제 #6
0
/**-----------------------------------------------------------------------------
 * @brief	Verification de la validite d'une donnee de la base.
 *
 */
static Bool_e IsValide(DatabaseEeprom_s* pDB)
{
	uint8_t Checksum_calcule;

	// Verification Checksum
	Checksum_calcule = (uint8_t) Checksum_CalculComplementA2((uint8_t*) pDB->pData, pDB->Size);
	if (pDB->Checksum != Checksum_calcule)
	{
		_CONSOLE(LogId, "Checksum error\n");
		return FALSE;
	}

	return TRUE;
}
예제 #7
0
파일: Arrosage.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Arrosage_Management(void)
{
	// Verification periodique
	if (TSW_IsFinished(&This.TmrMngt) == FALSE)
	{
		return;
	}
	TSW_ReStart(&This.TmrMngt);


	// Arrosage en cours
	if (TSW_IsRunning(&This.TmrActif) == TRUE)
	{
		This.Etat = Etat_ACTIF;
	}
	else
	{
		Arrosage_LaunchDbg();

		This.Etat = Etat_INACTIF;

		if ((This.Cfg_Intervalle_h > 0)
		&&	(RTC_GetTimestamp() >= This.TS_Suivant))
		{
			Arrosage_Start(This.Cfg_VolumeParPlant_ml);
			This.Cfg_SaveNeeded = TRUE;
		}
	}

	// Maj de l'etat de la sortie
	if (GPIO_Get(This.GPIO) != This.Etat)
	{
		_CONSOLE(LogId, "GPIO Arrosage = %d\n", This.Etat);
		GPIO_Set(This.GPIO, This.Etat);
		Logs_Data();
	}

	// Sauvegarde si necessaire
	if (This.Cfg_SaveNeeded == TRUE)
	{
		DatabaseEeprom_Write(DatabaseEeprom_Arrosage, &This);
		This.Cfg_SaveNeeded = FALSE;
	}
}
예제 #8
0
파일: Arrosage.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
uint32_t Arrosage_Start(uint32_t VolumeParPlant_ml)
{
	uint32_t Duree_s;


	if ((VolumeParPlant_ml == 0)
	||	(This.Cfg_DebitPompe_ml_par_h == 0))
	{
		TSW_Stop(&This.TmrActif);
		return 0;
	}

	// Calcul de la duree
	Duree_s  = VolumeParPlant_ml * This.Cfg_NbPlants;
	Duree_s *= 3600;
	Duree_s /= This.Cfg_DebitPompe_ml_par_h;

	// Mise a jour des donnees
	This.TS_Precedent	= RTC_GetTimestamp();
	This.TS_Suivant		= This.TS_Precedent + This.Cfg_Intervalle_h * 3600;
	if (This.VolumeRestant_ml > VolumeParPlant_ml * This.Cfg_NbPlants)
	{
		This.VolumeRestant_ml -= VolumeParPlant_ml * This.Cfg_NbPlants;
	}
	else
	{
		This.VolumeRestant_ml = 0;
	}

	// Sauvegarde des donnees
	//Parametres_Write(&Conf_IniFile,	Conf_ARR_VolumeRestant_ml		,	&This.VolumeRestant_ml		);
	//Parametres_Write(&Conf_IniFile,	Conf_ARR_TS_Precedent			,	&This.TS_Precedent			);
	//Parametres_Write(&Conf_IniFile,	Conf_ARR_TS_Suivant				,	&This.TS_Suivant			);

	// Envoi des infos
	_CONSOLE(LogId, "--- ARROSAGE START ---\n");
	_CONSOLE(LogId, "VolumeParPlant_ml   = %d\n",	VolumeParPlant_ml			);
	_CONSOLE(LogId, "Duree_s             = %d\n",	Duree_s						);
	_CONSOLE(LogId, "VolumeRestant_ml    = %d\n",	This.VolumeRestant_ml		);
	_CONSOLE(LogId, "TS_Precedent        = %d\n",	This.TS_Precedent			);
	_CONSOLE(LogId, "TS_Suivant          = %d\n",	This.TS_Suivant				);

	// Lancement arrosage
	TSW_Start(&This.TmrActif, Duree_s * 1000);

	This.Cfg_SaveNeeded = TRUE;

	return Duree_s;
}
예제 #9
0
파일: Logs.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Logs_Data(void)
{
	char LogBuffer[255];
	int16_t Temperature_DegC;


	// Mode, Temperature
	if (TempHygro_IsValide() == FALSE)
	{
		_sprintf(LogBuffer, "%d;%d;%d;%d;%d;%d,%d;%;%d,%d;",
				Mode, EtatVentillation, EtatChauffage, Arrosage_Get()->Etat, Hygrometrie_Get()->Etat,
				-100, 0,
				-100, 0
		);
	}
	else
	{
		_sprintf(LogBuffer, "%d;%d;%d;%d;%d;%d,%d;%;%d,%d;",
				Mode, EtatVentillation, EtatChauffage, Arrosage_Get()->Etat, Hygrometrie_Get()->Etat,
				(uint16_t) Temperature,
				(uint16_t) (Temperature * 10) % 10,
				(uint16_t) Hygrometrie,
				(uint16_t) (Hygrometrie * 10) % 10
		);
	}

	_CONSOLE(LogId, "LOG:%s\n", LogBuffer);
	LogFile_Write("", 0, LogBuffer);

	if ((Mode == MODE_CHAUFFAGE)
	||	(Mode == MODE_VENTILLATION)
	||	(Arrosage_Get()->Etat == Etat_ACTIF)
	||	(Hygrometrie_Get()->Etat == Etat_ACTIF))
	{
		TSW_Start(&Tmr_LOG, 1000 * LOG_DELAI_PENDANT_ACTION_s);
	}
	else
	{
		TSW_Start(&Tmr_LOG, 1000 * LOG_DELAI_s);
	}
}
예제 #10
0
파일: main.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
int main(void)
{
	Bool_e NouveauMode;
	Horodatage_s Time = {
			.Heure = 0,
			.Minute = 0,
			.Seconde = 0,
	};


	// ------------------------------------------------------------------------
	// --- INIT DU SYSTEME
	// --- Initialisations uC, Peripheriques, Fonctions et Interfaces
	BSP_Init();									// Init carte
	SysTick_Config(SystemCoreClock / 1000);		// Init Tick 1ms
	HAL_Console_Init(115200);
	RTC_StartInit(TRUE);						// Start Init RTC
	I2C1_Init(100 * 1000);						// 100kHz
	ADC1_Init();

	_CONSOLE(0, "\n");
	_CONSOLE(LogId, "--- START - ALJ%s ---\n", VERSION_SW);

	//AM23xx_Test();

	REGLAGE_RTC();

	//----------------------------------
	// FONCTIONNALITES
	MemoireFAT_Init((Diskio_drvTypeDef*) &SdCard_SPI_Driver);
	#if USE_TEMP_HYGRO
		TempHygro_Init(TEMPERATURE_PERIODE_ACQUISITION_ms);
	#endif
	Delay_ms(50);

//	Hygrometre_Init();
	ConfIni_Init();
	Arrosage_Init(USE_CONF_INI_FILE);
	Chauffage_Init(USE_CONF_INI_FILE);
	Ventilation_Init(USE_CONF_INI_FILE);
	Logs_Init();

	PC_Init();
	Terminal_Init();
	Terminal_Cmd_Init();

	//_CONSOLE(LogId, "MODE_FCT_SERVEUR\n");
	ModeFct = MODE_FCT_SERVEUR;
	//MemoireFAT_PrintFileList("httpserver");
	Ethernet_Init(USE_CONF_INI_FILE);

	if (RTC_BkpRegister_Read(0) != 0)
	{
		_CONSOLE(LogId, "MODE_FCT_USB\n");
		ModeFct = MODE_FCT_USB;
		//USB_Init((Diskio_drvTypeDef*) &SdCard_SPI_Driver);
		RTC_BkpRegister_Write(0, 0);
	}

	// Lancement des timers
	TSW_Start(&TmrAffichTempHygro, 3000);


	//Mode_Test();

	WDG_InitWWDG(10000);

	while (RTC_Main() != RTC_ETAPE_READY);
	TSW_Start(&Tmr_RTC, 10000);
	RTC_Lire(&StartTime);
	RTC_Lire(&Time);


	//--------------------------------------------------------------------------------
	_CONSOLE(LogId, "--------------------------\n");
	_CONSOLE(LogId, "StartupTime=%dms\n", TSW_GetTimestamp_ms());
	_CONSOLE(LogId, "--------------------------\n\n");
		while(1)
	{
		WDG_Refresh();

//		if (PC_Read((uint8_t*) BufferIn, NULL) == TRUE)
//		{
//			Terminal_Parser(BufferIn, BufferOut, 1024);
//			if (strlen(BufferOut) > 0)
//				PC_Write(BufferOut, strlen(BufferOut));
//		}

		// Choix du mode de fonctionnement
		// WKUP = ACTIF -> USB  -  WKUP = INACTIF -> WebServer
		//if (GPIO_Get(PORT_WKUP) == Etat_ACTIF)
		//{
		//	RTC_BkpRegister_Write(0, 1);
		//	while (GPIO_Get(PORT_WKUP) == Etat_ACTIF)
		//		TSW_Delay(100);
		//	GOTO(0);
		//}

		//----------------------------------
		// PROCESSUS
		LifeBit_Main();
		MemoireFAT_Main();
		#if USE_TEMP_HYGRO
			TempHygro_Thread();
		#endif

		if (Mode != MODE_DEMARRAGE)
		{
			Arrosage_Management();
			Chauffage_Management();
			Ventilation_Management();
			Hygrometrie_Management();
		}

		if (ModeFct == MODE_FCT_SERVEUR)
		{
			Ethernet_Management();
		}

		Logs_Management();


		//----------------------------------
		// LECTURE TEMPERATURE
		if ((TempHygro_IsValide() == FALSE)
		&&	(Mode != MODE_DEMARRAGE))
		{
			Mode = MODE_DEFAUT;
		}
		else
		{
			Temperature = TempHygro_GetTemperature();
			Hygrometrie = TempHygro_GetHygrometrie();
		}

		//----------------------------------
		// RTC
		if (TSW_IsFinished(&Tmr_RTC))
		{
			RTC_Lire(&Time);
			TSW_ReStart(&Tmr_RTC);

			//_CONSOLE(LogId, "RTC = %d-%02d-%02d %02d:%02d:%02d;%08d;",
			//				Time.Annee, Time.Mois, Time.Jour,
			//				Time.Heure, Time.Minute, Time.Seconde,
			//				TSW_GetTimestamp_ms());
		}


		//----------------------------------
		// AFFICHAGE TEMPERATURE
/*		if (TSW_IsRunning(&TmrAffichTempHygro) == FALSE)
		{
			_CONSOLE(LogId, "TempHygro = ");
			if (TempHygro_IsValide() == FALSE)
				_CONSOLE(LogId, "Non valide\n");
			else
			{
				_CONSOLE(LogId, "%.01f %c\t%.01f %c\n",
						Temperature, '°',
						Hygrometrie, '%');
			}

			TSW_Start(&TmrAffichTempHygro, 2500);
		}
*/


		//----------------------------------
		// GESTION DES MODES
		NouveauMode = FALSE;
		if (LastMode != Mode)
		{
			LastMode = Mode;
			NouveauMode = TRUE;
		}

		switch (Mode)
		{
			//--------------------------------------------------------------
			case MODE_DEMARRAGE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_DEMARRAGE -----\n");
					Logs_Data();
				}

				if (Mode_Demarrage() == Status_Fini)
				{
					Mode = MODE_SURVEILLANCE;
				}

				break;


			//--------------------------------------------------------------
			case MODE_SURVEILLANCE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_SURVEILLANCE -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					EtatVentillation	= Etat_INACTIF;
					EtatChauffage		= Etat_INACTIF;

					TSW_Start(&Tmr_ATTENTE, 1000 * 30); // On reste au moins 30sec en mode attente
				}

				if (TSW_IsRunning(&Tmr_ATTENTE) == TRUE)
				{
					break;
				}

				// Pas de chauffage dessuite après l'extraction
				if ((TSW_IsRunning(&Tmr_EXT) == FALSE)
				&&	(Temperature < Chauffage_Get()->Cfg_SeuilStart_DegC))
				{
					Mode = MODE_CHAUFFAGE;
				}

				// Pas d'extraction dessuite après le chauffage
				if ((TSW_IsRunning(&Tmr_CH) == FALSE)
				&&	(Temperature >= Ventilation_Get()->Cfg_SeuilStart_DegC))
				{
					Mode = MODE_VENTILLATION;
				}

				break;


			//--------------------------------------------------------------
			case MODE_CHAUFFAGE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_CHAUFFAGE -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					if (Ventilation_Get()->Cfg_ActiverPendantChauffage)
						EtatVentillation = Etat_ACTIF;
					else
						EtatVentillation = Etat_INACTIF;
					EtatChauffage = Etat_ACTIF;
				}

				// Attente franchissement seuil
			if (Temperature >= Chauffage_Get()->Cfg_SeuilStop_DegC)
				{
					EtatChauffage = Etat_INACTIF;

					TSW_Start(&Tmr_CH, 1000 * Chauffage_Get()->Cfg_TempoApresCh_s);
					Mode = MODE_SURVEILLANCE;
				}

				break;

			//--------------------------------------------------------------
			case MODE_VENTILLATION :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_VENTILLATION -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					EtatChauffage = Etat_INACTIF;
					EtatVentillation = Etat_ACTIF;
				}

				if (Temperature < Ventilation_Get()->Cfg_SeuilStop_DegC)
				{
					EtatVentillation = Etat_INACTIF;

					TSW_Start(&Tmr_EXT, 1000 * Ventilation_Get()->Cfg_TempoApresEXT_s);
					Mode = MODE_SURVEILLANCE;
				}

				break;

			//--------------------------------------------------------------
			case MODE_DEFAUT :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_DEFAUT -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_ACTIF);

					EtatVentillation 	= Etat_INACTIF;
					EtatChauffage		= Etat_INACTIF;
					//Arrosage_Stop();

					TSW_Start(&Tmr_DEFAULT, 60 * 1000);
					TSW_Start(&Tmr_DEFAULT_Max, 600 * 1000);
				}

				if (TempHygro_IsValide() == TRUE)
				{
					Mode = MODE_VENTILLATION;
					break;
				}

				if ((TSW_IsRunning(&Tmr_DEFAULT) == FALSE)
				&&	(REBOOT_ON_DEFAULT_MODE == TRUE)
				&&	(Arrosage_IsActive() == FALSE))
				{
					if ((Telnet_GetNbActiveConnection() == 0)
					||	(TSW_IsRunning(&Tmr_DEFAULT_Max) == FALSE))
					{
						_CONSOLE(LogId, "REBOOT...\n");
						MemoireFAT_DeInit();
						TSW_Delay(5000);
						GOTO(0);
						Mode = MODE_DEMARRAGE;
					}
				}
				break;

		}

		//----------------------------------
		// MAJ DES SORTIES
		if (GPIO_Get(PORT_RELAIS_V_EXT) != EtatVentillation)
		{
			_CONSOLE(LogId, "Ventillation = %d\n", EtatVentillation);
			GPIO_Set(PORT_RELAIS_V_EXT, EtatVentillation);
			Logs_Data();
		}
		if (GPIO_Get(PORT_RELAIS_CH) != EtatChauffage)
		{
			_CONSOLE(LogId, "Chauffage = %d\n", EtatChauffage);
			GPIO_Set(PORT_RELAIS_CH, EtatChauffage);
			Logs_Data();
		}
	}

	return 0;

}


/*------------------------------------------------------------------------------------------------*/
extern void SdCard_SPI_timerproc (void);

void ApplicationTickHook (void) {

	static uint8_t ucTick_10ms=0;
	static uint8_t ucTick_100ms=0;


	/* Gestion du Tick Timer Software */
	TSW_Refresh();

	/* Tick 10ms */
	ucTick_10ms++;
	if (ucTick_10ms >= 10){
		ucTick_10ms = 0;
		ADC1_Tick();
		SdCard_SPI_timerproc();
	}

	/* Tick 100ms */
	ucTick_100ms++;
	if (ucTick_100ms >= 10){
		ucTick_100ms = 0;

	}
}


/*------------------------------------------------------------------------------------------------*/
void Delay(uint32_t nCount)
{
  /* Capture the current local time */
  uint32_t timingdelay = TSW_GetTimestamp_ms() + nCount;

  /* wait until the desired delay finish */
  while(timingdelay > TSW_GetTimestamp_ms())
  {
  }
}
예제 #11
0
int main(int argc,char* argv[]){

  /**Initialize signal**/

  signal(SIGINT ,_end_server);
  signal(SIGUSR1,_end_server);

  /**Initialize struct proc**/
  init_proc();
  init_cons();

  /**Process becomes dem**/
  pid_t process_id = 0;
  pid_t sid = 0;

  if(argc >= 2){

    process_id = fork();

    if(process_id < 0){
      printf("fork failed ..\n");
      exit(1);
    }

    if(process_id > 0){
      exit(0);
    }

    umask(0);

    sid = setsid();

    if(sid < 0){
      exit(1);
    }

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

  }else{
    sid = getpid();
  }

  /**Setup the log file**/

  char log[32];

  sprintf(log,"log.%u",sid);

  //  fp = fopen(log,"w+");

  /**Start Initialize nvidia management library from Here!!**/

  nvmlReturn_t nres;
  int i;
  
  nres = nvmlInit();

  if(nres != NVML_SUCCESS){
    perror("Failed to initialize Nvidia Managerment Library...\n");
    exit(-1);
  }

  nres = nvmlDeviceGetCount(&dem.ndev);

  if(nres != NVML_SUCCESS){
    perror("Failed to get num of device...\n");
    exit(-1);
  }

  dem.devs = (nvmlDevice_t*)malloc(sizeof(nvmlDevice_t)*dem.ndev);
  dem.flags = (dflag*)malloc(sizeof(dflag)*dem.ndev);

  MAXPROC = dem.ndev * 4;

  for(i = 0 ; i < dem.ndev ; i ++){

    nres = nvmlDeviceGetHandleByIndex(i,&dem.devs[i]);

    if(nres != NVML_SUCCESS){
      perror("Failed to get device handle\n");
      exit(-1);
    }

    dem.flags[i].sd = -1;
    dem.flags[i].flag = 0;
    dem.flags[i].stayed = 0;
    dem.flags[i].reserved = 0;
  }

  dem.procCounter = 0;

  /**Setup the socket**/

  int len,rc,on = 1;
  int listen_sd,max_sd,new_sd;
  int desc_ready;
  int close_conn;

  struct sockaddr_un addr;
  struct timeval timeout;
  fd_set master_set,working_set;

  listen_sd = socket(AF_UNIX,SOCK_STREAM,0);

  if(listen_sd < 0){
    perror("socket() failed\n");
    exit(-1);
  }

  rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (char*)&on,sizeof(on));

  if(rc < 0){
    perror("setsockopt() failed\n");
    exit(-1);
  }

  unlink("mocu_server");

  memset(&addr,0,sizeof(addr));

  addr.sun_family = AF_UNIX;
  strcpy(addr.sun_path,"mocu_server");

  rc = bind(listen_sd,(struct sockaddr*)&addr,sizeof(addr));

  if(rc < 0){
    perror("bind() failed");
    close(listen_sd);
    exit(-1);
  }

  rc = listen(listen_sd,SOMAXCONN);

  if(rc < 0){
    perror("listen() failed");
    close(listen_sd);
    exit(-1);
  }

  FD_ZERO(&master_set);
  max_sd = listen_sd;
  FD_SET(listen_sd,&master_set);

  timeout.tv_sec = 3*60;
  timeout.tv_usec = 0;

  long counter = 0;

  /**Entering main loop**/
  proc_data* receivedProc = (proc_data*)malloc(sizeof(proc_data));

  mocu_check();

  do{

    memcpy(&working_set,&master_set,sizeof(master_set));

    rc = select(max_sd+1, &working_set, NULL, NULL, NULL);

    if(rc < 0){
      perror("select() failed\n");
      break;
    }

    if(rc == 0){
      printf("select() time out. End program.\n");
      break;
    }

    desc_ready = rc;

    for(i = 0 ; i < max_sd+1 && desc_ready > 0 ; ++i){
      
      if(FD_ISSET(i,&working_set)){

	desc_ready = -1;

	if(i == listen_sd){

	  new_sd = accept(listen_sd,NULL,NULL);

	  if(new_sd < 0){
	    printf("accept() failed");
	    end_server = TRUE;
	  }

	  FD_SET(new_sd,&master_set);

	  if(new_sd > max_sd){
	    max_sd = new_sd;
	  }

	}else{

	  rc = recv(i,receivedProc,sizeof(proc_data),0);

	  if(rc <= 0){

	    FD_CLR(i,&master_set);

	    _FIN(i);

	  }else{

	    if(receivedProc->REQUEST == CONNECT){

	      _CONNECT(i,receivedProc);

	    }else if(receivedProc->REQUEST == RENEW){

	      _RENEW(i,receivedProc);
	      
	    }else if(receivedProc->REQUEST == MIGDONE){

	      _MIGDONE(i,receivedProc);
	      
	    }else if(receivedProc->REQUEST == CANRECEIVE){

	      _CANRECEIVE(i,receivedProc);
	      
	    }else if(receivedProc->REQUEST == FAILEDTOALLOC){

	      _FAILEDTOALLOC(i,receivedProc);

	      exit(-1);//TEST
	      
	    }else if(receivedProc->REQUEST == MALLOCDONE){

	      _MALLOCDONE(i,receivedProc);

	    }else if(receivedProc->REQUEST == CUDAMALLOC){

	      _CUDAMALLOC(i,receivedProc);

	    }else if(receivedProc->REQUEST == BACKUPED){

	      _BACKUPED(i,receivedProc);
	      
	    }else if(receivedProc->REQUEST == CONTEXT_CHECK){

	      _CONTEXT_CHECK(i,receivedProc);
	      
	    }else if(receivedProc->REQUEST == CREATE_CONTEXT){

	      _CREATE_CONTEXT(i);

	    }else if(receivedProc->REQUEST == CONSOLE){

	      _CONSOLE(i);
	      
	    }else{
	      printf("Unkown request...\n");
	      exit(-1);
	    }
	  }
	}
      }
    }

    mocu_check();

  }while(end_server == FALSE);

  int closed = 0;

  for(i = 0 ; i < max_sd ; i ++){
    if(FD_ISSET(i,&master_set)){
      close(i);
      closed = 1;
    }
  }

  //  fclose(fp);

  return 0;
}
예제 #12
0
/**
  * @brief  ETH_BSP_Config
  * @param  None
  * @retval None
  */
void ETH_BSP_Config(void)
{
#if 0
  RCC_ClocksTypeDef RCC_Clocks;
  
  /* Configure the GPIO ports for ethernet pins */
  ETH_GPIO_Config();
  
  /* Configure the Ethernet MAC/DMA */
  ETH_MACDMA_Config();

  if (EthInitStatus == 0)
  {
    _printf("Ethernet Init failed\n");
    while(1);
  }

  /* Configure the PHY to generate an interrupt on change of link status */
  //Eth_Link_PHYITConfig(DP83848_PHY_ADDRESS);
  Eth_Link_PHYITConfig(KS8721_PHY_ADDRESS);

  /* Configure the EXTI for Ethernet link status. */
  //Eth_Link_EXTIConfig();
#else

	ETH_InitTypeDef ETH_InitStructure;

	/* Enable ETHERNET clocks  */
	RCC_AHB1PeriphClockCmd(	  RCC_AHB1Periph_ETH_MAC
							| RCC_AHB1Periph_ETH_MAC_Tx
							| RCC_AHB1Periph_ETH_MAC_Rx
							| RCC_AHB1Periph_ETH_MAC_PTP, ENABLE);

	/* Enable SYSCFG clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	/*Select RMII Interface*/
	SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);

	/* Reset ETHERNET on AHB Bus */
	ETH_DeInit();

	/* Software reset */
	ETH_SoftwareReset();

	/* Wait for software reset */
	while (ETH_GetSoftwareResetStatus() == SET);

	/* ETHERNET Configuration ------------------------------------------------------*/
	/* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
	ETH_StructInit(&ETH_InitStructure);

	/* Fill ETH_InitStructure parametrs */
	/*------------------------   MAC   -----------------------------------*/
	ETH_InitStructure.ETH_AutoNegotiation			= ETH_AutoNegotiation_Disable  ;
	ETH_InitStructure.ETH_Speed						= ETH_Speed_100M;
	ETH_InitStructure.ETH_LoopbackMode				= ETH_LoopbackMode_Disable;
	ETH_InitStructure.ETH_Mode						= ETH_Mode_FullDuplex;
	ETH_InitStructure.ETH_RetryTransmission			= ETH_RetryTransmission_Disable;
	ETH_InitStructure.ETH_AutomaticPadCRCStrip		= ETH_AutomaticPadCRCStrip_Disable;
	ETH_InitStructure.ETH_ReceiveAll				= ETH_ReceiveAll_Enable;
	ETH_InitStructure.ETH_BroadcastFramesReception	= ETH_BroadcastFramesReception_Disable;
	ETH_InitStructure.ETH_PromiscuousMode			= ETH_PromiscuousMode_Disable;
	ETH_InitStructure.ETH_MulticastFramesFilter		= ETH_MulticastFramesFilter_Perfect;
	ETH_InitStructure.ETH_UnicastFramesFilter		= ETH_UnicastFramesFilter_Perfect;

	unsigned int PhyAddr;
	uint16_t reg2;
	uint16_t reg3;

	// read the ID for match
	for (PhyAddr = 1; 32 >= PhyAddr; PhyAddr++)
	{
		reg2 = ETH_ReadPHYRegister(PhyAddr,2);	//PHY_MICR_INT_EN ?
		reg3 = ETH_ReadPHYRegister(PhyAddr,3);

		if ((reg2 == 0x0022) && (reg3 == 0x1609))
			break;
	}

	if (PhyAddr > 32)
	{
		_CONSOLE(LogId, "Ethernet Phy Not Found\n\r");
		return;// 1;
	}

	/* Configure Ethernet */
	if (ETH_Init(&ETH_InitStructure, PhyAddr) == 0)
	{
		_CONSOLE(LogId, "Ethernet Initialization Failed\n\r");
		return;// 1;
	}

	_CONSOLE(LogId, "Check LAN LEDs\n\r");
  
#endif
}
예제 #13
0
파일: tftpserver.c 프로젝트: jdaheron/GHB
/**
  * @brief  processes the tftp request on port 69
  * @param  pkt_buf: pointer on received pbuf
  * @param  ip_addr: pointer on source IP address
  * @param  port: pointer on source udp port
  * @retval None
  */
void process_tftp_request(struct pbuf *pkt_buf, struct ip_addr *addr, u16_t port)
{
  tftp_opcode op = tftp_decode_op(pkt_buf->payload);
  char FileName[30];
  struct udp_pcb *upcb;
  err_t err;

  /* create new UDP PCB structure */
  upcb = udp_new();
  if (!upcb)
  {     
    /* Error creating PCB. Out of Memory  */
    return;
  }

  /* bind to port 0 to receive next available free port */
  /* NOTE:  This is how TFTP works.  There is a UDP PCB for the standard port
   * 69 which al transactions begin communication on, however all subsequent
   * transactions for a given "stream" occur on another port!  */
  err = udp_bind(upcb, IP_ADDR_ANY, 0);
  if (err != ERR_OK)
  {    
    /* Unable to bind to port   */
    return;
  }
  switch (op)
  {
    case TFTP_RRQ:/* TFTP RRQ (read request)  */
    {
      /* Read the name of the file asked by the client to be sent from the SD card */
      tftp_extract_filename(FileName, pkt_buf->payload);

      _CONSOLE(LogId, "TFTP_RRQ:%s\n", FileName);

      /* could not open filesystem */
      if (f_mount(&filesystem, "", 0) != FR_OK)
      {
        return;
      }
      /* could not open the selected directory */
      if (f_opendir(&dir_1, "/") != FR_OK)
      {
        return;
      }
      /* Start the TFTP read mode*/
      tftp_process_read(upcb, addr, port, FileName);
      break;
    } 

    case TFTP_WRQ:    /* TFTP WRQ (write request)   */
    {
      /* Read the name of the file asked by the client to be received and writen in the SD card */
      tftp_extract_filename(FileName, pkt_buf->payload);
  
      _CONSOLE(LogId, "TFTP_WRQ:%s\n", FileName);

      /* Could not open filesystem */
      if (f_mount(&filesystem, "", 0) != FR_OK)
      {
        return;
      }
        
      /* If Could not open the selected directory */
      if (f_opendir(&dir_2, "/") != FR_OK)
      {
        return;
      }
        
      /* Start the TFTP write mode*/
      tftp_process_write(upcb, addr, port, FileName);
      break;
    }
    default: /* TFTP unknown request op */
      /* send generic access violation message */
      tftp_send_error_message(upcb, addr, port, TFTP_ERR_ACCESS_VIOLATION);
      udp_remove(upcb);

      break;
  }
}
예제 #14
0
파일: Hygrometrie.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Hygrometrie_Init(Bool_e UseConfIni)
{
	Hygrometrie_t TmpThis;
	Status_e ReadStatus;


	_CONSOLE(LogId, "---------- HYGROMETRIE INIT ----------\n");

	//----------------------------------------------------------
	// Initialisation des donnees
	DatabaseEeprom_InitData(DatabaseEeprom_Hygrometrie, NULL, sizeof(Hygrometrie_t));
	ReadStatus = DatabaseEeprom_Read(DatabaseEeprom_Hygrometrie, &TmpThis);
	DatabaseEeprom_Display(DatabaseEeprom_Hygrometrie, &TmpThis);
	if (ReadStatus == Status_KO)
	{
		_CONSOLE(LogId, "Invalid Eeprom Read: Default restored\n");
		DatabaseEeprom_Write(DatabaseEeprom_Hygrometrie, &This);
		memcpy(&TmpThis, &This, sizeof(Hygrometrie_t));
		This.Cfg_Restored = TRUE;
	}
	else
	{
		_CONSOLE(LogId, "Valid Eeprom Read \n");
		memcpy(&This, &TmpThis, sizeof(Hygrometrie_t));
		This.Cfg_Restored = FALSE;
	}


	//------------------------------------------------------
	// Comparaison avec fichier ini
	//------------------------------------------------------
/*	if ((ConfIni_Get()->IsValide == TRUE) && (UseConfIni == TRUE))
	{
		_CONSOLE(LogId, "Check SD cfg\n");

		This.Cfg_SeuilStop_Deg				= ConfIni_Get()->EXT_SeuilStop_DegC;
		This.Cfg_SeuilStart_Deg				= ConfIni_Get()->EXT_SeuilStart_DegC;
		This.Cfg_TempoApresProd_s			= ConfIni_Get()->EXT_TempoApresProd_s;
		This.Cfg_ActiverPendantChauffage	= ConfIni_Get()->EXT_ActiverPendantCh;

		if (memcmp(&TmpThis, &This, sizeof(Ventilation_t)) != 0)
		{
			_CONSOLE(LogId, "Cfg SD copied\n");
			DatabaseEeprom_Write(DatabaseEeprom_Ventilation, &This);
		}
		else
		{
			_CONSOLE(LogId, "Cfg unchanged\n");
		}
	}
*/

	//------------------------------------------------------
	// Affichage de la configuration
	//------------------------------------------------------
	_CONSOLE(LogId, "SeuilStop_DegC    = %d\n",	This.Cfg_SeuilStop_Deg				);
	_CONSOLE(LogId, "SeuilStart_DegC   = %d\n",	This.Cfg_SeuilStart_Deg				);
	_CONSOLE(LogId, "TempoApresEXT_s   = %d\n",	This.Cfg_TempoApresProd_s			);


	TSW_Start(&This.TmrTempo, 1000 * 30); // On reste au moins 30sec en mode attente

	This.GPIO = PORT_RELAIS_OPT1;
	This.Etat = Etat_INACTIF;

	// Verification toutes les 500ms
	TSW_Start(&This.TmrMngt, 500);
}
예제 #15
0
파일: Ethernet.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Ethernet_Init(Bool_e UseConfIni)
{
	Ethernet_t TmpThis;
	Status_e ReadStatus;


	_CONSOLE(LogId, "---------- CONF_ETHERNET INIT ----------\n");

	//------------------------------------------------------
	// Lecture des donnees flash
	//------------------------------------------------------
	DatabaseEeprom_InitData(DatabaseEeprom_Ethernet, NULL, sizeof(Ethernet_t));
	ReadStatus = DatabaseEeprom_Read(DatabaseEeprom_Ethernet, &TmpThis);
	DatabaseEeprom_Display(DatabaseEeprom_Ethernet, &TmpThis);
	if (ReadStatus == Status_KO)
	{
		_CONSOLE(LogId, "Invalid Eeprom Read: Default restored\n");
		DatabaseEeprom_Write(DatabaseEeprom_Ethernet, &This);
		memcpy(&TmpThis, &This, sizeof(Ethernet_t));
		This.Cfg_Restored 	= TRUE;
	}
	else
	{
		_CONSOLE(LogId, "Valid Eeprom Read \n");
		memcpy(&This, &TmpThis, sizeof(Ethernet_t));
		This.Cfg_Restored = FALSE;
	}

	//------------------------------------------------------
	// Comparaison avec fichier ini
	//------------------------------------------------------
	if ((ConfIni_Get()->IsValide == TRUE) && (UseConfIni == TRUE))
	{
		_CONSOLE(LogId, "Check SD cfg\n");

		memcpy(This.Cfg_IP_Adresse,		ConfIni_Get()->ETH_IP_Adresse, 4);
		memcpy(This.Cfg_IP_Masque,		ConfIni_Get()->ETH_IP_Masque, 4);
		memcpy(This.Cfg_IP_Passerelle,	ConfIni_Get()->ETH_IP_Passerelle, 4);
		memcpy(This.Cfg_MAC_Adresse,	ConfIni_Get()->ETH_MAC_Adresse, 6);
		This.Cfg_DHCP_Actif = ConfIni_Get()->ETH_DHCP_Actif;

		if (memcmp(&TmpThis, &This, sizeof(Ethernet_t)) != 0)
		{
			_CONSOLE(LogId, "Cfg SD copied\n");
			DatabaseEeprom_Write(DatabaseEeprom_Ethernet, &This);
		}
		else
		{
			_CONSOLE(LogId, "Cfg unchanged\n");
		}
	}


	//------------------------------------------------------
	// Affichage de la configuration
	//------------------------------------------------------
	_CONSOLE(LogId, "IP_Adresse    = %d.%d.%d.%d\n",		This.Cfg_IP_Adresse[0], This.Cfg_IP_Adresse[1], This.Cfg_IP_Adresse[2], This.Cfg_IP_Adresse[3]);
	_CONSOLE(LogId, "IP_Masque     = %d.%d.%d.%d\n",		This.Cfg_IP_Masque[0], This.Cfg_IP_Masque[1], This.Cfg_IP_Masque[2], This.Cfg_IP_Masque[3]);
	_CONSOLE(LogId, "IP_Passerelle = %d.%d.%d.%d\n", 		This.Cfg_IP_Passerelle[0], This.Cfg_IP_Passerelle[1], This.Cfg_IP_Passerelle[2], This.Cfg_IP_Passerelle[3]);
	_CONSOLE(LogId, "MAC_Adresse   = %d:%d:%d:%d:%d:%d\n",	This.Cfg_MAC_Adresse[0], This.Cfg_MAC_Adresse[1], This.Cfg_MAC_Adresse[2], This.Cfg_MAC_Adresse[3], This.Cfg_MAC_Adresse[4], This.Cfg_MAC_Adresse[5]);
	_CONSOLE(LogId, "DHCP_Actif    = %d\n",					This.Cfg_DHCP_Actif		);


	//------------------------------------------------------
	// Application de la configuration
	//------------------------------------------------------

	ETH_BSP_Config();	// Configure ethernet (GPIOs, clocks, MAC, DMA)
	LwIP_Init(This.Cfg_IP_Adresse, This.Cfg_IP_Masque, This.Cfg_IP_Passerelle, This.Cfg_DHCP_Actif, This.Cfg_MAC_Adresse);		// Initilaize the LwIP stack
	tftpd_init();		// TFTP server Init
	//httpd_init();		// Http webserver Init
	Telnet_Init();
}
예제 #16
0
/** 
 ***************************************************************************************************
 * @todo Validation
 */
Status_e
DatabaseEeprom_Read(
		DatabaseEeprom_Data_e	DatabaseEeprom_Data,	/**<[in] Index de la donnees dans la base.*/
		void*					pData					/**<[out] Pointeur vers les donnees lues.*/
)
{
	DatabaseEeprom_s* pDB;
	Bool_e Data0_valide;
	Bool_e Data1_valide;
	uint8_t Num0;
	uint8_t Num1;
	int8_t ChoixData = (-1);

	if (DatabaseEeprom_Data >= NB_DatabaseEeprom)
		return Status_KO;

	//--------------------------------------
	// Preparation
	pDB = &DatabaseEeprom[DatabaseEeprom_Data];
	pDB->pData = pData;

	if(!pDB->First_Read_Done) {
		pDB->First_Read_Done = TRUE;
	}

	//--------------------------------------
	// Lecture des donnees
	_CONSOLE(LogId, "DatabaseEeprom_Read\n");

	// Lecture et verification Data0
	ReadData(pDB->StartAddress, pDB);
	Num0 = pDB->Num;
	Data0_valide = IsValide(pDB);

	// Si pas de backup utilise on sort de suite
	if (pDB->UseBkp == FALSE)
	{
		if (Data0_valide)
			return Status_OK;
		else
			return Status_KO;
	}

	// Lecture et verification Data1 si utilise
	ReadData(pDB->StartAddress + ALIGN_PAGE(pDB->Size+2), pDB);
	Num1 = pDB->Num;
	Data1_valide = IsValide(pDB);

	_CONSOLE(LogId, "Data0: Num=%d | IsValide=%d\n", Num0, Data0_valide);
	_CONSOLE(LogId, "Data1: Num=%d | IsValide=%d\n", Num1, Data1_valide);

	//--------------------------------------
	// Choix de la data a conserver
	if (Data0_valide && Data1_valide)		// 2 Data valides (on prend le plus recente)
	{
		_CONSOLE(LogId, "Data0 et Data1 valides: ");
		if ((Num0 == 0) && (Num1 == 0xFF))
			ChoixData = 0;
		else if ((Num0 == 0xFF) && (Num1 == 0))
			ChoixData = 1;
		else if (Num0 > Num1)
			ChoixData = 0;
		else
			ChoixData = 1;
	}
	else if (Data0_valide && !Data1_valide)	// Seule la Data0 est valide
		ChoixData = 0;
	else if (!Data0_valide && Data1_valide)	// Seule la Data1 est valide
		ChoixData = 1;
	else									// Aucune Data valide...
		ChoixData = (-1);

	switch (ChoixData)
	{
		case 0:
			_CONSOLE(LogId, "utilisation de Data0.\n");
			ReadData(pDB->StartAddress, pDB);	// Relecture de Data0
			pDB->CurrentSpace = 0;
			break;

		case 1:
			_CONSOLE(LogId, "utilisation de Data1.\n");
			// Relecture inutile (deja stockee dans pData)
			pDB->CurrentSpace = 1;
			break;

		case (-1):
		default:
			_CONSOLE(LogId, "Aucune Data valide. Restauration des valeurs par defaut.\n");
			if (pDB->pDefaultData != NULL)
			{
				memcpy(pDB->pData, pDB->pDefaultData, pDB->Size);
				pDB->CurrentSpace = 1;
				DatabaseEeprom_Write(DatabaseEeprom_Data, pData);
			}
			return Status_KO;
			break;
	}

	return Status_OK;

}
예제 #17
0
파일: Arrosage.c 프로젝트: jdaheron/GHB
/*------------------------------------------------------------------------------------------------*/
void Arrosage_Init(Bool_e UseConfIni)
{
	Arrosage_t TmpThis;
	Status_e ReadStatus;


	_CONSOLE(LogId, "---------- ARROSAGE INIT ----------\n");

	//------------------------------------------------------
	// Lecture des donnees flash
	//------------------------------------------------------
	DatabaseEeprom_InitData(DatabaseEeprom_Arrosage, NULL, sizeof(Arrosage_t));
	ReadStatus = DatabaseEeprom_Read(DatabaseEeprom_Arrosage, &TmpThis);
	DatabaseEeprom_Display(DatabaseEeprom_Arrosage, &TmpThis);
	if (ReadStatus == Status_KO)
	{
		_CONSOLE(LogId, "Invalid Eeprom Read: Default restored\n");
		DatabaseEeprom_Write(DatabaseEeprom_Arrosage, &This);
		memcpy(&TmpThis, &This, sizeof(Arrosage_t));
		This.Cfg_Restored = TRUE;
	}
	else
	{
		_CONSOLE(LogId, "Valid Eeprom Read \n");
		memcpy(&This, &TmpThis, sizeof(Arrosage_t));
		This.Cfg_Restored = FALSE;
	}


	//------------------------------------------------------
	// Comparaison avec fichier ini
	//------------------------------------------------------
	if ((ConfIni_Get()->IsValide == TRUE) && (UseConfIni == TRUE))
	{
		_CONSOLE(LogId, "Check SD cfg\n");

		memcpy(This.Cfg_Heure,			  ConfIni_Get()->ARR_Heure, 8);
		This.Cfg_Intervalle_h			= ConfIni_Get()->ARR_Intervalle_h;
		This.Cfg_VolumeParPlant_ml		= ConfIni_Get()->ARR_VolumeParPlant_ml;
		This.Cfg_NbPlants				= ConfIni_Get()->ARR_NbPlants;
		This.Cfg_DebitPompe_ml_par_h	= ConfIni_Get()->ARR_DebitPompe_ml_par_h;
		This.Cfg_VolumeReservoir_ml		= ConfIni_Get()->ARR_VolumeReservoir_ml;

		if (memcmp(&TmpThis, &This, sizeof(Arrosage_t)) != 0)
		{
			_CONSOLE(LogId, "Cfg SD copied\n");
			DatabaseEeprom_Write(DatabaseEeprom_Arrosage, &This);
		}
		else
		{
			_CONSOLE(LogId, "Cfg unchanged\n");
		}
	}


	//------------------------------------------------------
	// Affichage
	//------------------------------------------------------
	_CONSOLE(LogId, "Heure               = %s\n",	This.Cfg_Heure					);
	_CONSOLE(LogId, "Intervalle_h        = %d\n",	This.Cfg_Intervalle_h			);
	_CONSOLE(LogId, "VolumeParPlant_ml   = %d\n",	This.Cfg_VolumeParPlant_ml		);
	_CONSOLE(LogId, "NbPlants            = %d\n",	This.Cfg_NbPlants				);
	_CONSOLE(LogId, "DebitPompe_ml_par_h = %d\n",	This.Cfg_DebitPompe_ml_par_h	);
	_CONSOLE(LogId, "VolumeReservoir_ml  = %d\n",	This.Cfg_VolumeReservoir_ml		);

	_CONSOLE(LogId, "STATUS:\n");
	_CONSOLE(LogId, "VolumeRestant_ml    = %d\n",	This.VolumeRestant_ml		);
	_CONSOLE(LogId, "TS_Precedent        = %d\n",	This.TS_Precedent			);
	_CONSOLE(LogId, "TS_Suivant          = %d\n",	This.TS_Suivant				);

	This.GPIO = PORT_RELAIS_OPT2;
	This.Etat = Etat_INACTIF;
	This.Cfg_SaveNeeded = FALSE;

	// Verification de l'arrosage gere toutes les 500ms
	TSW_Start(&This.TmrMngt, 500);
}