Code covered by the BSD License  

Highlights from
ECRobotInstaller – Simplified installation of tools for Embedded Coder Robot

image thumbnail

ECRobotInstaller – Simplified installation of tools for Embedded Coder Robot

by

 

02 Sep 2009 (Updated )

Simplifies the installation of ECRobot, a Simulink platform for LEGO Mindstorms NXT code generation

check_ecrobot_tools
function check_ecrobot_tools
% CHECK_ECROBOT_TOOLS
%
%   CHECK_ECROBOT_TOOLS is a diagnostic utility to check whether all the
%   programs for ECRobot have been installed correctly. It assumes that
%   INSTALL_ECROBOT_TOOLS has already been executed. 
%   
%   Notes on usage:
%   1) CHECK_ECROBOT_TOOLS reads the configuration information (install
%   directories, download filenames, etc.) from ECROBOT_INSTALL_CONFIG.M.
%
%   2) It is safe to run CHECK_ECROBOT_TOOLS multiple times. 
%
%   3) CHECK_ECROBOT_TOOLS saves all the diagnostic information to
%      C:\Temp\ECRobot_tools_check_log.txt  

%   Copyright 2009 The MathWorks, Inc.

% ECRobotInstaller version 1.2: (dec-11-2009)
%   * check_lego_usb_driver: fantom.dll existence is checked using
%     windows registry and getenv('SYSTEMROOT') (instead of just looking
%     for c:\winnt\system32\fantom.dll)
%   * check_nxt_firmware: checks for existence of lms_arm_nbcnxc* files
%     instead of hardcoded check for 3 files.
%
% ECRobotInstaller version 1.37: (Jan-01-2011)
%   * check_lego_usb_driver looks for fantom.dll in c:\windows\syswow64\ 
%     (this is where 32-bit dlls are placed on 64-bit systems)
%   * Fixed dump_config to handle non-string fields in config struct
%   * Added dump_system_info to capture Windows version & 32/64 bitness
%   * "Information logged to ..." message hyperlinks to logfile

    if ~ispc
        fprintf('This program runs only on Windows PCs\n');
        return;
    end

    if ~(exist('ecrobot_install_config', 'file') == 2)
        fprintf('Unable to find ecrobot_install_config.m\n');
        return;
    end
    
    logfileName = fullfile(tempdir, 'ECRobot_tools_check_log.txt');
    fid = fopen(logfileName, 'w');
    if fid < 0
        fprintf('Unable to create log file (%s)\n', logfileName);
        return;
    else
        fprintf('Information logged to <a href="matlab:edit(''%s'')">%s</a>\n', logfileName, logfileName);
    end

    % initialize logging functions
    visibleLog(fid);
    silentLog(fid);
    
    errorinfo = [];
    try
        
        config = ecrobot_install_config;
        verifyConfig(config, 'installation_dirs', @visibleLog);
        dump_system_info(config);
        dump_config(config);
        
        check_cygwin(config);
        check_gnutools(config);
        check_lego_usb_driver(config);        
        check_nxt_firmware(config);
        check_nxt_tools(config);
        check_ecrobot(config);
        check_nxt_osek(config);
    catch  %#ok<CTCH>
        visibleLog('Install canceled\n');
        % save error information only if it isn't generated by us
        le = lasterror; %#ok<LERR>
        if ~strncmp(le.identifier, 'ecrobot_installer', 17)
            errorinfo = le;
        end        
    end

    
    fclose(fid);
    if ~isempty(errorinfo)
        rethrow(errorinfo);
    end
    
    % reset logging functions 
    visibleLog([]);
    silentLog([]);
end


%% Logging functions
function visibleLog(varargin)
    persistent fileID
    if isnumeric(varargin{1})
        fileID = varargin{1};
        return;
    end
    fprintf(1, varargin{:});
    fprintf(fileID, varargin{:});
end

function silentLog(varargin)
    persistent fileID
    if isnumeric(varargin{1})
        fileID = varargin{1};
        return;
    end    
    fprintf(fileID, varargin{:});
end

function visibleLogSection(sectionname)    
    visibleLog('\n================ %s %s\n', datestr(now), sectionname);
end


%%
function dump_system_info(config) %#ok<INUSD>

visibleLogSection('System Information');

% Microsoft Windows 2000 [Version 5.00.2195]
% Microsoft Windows XP [Version 5.1.2600]
% Microsoft Windows [Version 5.2.3790]  % windows server 2003
% Microsoft Windows [Version 6.0.6001] % windows vista
% Microsoft Windows [Version 6.0.6002] % windows server 2008
% Microsoft Windows [Version 6.1.7600] % windows 7

silentLog('Computer: %s\n', computer);

[status,windowsVersion] = system('ver');
if status
    silentLog('Windows version: <unable to execute>\n');
else
    silentLog('Windows version: %s\n', windowsVersion);
end
end


%%
function dump_config(config)
    fn = fieldnames(config);
    visibleLogSection('Configuration parameters');
    for i=1:numel(fn)
        fname = fn{i};
        fvalue = config.(fn{i});
        if ischar(fvalue)
            silentLog('%42s = ''%s''\n', fname, fvalue);
        elseif isnumeric(fvalue)
            silentLog('%42s = %g\n', fname, fvalue);
        else
             silentLog('%42s = type %s\n', fname, class(fvalue));
        end
    end
end

%%
function check_cygwin(config)
    visibleLogSection('Cygwin');

    if isempty(config.Cygwin_InstallationDirectory)
        visibleLog('Cygwin_InstallationDirectory is not specified. Skipping check\n');
        return;
    end       

    % cygwin installation dir
    try
        cygpath = winqueryreg('HKEY_LOCAL_MACHINE', 'SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/', 'native');
    catch %#ok<CTCH>
        % not installed
        cygpath = [];        
        silentLog('\nCannot find registry entry for Cygwin\n');
    end
        
    if ~isempty(cygpath) && ~compareDirectoryNames(cygpath, config.Cygwin_InstallationDirectory)
        silentLog('Mismatch between windows registry and installation directory\n');
        silentLog('Windows registry entry = ''%s''\n', cygpath);
        silentLog('Installation directory  = ''%s''\n', config.Cygwin_InstallationDirectory);
    end
        
    cygcheck = fullfile(config.Cygwin_InstallationDirectory, 'bin', 'cygcheck');
    cmdstr = ['"' cygcheck '"' ' --version'];
    [status,result]=system(cmdstr);
    silentLog('\n%s\n%s\n', cmdstr, result);
    if status
        visibleLog('Cygwin does not seem to be installed correctly!\n');
    end
    
    % cygwin
    cmdstr = ['"' cygcheck '"'  ' --sysinfo'];
    [status,result]=system(cmdstr);
    silentLog('\n%s\n%s\n', cmdstr, result);
    if status
        visibleLog('Cygwin does not seem to be installed correctly!\n');
    end    
    
    cygwin_make = fullfile(config.Cygwin_InstallationDirectory, 'bin', 'make');
    cmdstr = ['"' cygwin_make '"' ' --version'];
    [status,result]=system(cmdstr);
    silentLog('\n%s\n%s\n', cmdstr, result);
    if status
        visibleLog('Problem executing Cygwin MAKE command!\n');
    end
    
end

%%
function check_gnutools(config)
    visibleLogSection('GNU ARM Compiler');
    
    if isempty(config.GnuTools_InstallationDirectory)
        visibleLog('GnuTools_InstallationDirectory is not specified. Skipping check\n');
        return;
    end    
    
    try
        % The following registry query does not work under Win7 64-bit. Remove the registry
        % check as it does not seem to be robust across different platforms
        % gnuPath = winqueryreg('HKEY_LOCAL_MACHINE', 'SOFTWARE\GNUARM\4.0.2', 'InstallPath');
        % alreadyInstalled = compareDirectoryNames(config.GnuTools_InstallationDirectory, gnuPath) ...
        %                   && (exist(elfgcc, 'file')==2);        
        elfgcc = fullfile(config.GnuTools_InstallationDirectory, 'bin', 'arm-elf-gcc.exe');
        alreadyInstalled = exist(elfgcc, 'file')==2;
    catch  %#ok<CTCH>
        % key is not present, so GNU tools aren't installed
        alreadyInstalled = false;
    end
    
    if ~alreadyInstalled
        visibleLog('GNU ARM Tools not installed\n');
        return;
    end

    % need to ensure that cygwin\bin is on the path before invoking GNU ARM commands
    currentPath = getenv('PATH');
    cygwin_bin = fullfile(config.Cygwin_InstallationDirectory, 'bin');
    if isempty( findstr(lower(currentPath), lower(cygwin_bin)) )
        setenv('PATH', [cygwin_bin ';' currentPath]);
    end
    
    % Step 2: GNU ARM tools
    elfgcc = fullfile(config.GnuTools_InstallationDirectory, 'bin', 'arm-elf-gcc.exe');
    cmdstr = [elfgcc ' -dumpversion'];
    [status2,result]=system(cmdstr);
    silentLog('\n%s\n%s\n', cmdstr, result);
    if status2
        visibleLog('Gnu ARM compiler does not seem to be installed correctly!\n');
    end        
    
    % gnu tools
    cmdstr = [elfgcc ' -print-search-dirs'];
    [status3,result]=system(cmdstr);
    silentLog('\n%s\n%s\n', cmdstr, result);
    if status3
        visibleLog('Gnu ARM compiler does not seem to be installed correctly!\n');
    end    
    
end

%%
function check_lego_usb_driver(config)     %#ok<INUSD>
    visibleLogSection('LEGO USB Driver');    
    
    % if NI-VISA is not installed, then lego usb driver is not installed
    % (but NI-VISA installation doesn't guarantee lego usb driver% installation)
    try
        versionStr = winqueryreg('HKEY_LOCAL_MACHINE', ...
                                 'SOFTWARE\National Instruments\NI-VISA for Windows 95/NT', ...
                                 'CurrentVersion');
        silentLog('NI VISA found in registry -- version %s\n', versionStr);
    catch  %#ok<CTCH>
        silentLog('NI VISA not found in registry\n');
    end
    
    systype = computer;
    if strcmpi(systype, 'PCWIN64')
        driverFile = fullfile(getenv('SYSTEMROOT'), 'sysWOW64', 'fantom.dll');
    elseif strcmpi(systype, 'PCWIN')
        driverFile = fullfile(getenv('SYSTEMROOT'), 'system32', 'fantom.dll');
    else
        error('Unexpected platform (''%s'')', systype);
    end
            
    dd = dir(driverFile);
    if numel(dd) == 0
        visibleLog('Unable to find LEGO driver: %s\n', driverFile);
    else
        silentLog('Found LEGO driver: %s (%d bytes)\n', driverFile, dd(1).bytes);
    end
    
    try
        dllnames = winqueryreg('name', 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls');
    catch
        dllnames = [];
        silentLog('Unable to find SharedDlls list in registry\n');
    end
    
    if ~isempty(dllnames)
        foundIndices = find(~cellfun('isempty', regexpi(dllnames, 'fantom\.dll')));
        if numel(foundIndices) > 0
            silentLog('Found %d instance(s) of fantom.dll in the registry\n', length(foundIndices));
            for i=1:numel(foundIndices)
                silentLog('  %s\n', dllnames{foundIndices(i)});
            end
        end
    end
    
end


%%
function check_nxt_tools(config)
    visibleLogSection('NeXTTool');    
    
    if isempty(config.NXTTOOL_InstallationDirectory)
        visibleLog('NXTTOOL_InstallationDirectory is not specified. Skipping check\n');
        return;
    end    

    nexttoolExe = fullfile(config.NXTTOOL_InstallationDirectory,'NeXTTool.exe');
    if exist(nexttoolExe, 'file') == 2
        [status,result]=system(nexttoolExe);
        silentLog('\n%s\n%s\n', nexttoolExe, result);
    else
        status = 1; % error state
    end
        
    if status 
        visibleLog('LEGO NeXTTool.EXE does not seem to be installed correctly!\n');
    end    
    
end

%%
function check_nxt_firmware(config)
    visibleLogSection('NXT Enhanced firmware');
    if isempty(config.NXTEnhancedFirmware_InstallationDirectory)
        visibleLog('NXTEnhancedFirmware_InstallationDirectory is not specified. Skipping check\n');
        return;
    end
    
    dd = dir(fullfile(config.NXTEnhancedFirmware_InstallationDirectory, '*.rfw'));
    dump_fileinfo(dd);
    
    dd = dir(fullfile(config.NXTEnhancedFirmware_InstallationDirectory, 'lms_arm_nbcnxc_*.rfw'));
    if isempty(dd)
         visibleLog('NXT Enhanced firmware does not seem to be installed correctly!\n');
    end
end

%%
function check_nxt_osek(config)
    visibleLogSection('NXT OSEK');
    if isempty(config.NXTOSEK_InstallationDirectory)
        visibleLog('NXTOSEK_InstallationDirectory is not specified. Skipping check\n');
        return;
    end
    
    osekDir = fullfile(config.NXTOSEK_InstallationDirectory,'nxtOSEK');
    dd = dir(osekDir);
    if numel(dd) == 0
        visibleLog('NXT OSEK does not seem to be installed\n');
        silentLog('\nNo files in %s\n', osekDir);
        return;
    end
    
    dump_fileinfo(dd);
    
    versionFileDir = fullfile(osekDir, 'ecrobot');
    versionFile = fullfile(versionFileDir, 'ver_nxtOSEK.m');
    if ~(exist(versionFile, 'file') == 2)
        silentLog('\nCannot find %s\n', versionFile);
        return;
    end
    
    oldDir = pwd;    
    try
        cd(versionFileDir);
        ver = ver_nxtOSEK;
        silentLog('\nnxtOSEK version = %g\n', ver);
        cd(oldDir);
    catch 
        cd(oldDir);
        le = lasterror;         %#ok<LERR>  
        silentLog('\nProblem running %s\n', versionFile);
        silentLog('%s\n', le.message);
    end    
end

%%
function check_ecrobot(config)
    visibleLogSection('ECRobot');

    if isempty(config.ECRobot_InstallationDirectory)
        visibleLog('ECRobot_InstallationDirectory is not specified. Skipping check\n');
        return;
    end
    
    ecrobotMainDir = fullfile(config.ECRobot_InstallationDirectory,'ecrobotNXT');
    environmentDir = fullfile(ecrobotMainDir, 'environment');    
    setupFile =  fullfile(ecrobotMainDir,'ecrobotnxtsetup.m');    
    
    d = dir(setupFile);
    if numel(d) == 0
        visibleLog(sprintf('Cannot find setup file for ECRobot (%s)', setupFile));
    else
        dump_fileinfo(d);
    end

    % print out the MATLAB path
    silentLog('\nMATLAB Path\n');
    p=path;
    [token, str] = strtok(p, ';');
    while ~isempty(str)
        silentLog('  %s\n', token);
        [token, str] = strtok(str, ';'); %#ok<STTOK>
    end
    
    nxtOSEKDir = fullfile(environmentDir, 'nxtOSEK');
    if ~(exist(nxtOSEKDir, 'file') == 7)
        silentLog('\nUnable to find %s\n', nxtOSEKDir);
    else
        silentLog('\nOSEK directory found: %s\n', nxtOSEKDir);
    end
    
    ecrobotSetupFile = fullfile(config.ECRobot_InstallationDirectory, 'ecrobotNXT', 'environment', 'ecrobotnxtsetupinfo.m');
    if ~(exist(ecrobotSetupFile, 'file') == 2)
        silentLog('\nUnable to find %s\n', ecrobotSetupFile);
    else
        filedata = fileread(ecrobotSetupFile);
        silentLog('\n%s\n%s\n\n', ecrobotSetupFile, filedata);        
    end
    
    % print out the MATLAB path, while leaving out the MATLAB toolboxes
%     mroot = fullfile(matlabroot, 'toolbox');
%     p=path;
%     [token, str] = strtok(p, ';');
%     while ~isempty(str)
%         if ~strncmpi(token, mroot, length(mroot))        
%             silentLog('  %s\n', token);
%         end
%         [token, str] = strtok(str, ';');
%     end
end


%%
function dump_fileinfo(dd)
    for i=1:numel(dd)
        silentLog('%20s -- %8d bytes -- %s\n', datestr(dd(i).datenum), dd(i).bytes, dd(i).name);
    end
end

Contact us