/// <summary> /// HAL Initialization. Must be called before any other HAL functions. /// </summary> /// <param name="mode">Initialization Mode</param> public static void Initialize(int mode = 0) { //Lock this function, so that if accidentally called from multiple threads it doesn't //get m_initialized at the wrong value. lock (s_lockObject) { // We don't want to initialize more then once. if (s_initialized) return; s_initialized = true; //Check to see if we are on a RoboRIO. We do this by probing for a file we know is located //on the RIO. HALType = HALTypes.Simulation; if (File.Exists("/usr/local/frc/bin/frcRunRobot.sh")) { HALType = HALTypes.RoboRIO; } try { switch (HALType) { case HALTypes.RoboRIO: AthenaHAL.HAL.InitializeImpl(); break; case HALTypes.Simulation: case HALTypes.Other: case HALTypes.None: SimulatorHAL.HAL.InitializeImpl(); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { //If our loading ever causes an exception, print it, print the stack trace, and kill the program. Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Environment.Exit(1); } var rv = HALInitialize(mode); if (rv != 1) { throw new Exception($"HAL Initialize Failed with return code {rv}"); } } }
/// <summary> /// HAL Initialization. Must be called before any other HAL functions. /// </summary> /// <param name="mode">Initialization Mode</param> public static void Initialize(int mode = 0) { //Lock this function, so that if accidentally called from multiple threads it doesn't //get m_initialized at the wrong value. lock (s_lockObject) { // We don't want to initialize more then once. if (s_initialized) return; s_initialized = true; //Check to see if we are on a RoboRIO. We do this by probing for a file we know is located //on the RIO. HALType = HALTypes.Simulation; if (File.Exists("/usr/local/frc/bin/frcRunRobot.sh")) { HALType = HALTypes.RoboRIO; } string asm; switch (HALType) { case (HALTypes.Simulation): asm = HALSim; break; case HALTypes.None: case HALTypes.RoboRIO: case HALTypes.Other: default: asm = HALRIO; break; } HALAssembly = Assembly.LoadFrom(asm); //Setup all of our delegates //This allows us to dynamically switch between simulator, RoboRIO //and potentially others later. //Using delegates speeds the method calls up directly over //invoking the method using reflection, by about 20x. SetupDelegates(); HALAccelerometer.SetupDelegates(); HALAnalog.SetupDelegates(); HALCAN.SetupDelegates(); HALCanTalonSRX.SetupDelegates(); HALCompressor.SetupDelegates(); HALDigital.SetupDelegates(); HALInterrupts.SetupDelegates(); HALNotifier.SetupDelegates(); HALPDP.SetupDelegates(); HALPower.SetupDelegates(); HALSemaphore.SetupDelegates(); HALSerialPort.SetupDelegates(); HALSolenoid.SetupDelegates(); HALUtilities.SetupDelegates(); var rv = HALInitialize(mode); if (rv != 1) { throw new Exception($"HAL Initialize Failed with return code {rv}"); } //This next piece of code is to make sure that the Notifier and Interrupt libraries work. //Note that this leaks 6 bytes, but there is no way in the HAL to delete this structure, //And it is leaked on normal use as well. So this is a workaround, and we hope to fix it //When the HAL fixes it. int status = 0; HALDigital.InitializeDigitalPort(GetPort(0), ref status); //If we are simulator, grab a local copy of the dictionary so we can debug its values. if (HALType == HALTypes.Simulation) { string className = "SimData"; var types = HALAssembly.GetTypes(); var q = from t in types where t.IsClass && t.Name == className select t; Type type = HALAssembly.GetType(q.ToList()[0].FullName); GetData data = (GetData)Delegate.CreateDelegate(typeof(GetData), type.GetMethod("GetData")); data(out halData, out halInData, out halDSData); StartSimulator(); } } }