Michael Spencer / Smoothie

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Config.cpp Source File

Config.cpp

00001 /*
00002       This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
00003       Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
00004       Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00005       You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
00006 */
00007 
00008 using namespace std;
00009 #include <vector>
00010 #include <string>
00011 
00012 #include "libs/Kernel.h"
00013 #include "Config.h"
00014 #include "ConfigValue.h"
00015 #include "ConfigSource.h"
00016 #include "ConfigCache.h"
00017 #include "libs/nuts_bolts.h"
00018 #include "libs/utils.h"
00019 #include "libs/SerialMessage.h"
00020 #include "libs/ConfigSources/FileConfigSource.h"
00021 #include "libs/ConfigSources/FirmConfigSource.h"
00022 
00023 // Add various config sources. Config can be fetched from several places.
00024 // All values are read into a cache, that is then used by modules to read their configuration
00025 Config::Config(){
00026     this->config_cache_loaded = false;
00027 
00028     // Config source for firm config found in src/config.default
00029     this->config_sources.push_back( new FirmConfigSource() );
00030 
00031     // Config source for */config files
00032     FileConfigSource* fcs = NULL;
00033     if( file_exists("/local/config") )
00034         fcs = new FileConfigSource("/local/config", LOCAL_CONFIGSOURCE_CHECKSUM);
00035     else if( file_exists("/local/config.txt") )
00036         fcs = new FileConfigSource("/local/config.txt", LOCAL_CONFIGSOURCE_CHECKSUM);
00037     if( fcs != NULL ){
00038         this->config_sources.push_back( fcs );
00039         fcs = NULL;
00040     }
00041     if( file_exists("/sd/config") )
00042        fcs = new FileConfigSource("/sd/config",    SD_CONFIGSOURCE_CHECKSUM   );
00043     else if( file_exists("/sd/config.txt") )
00044        fcs = new FileConfigSource("/sd/config.txt",    SD_CONFIGSOURCE_CHECKSUM   );
00045     if( fcs != NULL )
00046         this->config_sources.push_back( fcs );
00047 
00048     // Pre-load the config cache
00049     this->config_cache_load();
00050 
00051 }
00052 
00053 void Config::on_module_loaded(){}
00054 
00055 void Config::on_console_line_received( void* argument ){}
00056 
00057 // Set a value in the config cache, but not in any config source
00058 void Config::set_string( string setting, string value ){
00059     ConfigValue* cv = new ConfigValue;
00060     cv->found = true;
00061     get_checksums(cv->check_sums, setting);
00062     cv->value = value;
00063 
00064     this->config_cache.replace_or_push_back(cv);
00065 
00066     THEKERNEL->call_event(ON_CONFIG_RELOAD);
00067 }
00068 
00069 // Get a list of modules, used by module "pools" that look for the "enable" keyboard to find things like "moduletype.modulename.enable" as the marker of a new instance of a module
00070 void Config::get_module_list(vector<uint16_t>* list, uint16_t family){
00071     for( unsigned int i=1; i<this->config_cache.size(); i++){
00072         ConfigValue* value = this->config_cache.at(i);
00073         //if( value->check_sums.size() == 3 && value->check_sums.at(2) == CHECKSUM("enable") && value->check_sums.at(0) == family ){
00074         if( value->check_sums[2] == CHECKSUM("enable") && value->check_sums[0] == family ){
00075             // We found a module enable for this family, add it's number
00076             list->push_back(value->check_sums[1]);
00077         }
00078     }
00079 }
00080 
00081 
00082 // Command to load config cache into buffer for multiple reads during init
00083 void Config::config_cache_load(){
00084 
00085     // First clear the cache
00086     this->config_cache_clear();
00087 
00088     // First element is a special empty ConfigValue for values not found
00089     ConfigValue* result = new ConfigValue;
00090     this->config_cache.push_back(result);
00091 
00092     // For each ConfigSource in our stack
00093     for( unsigned int i = 0; i < this->config_sources.size(); i++ ){
00094         ConfigSource* source = this->config_sources[i];
00095         source->transfer_values_to_cache(&this->config_cache);
00096     }
00097 
00098     this->config_cache_loaded = true;
00099 }
00100 
00101 // Command to clear the config cache after init
00102 void Config::config_cache_clear(){
00103     while( ! this->config_cache.empty() ){
00104         delete this->config_cache.back();
00105         this->config_cache.pop_back();
00106     }
00107     this->config_cache_loaded = false;
00108 }
00109 
00110 // Three ways to read a value from the config, depending on adress length
00111 ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c ){
00112     uint16_t check_sums[3];
00113     check_sums[0] = check_sum_a;
00114     check_sums[1] = check_sum_b;
00115     check_sums[2] = check_sum_c;
00116     return this->value(check_sums);
00117 }
00118 
00119 ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b){
00120     uint16_t check_sums[3];
00121     check_sums[0] = check_sum_a;
00122     check_sums[1] = check_sum_b;
00123     check_sums[2] = 0x0000;
00124     return this->value(check_sums);
00125 }
00126 
00127 ConfigValue* Config::value(uint16_t check_sum){
00128     uint16_t check_sums[3];
00129     check_sums[0] = check_sum;
00130     check_sums[1] = 0x0000;
00131     check_sums[2] = 0x0000;
00132     return this->value(check_sums);
00133 }
00134 
00135 // Get a value from the configuration as a string
00136 // Because we don't like to waste space in Flash with lengthy config parameter names, we take a checksum instead so that the name does not have to be stored
00137 // See get_checksum
00138 ConfigValue* Config::value(uint16_t check_sums[]){
00139     ConfigValue* result = this->config_cache[0];
00140     bool cache_preloaded = this->config_cache_loaded;
00141     if( !cache_preloaded ){ this->config_cache_load(); }
00142 
00143     for( unsigned int i=1; i<this->config_cache.size(); i++){
00144         // If this line matches the checksum
00145         bool match = true;
00146         unsigned int counter = 0;
00147         while(check_sums[counter] != 0x0000 && counter <= 2 ){
00148              if(this->config_cache[i]->check_sums[counter] != check_sums[counter] ){
00149                 match = false;
00150                 break;
00151             }
00152             counter++;
00153         }
00154         if( match == false ){
00155             continue;
00156         }
00157         result = this->config_cache[i];
00158         break;
00159     }
00160 
00161     if( !cache_preloaded ){
00162         this->config_cache_clear();
00163     }
00164     return result;
00165 }
00166 
00167 
00168