Hello again everyone. I’m about to deploy a project a long way from home and would like to be able to keep it up to date with the IFU class and an SD Card. However, I’m rather new to this and need some more details than what is provided at this address; https://www.ghielectronics.com/docs/147/in-field-update
Some questions I have like; What is Config.hex, how can I generate it, and do I need it.
Here is the code I’ve Tried.
using GHI.Processor;
using System.IO;
using System.Threading;
namespace G120.Programs
{
class IFU
{
public const int BLOCK_SIZE = 65536;
public static void FlashFirmware()
{
// Reserve the memory needed to buffer the update.
// A lot of RAM is needed so it is recommended to do this at the program start.
InFieldUpdate.Initialize(InFieldUpdate.Types.Firmware | InFieldUpdate.Types.Configuration);
if (!SAL.Detect.SD_Card())
{
Sally.StatusLED[3].Write(true);
return;
}
// Start loading the new firmware on the RAM reserved in last step.
// Nothing is written to FLASH In this stage. Power loss and failures are okay
// Simply abort this stage any way you like!
// Files can come from Storage, from network, from serial bus and any Other way.
//LoadFile("\\SD\\Config.hex", InFieldUpdate.Types.Configuration);
LoadFile("\\SD\\Upgrades\\Firmware.hex", InFieldUpdate.Types.Firmware);
//LoadFile("\\SD\\Firmware2.hex", InFieldUpdate.Types.Firmware); //Only if your device has two firmware files.
// This method will copy The new firmware from RAM to FLASH.
// This function will not return But will reset the system when done.
// Power loss during Before this function resets the system quill result in a corrupted firmware.
// A manual update will be needed if this method failed, due to power loss for example.
Sally.StatusLED[1].Write(true);
while (Sally.LDR0.Read() & Sally.LDR1.Read())
{
Thread.Sleep(1000);
}
Sally.StatusLED[2].Write(true);
InFieldUpdate.FlashAndReset();
}
public static void LoadFile(string filename, InFieldUpdate.Types type)
{
using (var stream = new FileStream(filename, FileMode.Open))
{
var data = new byte[BLOCK_SIZE];
for (int i = 0; i < stream.Length / BLOCK_SIZE; i++)
{
stream.Read(data, 0, BLOCK_SIZE);
InFieldUpdate.Load(type, data, BLOCK_SIZE);
}
stream.Read(data, 0, (int)stream.Length % BLOCK_SIZE);
InFieldUpdate.Load(type, data, (int)stream.Length % BLOCK_SIZE);
}
}
}
}
Try changing the type of data to byte and not var. The error is the wrong type in one of the arguments. I’ve seen this before where I’ve passed in a different type and it didn’t automatically cast.
I’ve found something that works. I had to change the type to application and initialize the application loader first.
I would still like to know how to generate the config and firmware hex files, What the difference is and how to load them.
Thanks. here is the code that works.
using GHI.Processor;
using System.IO;
using System.Threading;
namespace G120.Programs
{
class IFU
{
public const int BLOCK_SIZE = 65536;
public static void FlashFirmware()
{
// Reserve the memory needed to buffer the update.
// A lot of RAM is needed so it is recommended to do this at the program start.
InFieldUpdate.Initialize(InFieldUpdate.Types.Firmware | InFieldUpdate.Types.Configuration | InFieldUpdate.Types.Application);
if (!SAL.Detect.SD_Card())
{
Sally.StatusLED[3].Write(true);
return;
}
// Start loading the new firmware on the RAM reserved in last step.
// Nothing is written to FLASH In this stage. Power loss and failures are okay
// Simply abort this stage any way you like!
// Files can come from Storage, from network, from serial bus and any Other way.
//LoadFile("\\SD\\Config.hex", InFieldUpdate.Types.Configuration);
LoadFile("\\SD\\Upgrades\\Firmware.hex", InFieldUpdate.Types.Application);
//LoadFile("\\SD\\Firmware2.hex", InFieldUpdate.Types.Firmware); //Only if your device has two firmware files.
// This method will copy The new firmware from RAM to FLASH.
// This function will not return But will reset the system when done.
// Power loss during Before this function resets the system quill result in a corrupted firmware.
// A manual update will be needed if this method failed, due to power loss for example.
Sally.StatusLED[1].Write(true);
while (Sally.LDR0.Read() & Sally.LDR1.Read())
{
Thread.Sleep(1000);
}
Sally.StatusLED[2].Write(true);
InFieldUpdate.FlashAndReset();
}
public static void LoadFile(string filename, InFieldUpdate.Types type)
{
using (var stream = new FileStream(filename, FileMode.Open))
{
var data = new byte[BLOCK_SIZE];
for (int i = 0; i < stream.Length / BLOCK_SIZE; i++)
{
stream.Read(data, 0, BLOCK_SIZE);
InFieldUpdate.Load(type, data, BLOCK_SIZE);
}
stream.Read(data, 0, (int)stream.Length % BLOCK_SIZE);
InFieldUpdate.Load(type, data, (int)stream.Length % BLOCK_SIZE);
}
}
}
}
That must be an exception here, unless the Firmware.hex is application because you changed its name.
First post is correct, it should work.
Second post is incorrect. It should not work.
You get it working at 2nd post just because you changed your application.hex to firmware.hex.
Its name is firmware.hex but that is actually application, so it will work with Types.Application.
OH NO Batman, What have I been doing? Here is my complete IFU class.
I’ve been using this no problem, but I’ve just discovered that I’m missing the Firmware2.hex file? How has this been working then? Or is it that the firmware has not changed since I started?
namespace Mustang
{
public static class IFU
{
public const int BLOCK_SIZE = 65536;
public static void Flash_App()
{
// Reserve the memory needed to buffer the update.
// A lot of RAM is needed so it is recommended to do this at the program start.
InFieldUpdate.Initialize(InFieldUpdate.Types.Firmware | InFieldUpdate.Types.Configuration | InFieldUpdate.Types.Application);
if (!Detect.SD_Card())
{
LEDs.Show(3);
return;
}
// Start loading the new firmware on the RAM reserved in last step.
// Nothing is written to FLASH In this stage. Power loss and failures are okay
// Simply abort this stage any way you like!
// Files can come from Storage, from network, from serial bus and any Other way.
//LoadFile("\\SD\\Upgrades\\Firmware.hex", InFieldUpdate.Types.Firmware);
//LoadFile("\\SD\\Upgrades\\Config.hex", InFieldUpdate.Types.Configuration);
LoadFile("\\SD\\Upgrades\\App.hex", InFieldUpdate.Types.Application);
LEDs.Show(2);
while (SAL.LDR0.Read())
{
Thread.Sleep(1000);
}
LEDs.Show(4);
// This method will copy The new firmware from RAM to FLASH.
// This function will not return But will reset the system when done.
// Power loss during Before this function resets the system quill result in a corrupted firmware.
// A manual update will be needed if this method failed, due to power loss for example.
InFieldUpdate.FlashAndReset();
}
public static void Flash_All()
{
// Reserve the memory needed to buffer the update.
// A lot of RAM is needed so it is recommended to do this at the program start.
InFieldUpdate.Initialize(InFieldUpdate.Types.Firmware | InFieldUpdate.Types.Configuration | InFieldUpdate.Types.Application);
if (!Detect.SD_Card())
{
LEDs.Show(3);
return;
}
// Start loading the new firmware on the RAM reserved in last step.
// Nothing is written to FLASH In this stage. Power loss and failures are okay
// Simply abort this stage any way you like!
// Files can come from Storage, from network, from serial bus and any Other way.
LoadFile("\\SD\\Upgrades\\Firmware.hex", InFieldUpdate.Types.Firmware);
LoadFile("\\SD\\Upgrades\\Config.hex", InFieldUpdate.Types.Configuration);
LoadFile("\\SD\\Upgrades\\App.hex", InFieldUpdate.Types.Application);
LEDs.Show(2);
while (SAL.LDR1.Read())
{
Thread.Sleep(1000);
}
LEDs.Show(4);
// This method will copy The new firmware from RAM to FLASH.
// This function will not return But will reset the system when done.
// Power loss during Before this function resets the system quill result in a corrupted firmware.
// A manual update will be needed if this method failed, due to power loss for example.
InFieldUpdate.FlashAndReset();
}
private static void LoadFile(string filename, InFieldUpdate.Types type)
{
using (var stream = new FileStream(filename, FileMode.Open))
{
var data = new byte[BLOCK_SIZE];
for (int i = 0; i < stream.Length / BLOCK_SIZE; i++)
{
stream.Read(data, 0, BLOCK_SIZE);
InFieldUpdate.Load(type, data, BLOCK_SIZE);
}
stream.Read(data, 0, (int)stream.Length % BLOCK_SIZE);
InFieldUpdate.Load(type, data, (int)stream.Length % BLOCK_SIZE);
}
}
}
Unfortunately there is no guarantee that the format or contents of config doesn’t change between releases. So you’d need to thoroughly test it on your end if you don’t.
Perhaps you can configure a system in your lab with the configuration you desire (device name, default network & MAC addresses, etc.) using the target F/W release, then create a Config.HEX file using FEZ Config, Then send the new config with the new F/W to your in-field unit for IFU.