Explorar o código

Fix alignment mark PSRAM issue (#2357)

* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
CaCO3 %!s(int64=2) %!d(string=hai) anos
pai
achega
9b1a83c8b4

+ 2 - 0
code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp

@@ -218,6 +218,8 @@ bool ClassFlowTakeImage::doFlow(string zwtime)
         LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
     #endif
 
+    psram_deinit_shared_memory_for_take_image_step();
+
     return true;
 }
 

+ 23 - 11
code/components/jomjol_flowcontroll/MainFlowControl.cpp

@@ -657,20 +657,32 @@ esp_err_t handler_editflow(httpd_req_t *req)
 
         string out2 = out.substr(0, out.length() - 4) + "_org.jpg";
 
-        CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in);
-        caic->CutAndSave(out2, x, y, dx, dy);
-        delete caic;    
+        if ((*flowctrl.getActStatus() == "Flow finished") && psram_init_shared_memory_for_take_image_step()) {
+            LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Taking image for Alignment Mark Update...");
 
-        CImageBasis *cim = new CImageBasis("cutref", out2);
-        if (enhance)
-        {
-            cim->Contrast(90);
-        }
+            CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in);
+            caic->CutAndSave(out2, x, y, dx, dy);
+            delete caic;   
+
+            CImageBasis *cim = new CImageBasis("cutref", out2);
+            if (enhance)
+            {
+                cim->Contrast(90);
+            }
+
+            cim->SaveToFile(out);
+            delete cim;        
 
-        cim->SaveToFile(out);
-        delete cim;        
+            psram_deinit_shared_memory_for_take_image_step();
+
+
+            zw = "CutImage Done";
+        }
+        else {
+            LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Taking image for Alignment Mark not possible while device is busy with a round!");
+            zw = "Device Busy";
+        }
 
-        zw = "CutImage Done";
         httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
         httpd_resp_send(req, zw.c_str(), zw.length()); 
         

+ 47 - 9
code/components/jomjol_helper/psram.cpp

@@ -9,6 +9,7 @@ using namespace std;
 
 void *shared_region = NULL;
 uint32_t allocatedBytesForSTBI = 0;
+std::string sharedMemoryInUseFor = "";
 
 
 /** Reserve a large block in the PSRAM which will be shared between the different steps.
@@ -33,9 +34,24 @@ bool reserve_psram_shared_region(void) {
 /*******************************************************************
  * Memory used in Take Image (STBI)
  *******************************************************************/
-void psram_init_shared_memory_for_take_image_step(void) {
-        LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init shared memory for step 'Take Image' (STBI buffers)");
+bool psram_init_shared_memory_for_take_image_step(void) {
+    if (sharedMemoryInUseFor != "") {
+        LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
+        return false;
+    }
+
+    LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init shared memory for step 'Take Image' (STBI buffers)");
     allocatedBytesForSTBI = 0;
+    sharedMemoryInUseFor = "TakeImage";
+
+    return true;
+}
+
+
+void psram_deinit_shared_memory_for_take_image_step(void) {
+    LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Deinit shared memory for step 'Take Image' (STBI buffers)");
+    allocatedBytesForSTBI = 0;
+    sharedMemoryInUseFor = "";
 }
 
 
@@ -45,7 +61,7 @@ void *psram_reserve_shared_stbi_memory(size_t size) {
     if (size >= 100000) {
         if ((allocatedBytesForSTBI + size) > TENSOR_ARENA_SIZE + MAX_MODEL_SIZE) { // Check if it still fits in the shared region
             LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM too small (STBI) to fit additional " + 
-                    std::to_string(size) + "bytes! Available: " + std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE - allocatedBytesForSTBI) + " bytes!");
+                    std::to_string(size) + " bytes! Available: " + std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE - allocatedBytesForSTBI) + " bytes!");
             return NULL;
         }
         
@@ -83,14 +99,21 @@ void psram_free_shared_stbi_memory(void *p) {
  * During this step we only use the shared part of the PSRAM
  * for the tmpImage. 
  *******************************************************************/
-void *psram_reserve_shared_tmp_image_memory(void) {  
+void *psram_reserve_shared_tmp_image_memory(void) {
+    if (sharedMemoryInUseFor != "") {
+        LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
+        return NULL;
+    }
+
     LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating tmpImage (" + std::to_string(IMAGE_SIZE) + " bytes, use shared memory in PSRAM)...");
+    sharedMemoryInUseFor = "Aligning";
     return shared_region; // Use 1th part of the shared memory for the tmpImage (only user)
 }
 
 
 void psram_free_shared_temp_image_memory(void) {
     LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for tmpImage (PSRAM, part of shared memory) is free again");
+    sharedMemoryInUseFor = "";
 }
 
 
@@ -103,18 +126,33 @@ void psram_free_shared_temp_image_memory(void) {
  * Tensor Arena. Therefore we do not need to monitor the usage.
  *******************************************************************/
 void *psram_get_shared_tensor_arena_memory(void) {
-    LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Tensor Arena (" + std::to_string(TENSOR_ARENA_SIZE) + " bytes, use shared memory in PSRAM)...");
-    return shared_region; // Use 1th part of the shared memory for Tensor
+    if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Model")) {
+        sharedMemoryInUseFor = "Digitalization_Tensor";
+        LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Tensor Arena (" + std::to_string(TENSOR_ARENA_SIZE) + " bytes, use shared memory in PSRAM)...");
+        return shared_region; // Use 1th part of the shared memory for Tensor
+    }
+    else {
+        LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
+        return NULL;
+    }
 }
 
 
 void *psram_get_shared_model_memory(void) {
-    LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Model memory (" + std::to_string(MAX_MODEL_SIZE) + " bytes, use shared memory in PSRAM)...");
-    return (uint8_t *)shared_region + TENSOR_ARENA_SIZE; // Use 2nd part of the shared memory (after Tensor Arena) for the model
+    if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Tensor")) {
+        sharedMemoryInUseFor = "Digitalization_Model";
+        LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Model memory (" + std::to_string(MAX_MODEL_SIZE) + " bytes, use shared memory in PSRAM)...");
+        return (uint8_t *)shared_region + TENSOR_ARENA_SIZE; // Use 2nd part of the shared memory (after Tensor Arena) for the model
+    }
+    else {
+        LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
+        return NULL;
+    }
 }
 
 
 void psram_free_shared_tensor_arena_and_model_memory(void) {
+    sharedMemoryInUseFor = "";
     LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for Tensor Arena and model (PSRAM, part of shared memory) is free again");
 }
 
@@ -156,7 +194,7 @@ void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps)
 
 	ptr = heap_caps_calloc(n, size, caps);
     if (ptr != NULL) {
-	    LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
+	    LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
 	}
     else {
         LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");

+ 2 - 1
code/components/jomjol_helper/psram.h

@@ -9,7 +9,8 @@ bool reserve_psram_shared_region(void);
 
 
 /* Memory used in Take Image Step */
-void psram_init_shared_memory_for_take_image_step(void);
+bool psram_init_shared_memory_for_take_image_step(void);
+void psram_deinit_shared_memory_for_take_image_step(void);
 void *psram_reserve_shared_stbi_memory(size_t size);
 void *psram_reallocate_shared_stbi_memory(void *ptr, size_t newsize);
 void psram_free_shared_stbi_memory(void *p);

+ 9 - 7
sd-card/html/edit_alignment.html

@@ -73,7 +73,7 @@ select {
 	  <tr>
 		<td style="padding-top: 10px">x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()"></td>
 		<td style="padding-top: 10px">dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchanged()"></td>
-		<td rowspan="2" style="padding-top: 10px"><input class="button" type="button" value="Update Reference" onclick="CutOutReference()"></td>	
+		<td rowspan="2" style="padding-top: 10px"><input class="button" type="button" value="Update Reference Image" onclick="CutOutReference()"></td>	
 	  </tr>
 	  <tr>
 		<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
@@ -133,7 +133,7 @@ function SaveToConfig(){
     WriteConfigININew();
     UpdateConfigReference(domainname)
     SaveConfigToServer(domainname);
-    firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000);
+    firework.launch('Reference Marks got updated. The change will get applied after the next reboot!', 'success', 5000);
 }
 
 function EnhanceContrast(){
@@ -144,8 +144,9 @@ function EnhanceContrast(){
     refInfo[aktindex]["dy"] = document.getElementById("refdy").value;       
 
     enhanceCon = true;
-    MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname);
-    UpdateReference();
+    if (MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname)) {
+        UpdateReference();
+    }
 }
 
 function UpdateReference(){
@@ -250,9 +251,10 @@ function dataURLtoBlob(dataurl) {
             refInfo[aktindex]["y"] = document.getElementById("refy").value; 
             refInfo[aktindex]["dx"] = document.getElementById("refdx").value;
             refInfo[aktindex]["dy"] = document.getElementById("refdy").value;   
-            MakeRefZW(refInfo[aktindex], domainname); 
-            UpdateReference();
-            document.getElementById("enhancecontrast").disabled = false;
+            if (MakeRefZW(refInfo[aktindex], domainname)) {
+                UpdateReference();
+                document.getElementById("enhancecontrast").disabled = false;
+            }
         }
 
         function drawGrid(){

+ 1 - 1
sd-card/html/edit_reference.html

@@ -272,7 +272,7 @@ table {
                 SaveCanvasToImage(canvas, "/config/reference.jpg", true, getDomainname());
                 showReference(param);
                 UpdatePage();
-                firework.launch('Reference got updated. It will get applied after the next reboot!', 'success', 5000);
+                firework.launch('Reference got saved. It will get applied after the next reboot!', 'success', 5000);
             }
         }
 

+ 25 - 5
sd-card/html/readconfigcommon.js

@@ -252,11 +252,21 @@ function MakeContrastImageZW(zw, _enhance, _domainname){
      var xhttp = new XMLHttpRequest();  
      try {
           xhttp.open("GET", url, false);
-          xhttp.send();     }
+          xhttp.send();
+     }
      catch (error)
      {
 //	    firework.launch('Deleting Config.ini failed!', 'danger', 30000);
      }
+
+     if (xhttp.responseText == "CutImage Done") {
+          firework.launch('Reference Image Contrast got enhanced.', 'success', 5000);
+          return true;
+     }
+     else {
+          firework.launch("Device is busy, please try again when the round got completed!", 'warning', 10000);
+          return false;
+     }
 }
 
 
@@ -268,13 +278,23 @@ function MakeRefZW(zw, _domainname){
      var xhttp = new XMLHttpRequest();  
      try {
           xhttp.open("GET", url, false);
-          xhttp.send();     }
+          xhttp.send();
+     }
      catch (error)
      {
 //	    firework.launch('Deleting Config.ini failed!', 'danger', 30000);
      }
-     _filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
-//     _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
-     FileCopyOnServer(_filetarget, _filetarget2, _domainname);
+
+     if (xhttp.responseText == "CutImage Done") {
+          _filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
+     //     _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
+          FileCopyOnServer(_filetarget, _filetarget2, _domainname);
+          firework.launch('Reference Image got updated.', 'success', 5000);
+          return true;
+     }
+     else {
+          firework.launch("Device is busy, please try again when the round got completed!", 'warning', 10000);
+          return false;
+     }
 }