HI Tom,
For the the c file test I started with BlinkKflop.c and added a line of garbage code that can be uncommented to produce a compile error.
Code: Select all
[#include "KMotionDef.h"
void main()
{
//garbagecodetest
int i;
for (i=0; i<10; i++)
{
ClearBit(46);
Delay_sec(0.1);
SetBit(46);
Delay_sec(0.1);
}
}
Everything works as expected when compiled with the vaild c code.
SimpleForms Behavior
When
//garbcodetest is uncommented and I try to compile/run from SimpleForms I get a "Microsoft Visual C++ Runtime Library" error message and then the process shuts down - terminating the program and all windows.
I'll have to figure out how to post pictures, but the Error message box says:
Code: Select all
Debug Assertion Failed!
Program:
C:\Kmotion5.0.6\Kmotion\Debug\SimpleFormsCS.exe
File:
minkernel\crts\ucrt\inc\corecrt_inteneral_string_templates.h
Line: 81
Expression: (L"Buffer is too small" && 0)
The message box button options are Abort/Retry/Ignore. Regardless of which button is used to acknowledge the dialog, the behavior is an immediate termination of the windows process:
Interrogating the debug console, the termination code is found:
The program '[8748] SimpleFormsCS.exe' has exited with code 3221226505 (0xc0000409).
My C# Application Behavior
Interestingly, when I run the same test from my C# application I
DO NOT get the "Microsoft Visual C++ Runtime Library" error message. The process just quietly exits with the same debug console termination code:
The program '[9540] KognaTemplateApp.exe' has exited with code 3221226505 (0xc0000409).
My C# code is very similar to the SimpleForms example
Code: Select all
/// <summary>
/// Compile a C program (from file path given) and execute (on the thread passed in)
/// </summary>
/// <param name="strFileName">Full file name and path of .c file </param>
/// <param name="threadNum">Thread numnber to execute program on (1 to 7 are valid numnbers)</param>
public bool CompileLoadExecute(string strFileName, int threadNum)
{
if (!Connected)
return false;
try
{
string Result = KM.CompileAndLoadCoff(threadNum, strFileName, false);
if (Result != "")
{
MessageBox.Show(Result, "Compile Error");
return false;
}
else
{
// everything ok, execute the Thread
string strExec = "Execute" + threadNum.ToString();
SendConsoleCommand(strExec);
return true;
}
}
catch (DMException ex)
{
MessageBox.Show(ex.InnerException.Message);
return false;
}
}
Code: Select all
/// <summary>
/// use this method to send console commands to the board. It checks for connection and wraps the KM.WriteLine call in Try/Catch....
/// </summary>
public bool SendConsoleCommand(string cmd)
{
if (Connected == false)
return false;
try
{
KM.WriteLine(cmd);
return true;
}
catch (KMotion_dotNet.DMException ex)
{
GScommon.DebugLog.Write(ex.Message + ":" + ex.StackTrace);
return false;
}
catch (Exception e)
{
GScommon.DebugLog.Write(e.Message + ":" + e.StackTrace);
return false;
}
}
In previous Kflop releases, the same code would produce a messagebox that there was a compile error, but application would not crash.
Calling TCC Command Line Interface
From my C# application, I also have coded the ability to call l the TCC compiler's CLI directly:
Code: Select all
/// <summary>
/// call up the TCC67 command line interface to compile a c code file
/// </summary>
/// <param name="file2compile">the full name/path of the .c code to compile </param>
/// <param name="threadNumber">the thread that the compiled coff file is intended to be run on </param>
public static void complileKogna(string c_file_name, int threadNumber)
{
if (File.Exists(c_file_name) == false)
{
//TODO:
//AppLog.Write("No File Selected... aborting compile");
return;
}
string coffname = Get_Coff_Name_From_C_file(c_file_name, threadNumber);
string c_path = Path.GetDirectoryName(c_file_name);
//create the bin directory if needed
if (Directory.Exists(Path.GetDirectoryName(coffname)) == false)
{
string dir2create = Path.GetDirectoryName(coffname);
Directory.CreateDirectory(dir2create);
System.Threading.Thread.Sleep(100);
}
//read in user settings
string exe_path = GS.Dynomotion.mdl_DynoAppSettings.TCC_exe.Value;
string dsp_file = GS.Dynomotion.mdl_DynoAppSettings.DSP_out_file.Value;
string dsp_include = Path.GetDirectoryName(dsp_file);
//build up the argument list
string compileArgs = "-text " + threadAddressKogna[threadNumber] + " -g -nostdinc ";
compileArgs += "-I " + quote(dsp_include) + " ";
compileArgs += "-I " + quote(c_path) + " ";
compileArgs += "-o " + quote(coffname) + " " + quote(c_file_name) + " " + quote(dsp_file);
//procCompile=System.Diagnostics.Process.Start(compiler_path, compileArgs);
procCompile = new System.Diagnostics.Process();
procCompile.StartInfo.FileName = exe_path; // set compiler path
procCompile.StartInfo.Arguments = compileArgs; // add arguments
procCompile.StartInfo.UseShellExecute = false; // Set UseShellExecute to false for redirection.
procCompile.StartInfo.RedirectStandardOutput = true; // Redirect the standard output of the sort command.
procCompile.StartInfo.RedirectStandardError = true; // Redirect the standard output of the sort command.
// some diagnostic output
GScommon.DebugLog.Write("Running Compiler: " + exe_path);
GScommon.DebugLog.Write(" -args: " + compileArgs);
procCompile.Start(); // start the compile process
StreamReader stdReader = procCompile.StandardOutput; // hook into the standard output stream
StreamReader errReader = procCompile.StandardError; // hook into the stardard error stream (this is actually where messages come in)
// wait till the compiler is finished
while (procCompile.HasExited == false) { /* just hang tight */ };
//output the compiler results
GScommon.DebugLog.Write("Compiler returned with exit code: " + procCompile.ExitCode);
string s = stdReader.ReadToEnd();
s += errReader.ReadToEnd();
// if there was a compile error, jump out here without reading the coff
if (procCompile.ExitCode != 0)
{
GScommon.DebugLog.Write("Compiler Returned an eror:\r\n" + s);
return;
}
}
public static string[] threadAddressKogna = {
"C0080000", /*thread 0, we don't use this*/
"C0080000", /*thread 1*/
"C00C0000", /*thread 2*/
"C0100000", /*thread 3*/
"C0140000", /*thread 4*/
"C0180000", /*thread 5*/
"C01C0000", /*thread 6*/
"C0200000", /*thread 7*/
};
Calling complileKogna() with the offending C program results in the compiler error is as one would expect, but I can handle the error gracefully without terminating the process:
Code: Select all
Running Compiler: C:\KMotion5.0.6\KMotion\Release\TCC67.exe
-args: -text C0200000 -g -nostdinc -I "C:\KMotion5.0.6\DSP_KOGNA" -I "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles" -o "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP(7).out" "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP.c" "C:\KMotion5.0.6\DSP_KOGNA\DSPKOGNA.out"
Compiler returned with exit code: 1
Compiler Returned an eror:
C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP.c:8: 'garbargecodetest' undeclared
And running the same code with the valid KflopBlink.c program as input:
Code: Select all
Running Compiler: C:\KMotion5.0.6\KMotion\Release\TCC67.exe
-args: -text C0200000 -g -nostdinc -I "C:\KMotion5.0.6\DSP_KOGNA" -I "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles" -o "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP(7).out" "C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP.c" "C:\KMotion5.0.6\DSP_KOGNA\DSPKOGNA.out"
Compiler returned with exit code: 0
reading code sizes from coff file: C:\Users\GradientR9\Desktop\Kogna\KognaTemplateApp\KognaTemplateApp\Application Data\TestCfiles\BlinkKFLOP(7).out
text=384 | data=16 | bss=0 | total=400
The reason that I have/use the TCC command line interface if because I primarily develop/edit Kflop C programs in VS Code and I have a helper C# app to handle the compiling during my development phases.