diff --git a/EDSEditor.sln b/EDSEditor.sln index 3bc6d4f2..5b28768c 100644 --- a/EDSEditor.sln +++ b/EDSEditor.sln @@ -8,6 +8,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libEDSsharp", "libEDSsharp\libEDSsharp.csproj", "{CC0FA4B1-2BFC-43B3-8C56-B428DF2D24E7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2A479BF3-7628-409B-8A29-9314C308445E}" + ProjectSection(ProjectDependencies) = postProject + {8B7A7545-6257-44BF-8868-F429E1B72C77} = {8B7A7545-6257-44BF-8868-F429E1B72C77} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDSSharp", "EDSSharp\EDSSharp.csproj", "{8B7A7545-6257-44BF-8868-F429E1B72C77}" EndProject diff --git a/EDSEditorGUI/Form1.cs b/EDSEditorGUI/Form1.cs index f94216a0..9c07d69c 100644 --- a/EDSEditorGUI/Form1.cs +++ b/EDSEditorGUI/Form1.cs @@ -226,7 +226,8 @@ private void exportCanOpenNode(DeviceView dv, string FileName, ExporterFactory.E { string savePath = Path.GetDirectoryName(FileName); string baseFileName = Path.GetFileNameWithoutExtension(FileName); - exporter.export(savePath, baseFileName, this.gitVersion, dv.eds, baseFileName); + var filepath = $"{savePath}/{baseFileName}"; + exporter.export(filepath, this.gitVersion, dv.eds); } catch (Exception ex) { diff --git a/EDSSharp/Program.cs b/EDSSharp/Program.cs index e149a96e..d1d96f79 100644 --- a/EDSSharp/Program.cs +++ b/EDSSharp/Program.cs @@ -92,8 +92,6 @@ private static void openEDSfile(string infile, string outfile, InfoSection.Filet private static void exportCOOD(string outpath,ExporterFactory.Exporter type) { - string odname = outpath; - outpath = Path.GetFullPath(outpath); string savePath = Path.GetDirectoryName(outpath); @@ -103,8 +101,9 @@ private static void exportCOOD(string outpath,ExporterFactory.Exporter type) Warnings.warning_list.Clear(); IExporter exporter = ExporterFactory.getExporter(type); + var filepath = Path.Combine(savePath, Path.GetFileNameWithoutExtension(outpath)); - exporter.export(savePath, Path.GetFileNameWithoutExtension(outpath), gitversion, eds, odname); + exporter.export(filepath, gitversion, eds); foreach(string warning in Warnings.warning_list) { diff --git a/Tests/CLITest.cs b/Tests/CLITest.cs new file mode 100644 index 00000000..8bbdbae8 --- /dev/null +++ b/Tests/CLITest.cs @@ -0,0 +1,37 @@ +using System.Diagnostics; +using System.IO; +using Xunit; + +namespace Tests +{ + public class CliTest : libEDSsharp.EDSsharp + { + string RunEDSSharp(string arguments) + { + Process p = new Process(); + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.FileName = "EDSSharp.exe"; + p.StartInfo.Arguments = arguments; + p.Start(); + string output = p.StandardOutput.ReadToEnd(); + p.WaitForExit(); + return output; + } + + [Fact] + public void XddToCanOpenNodeLegacy() + { + RunEDSSharp("--type CanOpenNode --infile minimal_project.xdd --outfile Legacy"); + string[] files = Directory.GetFiles(".", "Legacy.*"); + Assert.Equal(2, files.Length); + } + [Fact] + public void XddToCanOpenNodeV4() + { + RunEDSSharp("--type CanOpenNodeV4 --infile minimal_project.xdd --outfile V4"); + string[] files = Directory.GetFiles(".", "V4.*"); + Assert.Equal(2, files.Length); + } + } +} diff --git a/Tests/ExporterTestsV4.cs b/Tests/ExporterTestsV4.cs index 1d040355..becda204 100644 --- a/Tests/ExporterTestsV4.cs +++ b/Tests/ExporterTestsV4.cs @@ -14,7 +14,7 @@ public ExporterTestsV4() _eds = new EDSsharp(); } - void GetExportResult(EDSsharp eds, out IEnumerable cfile, out IEnumerable hfile) + void GetExportResult(EDSsharp eds, out IEnumerable cfile, out IEnumerable hfile, out string odname) { var fullPath = Path.GetTempFileName(); var tempfile = Path.GetFileName(fullPath); @@ -22,9 +22,10 @@ void GetExportResult(EDSsharp eds, out IEnumerable cfile, out IEnumerabl var cfilePath = fullPath + ".c"; var hfilePath = fullPath + ".h"; - export(path, tempfile, ".", eds, "OD_Test"); + export(cfilePath, ".", eds); cfile = File.ReadLines(cfilePath); hfile = File.ReadLines(hfilePath); + odname = tempfile; } bool FindExpectedLines(IEnumerable lines, List expectedLines) @@ -85,12 +86,12 @@ public void TestVariableStringZeroData() _eds.ods.Add(0x2000, od); - GetExportResult(_eds, out var cfile, out var hfile); - Assert.True(FindExpectedLines(hfile, new List { "#define OD_Test_ENTRY_H2000 &OD_Test->list[0]" })); - Assert.True(FindExpectedLines(hfile, new List { "#define OD_Test_ENTRY_H2000_testString &OD_Test->list[0]" })); + GetExportResult(_eds, out var cfile, out var hfile, out var odname); + Assert.True(FindExpectedLines(hfile, new List { $"#define {odname}_ENTRY_H2000 &{odname}->list[0]" })); + Assert.True(FindExpectedLines(hfile, new List { $"#define {odname}_ENTRY_H2000_testString &{odname}->list[0]" })); Assert.True(FindExpectedLines(cfile, new List { - "static CO_PROGMEM OD_TestObjs_t OD_TestObjs = {", + $"static CO_PROGMEM {odname}Objs_t {odname}Objs = {{", " .o_2000_testString = {", " .dataOrig = NULL,", " .attribute = ODA_SDO_R | ODA_STR,", @@ -99,8 +100,8 @@ public void TestVariableStringZeroData() "};"})); Assert.True(FindExpectedLines(cfile, new List { - "static OD_Test_ATTR_OD OD_entry_t OD_TestList[] = {", - " {0x2000, 0x01, ODT_VAR, &OD_TestObjs.o_2000_testString, NULL},", + $"static {odname}_ATTR_OD OD_entry_t {odname}List[] = {{", + $" {{0x2000, 0x01, ODT_VAR, &{odname}Objs.o_2000_testString, NULL}},", " {0x0000, 0x00, 0, NULL, NULL}", "};"})); } @@ -123,25 +124,25 @@ public void TestVariableString(string defaultValue, uint stringLengthMin, int ex _eds.ods.Add(0x2000, od); - GetExportResult(_eds, out var cfile, out var _); + GetExportResult(_eds, out var cfile, out var _, out var odname); Assert.True(FindExpectedLines(cfile, new List { - "OD_Test_ATTR_RAM OD_Test_RAM_t OD_Test_RAM = {", + $"{odname}_ATTR_RAM {odname}_RAM_t {odname}_RAM = {{", $" .x2000_testString = {{{expectedInitialValues}}}", "};"})); Assert.True(FindExpectedLines(cfile, new List { - "static CO_PROGMEM OD_TestObjs_t OD_TestObjs = {", + $"static CO_PROGMEM {odname}Objs_t {odname}Objs = {{", " .o_2000_testString = {", - " .dataOrig = &OD_Test_RAM.x2000_testString[0],", + $" .dataOrig = &{odname}_RAM.x2000_testString[0],", " .attribute = ODA_SDO_R | ODA_STR,", $" .dataLength = {expectedLength}", " }", "};"})); Assert.True(FindExpectedLines(cfile, new List { - "static OD_Test_ATTR_OD OD_entry_t OD_TestList[] = {", - " {0x2000, 0x01, ODT_VAR, &OD_TestObjs.o_2000_testString, NULL},", + $"static {odname}_ATTR_OD OD_entry_t {odname}List[] = {{", + $" {{0x2000, 0x01, ODT_VAR, &{odname}Objs.o_2000_testString, NULL}},", " {0x0000, 0x00, 0, NULL, NULL}", "};"})); } @@ -165,18 +166,18 @@ public void TestRecordWithString(string defaultValue, uint stringLengthMin, int od.subobjects[1].prop.CO_stringLengthMin = stringLengthMin; _eds.ods.Add(0x2000, od); - GetExportResult(_eds, out var cfile, out var hfile); + GetExportResult(_eds, out var cfile, out var hfile, out var odname); Assert.True(FindExpectedLines(hfile, new List { "typedef struct {", " struct {", " uint8_t numElements;", $" char str[{expectedLength+1}];", " } x2000_testRec;", - "} OD_Test_RAM_t;"})); + $"}} {odname}_RAM_t;"})); Assert.True(FindExpectedLines(cfile, new List { - "OD_Test_ATTR_RAM OD_Test_RAM_t OD_Test_RAM = {", + $"{odname}_ATTR_RAM {odname}_RAM_t {odname}_RAM = {{", " .x2000_testRec = {", " .numElements = 0x00,", $" .str = {{{expectedInitialValues}}}", @@ -187,20 +188,20 @@ public void TestRecordWithString(string defaultValue, uint stringLengthMin, int { "typedef struct {", " OD_obj_record_t o_2000_testRec[2];", - "} OD_TestObjs_t;"})); + $"}} {odname}Objs_t;"})); Assert.True(FindExpectedLines(cfile, new List { - "static CO_PROGMEM OD_TestObjs_t OD_TestObjs = {", + $"static CO_PROGMEM {odname}Objs_t {odname}Objs = {{", " .o_2000_testRec = {", " {", - " .dataOrig = &OD_Test_RAM.x2000_testRec.numElements,", + $" .dataOrig = &{odname}_RAM.x2000_testRec.numElements,", " .subIndex = 0,", " .attribute = ODA_SDO_RW | ODA_TRPDO,", " .dataLength = 1", " },", " {", - " .dataOrig = &OD_Test_RAM.x2000_testRec.str[0],", + $" .dataOrig = &{odname}_RAM.x2000_testRec.str[0],", " .subIndex = 1,", " .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_STR,", $" .dataLength = {expectedLength}", @@ -210,8 +211,8 @@ public void TestRecordWithString(string defaultValue, uint stringLengthMin, int Assert.True(FindExpectedLines(cfile, new List { - "static OD_Test_ATTR_OD OD_entry_t OD_TestList[] = {", - " {0x2000, 0x02, ODT_REC, &OD_TestObjs.o_2000_testRec, NULL},", + $"static {odname}_ATTR_OD OD_entry_t {odname}List[] = {{", + $" {{0x2000, 0x02, ODT_REC, &{odname}Objs.o_2000_testRec, NULL}},", " {0x0000, 0x00, 0, NULL, NULL}", "};"})); } @@ -231,17 +232,17 @@ public void TestRecordWithZeroLengthString() od.addsubobject(1, new ODentry("str", 0x2000, DataType.VISIBLE_STRING, "", EDSsharp.AccessType.rw, PDOMappingType.optional)); _eds.ods.Add(0x2000, od); - GetExportResult(_eds, out var cfile, out var hfile); + GetExportResult(_eds, out var cfile, out var hfile, out var odname); Assert.True(FindExpectedLines(hfile, new List { "typedef struct {", " struct {", " uint8_t numElements;", " } x2000_testRec;", - "} OD_Test_RAM_t;"})); + $"}} {odname}_RAM_t;"})); Assert.True(FindExpectedLines(cfile, new List { - "OD_Test_ATTR_RAM OD_Test_RAM_t OD_Test_RAM = {", + $"{odname}_ATTR_RAM {odname}_RAM_t {odname}_RAM = {{", " .x2000_testRec = {", " .numElements = 0x00", " }", @@ -251,14 +252,14 @@ public void TestRecordWithZeroLengthString() { "typedef struct {", " OD_obj_record_t o_2000_testRec[2];", - "} OD_TestObjs_t;"})); + $"}} {odname}Objs_t;"})); Assert.True(FindExpectedLines(cfile, new List { - "static CO_PROGMEM OD_TestObjs_t OD_TestObjs = {", + $"static CO_PROGMEM {odname}Objs_t {odname}Objs = {{", " .o_2000_testRec = {", " {", - " .dataOrig = &OD_Test_RAM.x2000_testRec.numElements,", + $" .dataOrig = &{odname}_RAM.x2000_testRec.numElements,", " .subIndex = 0,", " .attribute = ODA_SDO_RW | ODA_TRPDO,", " .dataLength = 1", @@ -274,8 +275,8 @@ public void TestRecordWithZeroLengthString() Assert.True(FindExpectedLines(cfile, new List { - "static OD_Test_ATTR_OD OD_entry_t OD_TestList[] = {", - " {0x2000, 0x02, ODT_REC, &OD_TestObjs.o_2000_testRec, NULL},", + $"static {odname}_ATTR_OD OD_entry_t {odname}List[] = {{", + $" {{0x2000, 0x02, ODT_REC, &{odname}Objs.o_2000_testRec, NULL}},", " {0x0000, 0x00, 0, NULL, NULL}", "};"})); } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 5deedc04..02f77340 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -9,6 +9,17 @@ + + + + + + + + + Always + + diff --git a/Tests/minimal_project.xdd b/Tests/minimal_project.xdd new file mode 100644 index 00000000..2a043d8a --- /dev/null +++ b/Tests/minimal_project.xdd @@ -0,0 +1,297 @@ + + + + + + + CANopen device profile + 1.1 + + + Device + + 1 + 1 + CANopen + + + + + + + minimal_test + + 0 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * bit 7: manufacturer specific +* bit 6: Reserved (always 0) +* bit 5: device profile specific +* bit 4: communication error (overrun, error state) +* bit 3: temperature +* bit 2: voltage +* bit 1: current +* bit 0: generic error + + + + + + * Sub Index 0: Contains number of actual errors. 0 can be written to clear error history. +* sub-index 1 and above: + * bit 16-31: Manufacturer specific additional information + * bit 0-15: Error code as transmited in the Emergency object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * bit 31: set to 0 +* bit 30: If set, CANopen device generates SYNC object +* bit 11-29: set to 0 +* bit 0-10: 11-bit CAN-ID + + + + + + + Period of SYNC transmission in µs (0 = transmission disabled). + + + + + + + Synchronous window leghth in µs (0 = not used). All synchronous PDOs must be transmitted within this time window. + + + + + + * bit 31: If set, EMCY does NOT exist / is NOT valid +* bit 11-30: set to 0 +* bit 0-10: 11-bit CAN-ID + + + + + + + Inhibit time of emergency message in multiples of 100µs. The value 0 disables the inhibit time. + + + + + + Heartbeat producer time in ms (0 = disable transmission). + + + + + + + * Value 0: SYNC message is transmitted with data length 0. +* Value 1: reserved. +* Value 2-240: SYNC message has one data byte, which contains the counter. +* Value 241-255: reserved. + + + + + + Sub-indexes 1 and above: +* Value 0x00: on error change to NMT state Pre-operational (only if currently in NMT state Operational) +* Value 0x01: on error do nothing +* Value 0x02: on error change to NMT state Stopped + + + + + + + + + + + + + + + + + + + + + + + + + + CANopen communication network profile + 1.1 + + + CommunicationNetwork + + 1 + 1 + CANopen + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libEDSsharp/CanOpenNodeExporter.cs b/libEDSsharp/CanOpenNodeExporter.cs index 92c8eedb..3e9f1b95 100644 --- a/libEDSsharp/CanOpenNodeExporter.cs +++ b/libEDSsharp/CanOpenNodeExporter.cs @@ -94,14 +94,13 @@ public void prepareCanOpenNames() /// /// Export eds into CanOpenNode v1-3 source files (.h and .c) /// - /// folder path to save the files into - /// base filename, .c and .h will be added to this + /// filepath, .c and .h will be added to this to make the mulitiple files /// git version of this software /// the eds data to be exported - /// object dictionary name - public void export(string folderpath, string filename, string gitVersion, EDSsharp eds,string odname) + public void export(string filepath, string gitVersion, EDSsharp eds) { - this.folderpath = folderpath; + this.folderpath = Path.GetDirectoryName(filepath); + string filename = Path.GetFileNameWithoutExtension(filepath); this.gitVersion = gitVersion; this.eds = eds; diff --git a/libEDSsharp/CanOpenNodeExporter_V4.cs b/libEDSsharp/CanOpenNodeExporter_V4.cs index c5e86043..05a66a43 100644 --- a/libEDSsharp/CanOpenNodeExporter_V4.cs +++ b/libEDSsharp/CanOpenNodeExporter_V4.cs @@ -49,14 +49,14 @@ public class CanOpenNodeExporter_V4 : IExporter /// /// export the current data set in the CanOpen Node format V4 /// - /// - /// + /// filepath, .c and .h will be added to this to make the mulitiple files /// /// - /// - public void export(string folderpath, string filename, string gitVersion, EDSsharp eds, string odname) + public void export(string filepath, string gitVersion, EDSsharp eds) { - this.odname = odname; + string filename = Path.GetFileNameWithoutExtension(filepath); + string folderpath = Path.GetDirectoryName(filepath); + this.odname = filename; Prepare(eds); diff --git a/libEDSsharp/IExporter.cs b/libEDSsharp/IExporter.cs index 53b94b10..683cfe32 100644 --- a/libEDSsharp/IExporter.cs +++ b/libEDSsharp/IExporter.cs @@ -14,11 +14,9 @@ public interface IExporter /// /// Export file(s) /// - /// Path to the folder that will contain the new files - /// base filename for the new files + /// filepath, .c and .h will be added to this to make the mulitiple files /// version that will be saved to the file /// The eds that will be exported - /// The object dictionary name - void export(string folderpath, string filename, string gitVersion, EDSsharp eds , string odname="OD"); + void export(string filepath, string gitVersion, EDSsharp eds); } }