made kernel more efficient, and some caching in gcode objects
authorArthur Wolf <wolf.arthur@gmail.com>
Tue, 30 Oct 2012 21:59:52 +0000 (22:59 +0100)
committerArthur Wolf <wolf.arthur@gmail.com>
Tue, 30 Oct 2012 21:59:52 +0000 (22:59 +0100)
src/libs/Kernel.cpp
src/libs/Kernel.h
src/modules/communication/GcodeDispatch.cpp
src/modules/communication/utils/Gcode.cpp
src/modules/communication/utils/Gcode.h
src/modules/robot/Stepper.cpp
src/modules/tools/extruder/Extruder.cpp
src/modules/tools/temperaturecontrol/TemperatureControl.cpp
src/modules/utils/configurator/Configurator.cpp
src/modules/utils/configurator/Configurator.h

index ed60e41..7aa777c 100644 (file)
@@ -5,8 +5,6 @@
       You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>. 
 */
 
-using namespace std;
-#include <vector>
 #include "libs/Kernel.h"
 #include "libs/Module.h"
 #include "libs/Config.h"
@@ -49,6 +47,9 @@ const ModuleCallback kernel_callback_functions[NUMBER_OF_DEFINED_EVENTS] = {
 // The kernel is the central point in Smoothie : it stores modules, and handles event calls
 Kernel::Kernel(){
 
+    // Value init for the arrays
+    for( uint8_t i = 0; i < NUMBER_OF_DEFINED_EVENTS; i++ ){ this->hooks[i][0] = NULL; }
+
     // Config first, because we need the baud_rate setting before we start serial 
     this->config         = new Config();
 
@@ -97,17 +98,31 @@ void Kernel::add_module(Module* module){
 }
 
 void Kernel::register_for_event(unsigned int id_event, Module* module){
-    this->hooks[id_event].push_back(module);
+    uint8_t current_id = 0; 
+    Module* current = this->hooks[id_event][0];
+    while(current != NULL ){
+        if( current == module ){ return; }
+        current_id++;
+        current = this->hooks[id_event][current_id];
+    }
+    this->hooks[id_event][current_id] = module;
+    this->hooks[id_event][current_id+1] = NULL;
 }
 
 void Kernel::call_event(unsigned int id_event){
-    for(unsigned int i=0; i < this->hooks[id_event].size(); i++){
-        (this->hooks[id_event][i]->*kernel_callback_functions[id_event])(this);
+    uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
+    while(current != NULL ){   // For each active stepper
+        (current->*kernel_callback_functions[id_event])(this);
+        current_id++;
+        current = this->hooks[id_event][current_id];
     }
 }
 
 void Kernel::call_event(unsigned int id_event, void * argument){
-    for(unsigned int i=0; i < this->hooks[id_event].size(); i++){
-        (this->hooks[id_event][i]->*kernel_callback_functions[id_event])(argument);
+    uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
+    while(current != NULL ){   // For each active stepper
+        (current->*kernel_callback_functions[id_event])(argument);
+        current_id++;
+        current = this->hooks[id_event][current_id];
     }
 }
index 2b64fab..22db613 100644 (file)
@@ -37,9 +37,6 @@
 #define ON_IDLE                    11
 
 
-using namespace std;
-#include <vector>
-
 typedef void (Module::*ModuleCallback)(void * argument);
 
 //Module manager
@@ -73,7 +70,7 @@ class Kernel {
         Digipot*          digipot;
 
     private:
-        vector<Module*> hooks[NUMBER_OF_DEFINED_EVENTS]; // When a module asks to be called for a specific event ( a hook ), this is where that request is remembered
+        Module* hooks[NUMBER_OF_DEFINED_EVENTS][16]; // When a module asks to be called for a specific event ( a hook ), this is where that request is remembered
 
 };
 
index dc8c95c..5f96a9a 100644 (file)
@@ -97,6 +97,7 @@ void GcodeDispatch::on_console_line_received(void * line){
                 Gcode gcode = Gcode();
                 gcode.command = single_command;
                 gcode.stream = new_message.stream;
+                gcode.prepare_cached_values();
 
                 //Dispatch message!
                 this->kernel->call_event(ON_GCODE_RECEIVED, &gcode );
index 2e19821..4fb6221 100644 (file)
@@ -51,3 +51,18 @@ double Gcode::get_value( char letter ){
     //__enable_irq();
     return 0; 
 }
+
+void Gcode::prepare_cached_values(){
+    if( this->has_letter('G') ){
+        this->has_g = true;
+        this->g = this->get_value('G');
+    }else{
+        this->has_g = false;
+    }
+    if( this->has_letter('M') ){
+        this->has_m = true;
+        this->m = this->get_value('m');
+    }else{
+        this->has_m = false;
+    }
+}
index 54f3efc..0966143 100644 (file)
@@ -11,7 +11,7 @@
 #include <string>
 using std::string;
 #include "libs/StreamOutput.h"
-// Object to represent a Gcode comman
+// Object to represent a Gcode command
 #include <stdlib.h>
 
 class Gcode {
@@ -19,12 +19,18 @@ class Gcode {
         Gcode();
         bool has_letter( char letter );
         double get_value ( char letter );
+        void prepare_cached_values();
 
         string command;
         double millimeters_of_travel;
         bool call_on_gcode_execute_event_immediatly;
         bool on_gcode_execute_event_called;
 
+        bool has_m;
+        bool has_g;
+        unsigned int m;
+        unsigned int g;
+
         StreamOutput* stream;
 };
 #endif
index de36eab..73e4d19 100644 (file)
@@ -82,12 +82,11 @@ void Stepper::on_play(void* argument){
 void Stepper::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
 
-    if( gcode->has_letter('M')){
-        int code = (int) gcode->get_value('M');
-        if( code == 17 ){
+    if( gcode->has_m){
+        if( gcode->m == 17 ){
             this->turn_enable_pins_on(); 
         }
-        if( code == 84 || code == 18 ){
+        if( gcode->m == 84 || gcode->m == 18 ){
             this->turn_enable_pins_off(); 
         }
     }
index 2313bd3..782df7b 100644 (file)
@@ -95,19 +95,18 @@ void Extruder::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
 
     // Absolute/relative mode
-    if( gcode->has_letter('M')){
-        int code = (int) gcode->get_value('M');
-        if( code == 82 ){ this->absolute_mode = true; }
-        if( code == 83 ){ this->absolute_mode = false; }
-        if( code == 84 ){ this->en_pin->set(1); }
+    if( gcode->has_m ){
+        if( gcode->m == 82 ){ this->absolute_mode = true; }
+        if( gcode->m == 83 ){ this->absolute_mode = false; }
+        if( gcode->m == 84 ){ this->en_pin->set(1); }
     }
 
     // The mode is OFF by default, and SOLO or FOLLOW only if we need to extrude
     this->mode = OFF;
 
-    if( gcode->has_letter('G') ){
+    if( gcode->has_g ){
         // G92: Reset extruder position
-        if( gcode->get_value('G') == 92 ){
+        if( gcode->g == 92 ){
             if( gcode->has_letter('E') ){
                 this->current_position = gcode->get_value('E');
                 this->target_position  = this->current_position;
@@ -135,7 +134,6 @@ void Extruder::on_gcode_execute(void* argument){
             }
         }
     }
-
 }
 
 // When a new block begins, either follow the robot, or step by ourselves ( or stay back and do nothing )
index 48929fd..beab989 100644 (file)
@@ -92,29 +92,23 @@ void TemperatureControl::on_config_reload(void* argument){
 
 void TemperatureControl::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
-
-
-    //gcode->stream->printf("%u %u %u \r\n",gcode->has_letter('M'), (gcode->get_value('M') == 104), gcode->has_letter('S') );
-
-    // Set temperature without waiting
-    if( gcode->has_letter('M') && gcode->get_value('M') == this->set_m_code && gcode->has_letter('S') ){
-        //gcode->stream->printf("setting to %f meaning %u  \r\n", gcode->get_value('S'), this->temperature_to_adc_value( gcode->get_value('S') ) );
-        this->set_desired_temperature(gcode->get_value('S')); 
-    } 
-
-    // Set temperature and wait
-    if( gcode->has_letter('M') && gcode->get_value('M') == this->set_and_wait_m_code && gcode->has_letter('S') ){
-        this->set_desired_temperature(gcode->get_value('S'));
-        
-        // Pause 
-        this->kernel->pauser->take(); 
-        this->waiting = true; 
-    
-    } 
-
-    // Get temperature
-    if( gcode->has_letter('M') && gcode->get_value('M') == this->get_m_code ){
-        gcode->stream->printf("get temperature: %f current:%f target:%f bare_value:%u \r\n", this->get_temperature(), this->new_thermistor_reading(), this->desired_adc_value, this->kernel->adc->read(this->thermistor_pin)  );
+    if( gcode->has_m){
+        // Set temperature without waiting
+        if( gcode->m == this->set_m_code && gcode->has_letter('S') ){
+            //gcode->stream->printf("setting to %f meaning %u  \r\n", gcode->get_value('S'), this->temperature_to_adc_value( gcode->get_value('S') ) );
+            this->set_desired_temperature(gcode->get_value('S')); 
+        } 
+        // Set temperature and wait
+        if( gcode->m == this->set_and_wait_m_code && gcode->has_letter('S') ){
+            this->set_desired_temperature(gcode->get_value('S'));
+            // Pause 
+            this->kernel->pauser->take(); 
+            this->waiting = true; 
+        } 
+        // Get temperature
+        if( gcode->m == this->get_m_code ){
+            gcode->stream->printf("get temperature: %f current:%f target:%f bare_value:%u \r\n", this->get_temperature(), this->new_thermistor_reading(), this->desired_adc_value, this->kernel->adc->read(this->thermistor_pin)  );
+        }
     } 
 }
 
index d321c93..77a22bf 100644 (file)
@@ -16,7 +16,7 @@
 
 void Configurator::on_module_loaded(){
     this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
-//    this->register_for_event(ON_GCODE_EXECUTE);
+//    this->register_for_event(ON_GCODE_RECEIVED);
 //    this->register_for_event(ON_MAIN_LOOP);
 }
 
@@ -37,7 +37,7 @@ void Configurator::on_console_line_received( void* argument ){
 }
 
 // Process and respond to eeprom gcodes (M50x)
-void Configurator::on_gcode_execute(void* argument){
+void Configurator::on_gcode_received(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
     if( gcode->has_letter('G') ){
         int code = gcode->get_value('G');
index 3468c2e..3805b3b 100644 (file)
@@ -30,7 +30,7 @@ class Configurator : public Module {
 
         void on_module_loaded();
         void on_console_line_received( void* argument );
-        void on_gcode_execute( void* argument );
+        void on_gcode_received( void* argument );
         void on_main_loop( void* argument );
 
         void config_get_command( string parameters, StreamOutput* stream );