]> rtime.felk.cvut.cz Git - mf624-simulink.git/commitdiff
Improve cleanup on termination (unmaps mappings and closes fd)
authorMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 23 Jul 2013 18:06:49 +0000 (20:06 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 23 Jul 2013 18:06:49 +0000 (20:06 +0200)
mf624_SIMULINK.c
mf624_SIMULINK.h
sfAnalogInput.c
sfAnalogOutput.c
sfDigitalOutput.c
sfReadPWM.c

index 51cca623ba87cb2456b20f042db59d70a4c9d00a..54406d879d05534c4e5a7ec3d4a802d6984dc77b 100644 (file)
@@ -42,6 +42,7 @@
 #define UIO "uio0"
 
 mf624_state_t* mfst=NULL;
+unsigned mfst_refcnt = 0;
 
 static int bar_mapping_fill(bar_mapping_t *barmap, const char *uio_dev, int map_nr)
 {
@@ -111,6 +112,19 @@ static int bar_mapping_setup(bar_mapping_t *barmap, int device_fd)
        return 0;
 }
 
+static int bar_mapping_destroy(bar_mapping_t *barmap)
+{
+       off_t mmap_start;
+        size_t mmap_size;
+       size_t page_mask = sysconf(_SC_PAGESIZE) - 1;
+       
+       mmap_start = barmap->mmap_offset & ~page_mask;
+       mmap_size = barmap->mmap_offset + barmap->size + page_mask - mmap_start;
+       mmap_size &= ~page_mask;
+
+       return munmap(barmap->mmap_addr, mmap_size);
+}
+
 /****************************************************************/
 
 #define BUFF_SMALL             32
@@ -436,8 +450,8 @@ int mf624_init(SimStruct *S)
                        if (S) ssSetErrorStatus(S,"/dev/" UIO ": mmap_regions failed");
                        goto close;
                }
-
        }
+       mfst_refcnt++;
        return 0;
 close:
        close(mfst->device_fd);
@@ -447,6 +461,38 @@ free:
        return -1;
 }
 
+int mf624_done()
+{
+       if (mfst) {
+               if (--mfst_refcnt == 0) {
+                       close(mfst->device_fd);
+                       bar_mapping_destroy(&mfst->bar0);
+                       bar_mapping_destroy(&mfst->bar2);
+                       bar_mapping_destroy(&mfst->bar4);
+                       free(mfst);
+                       mfst = NULL;
+               }
+       }
+}
+
+
+/** 
+ * Check whether MF624 card is initialized.
+ * 
+ * @param S 
+ * 
+ * @return Zero if MF624 is initialized, -1 othewise.
+ */
+int mf624_check(SimStruct *S)
+{
+       if (mfst==NULL) {
+               if (S) ssSetErrorStatus(S, "MF624 is not initialized");
+               return -1;
+       }
+       else
+               return 0;
+}
+
 /*int main(int argc, char* argv[])
 {
        mf624_state_t* mfst = &mf624_state;
index 4ee62b9f86fadb7f40c1dc28cf84bda56efed69d..50ef8168b8fdf5c52e84763060f28806cdf396ed 100644 (file)
@@ -137,5 +137,7 @@ extern int ADC_enable(mf624_state_t* mfst, adc_channel_t channel);
 extern double ADC_read(mf624_state_t* mfst, adc_channel_t channel);
 
 int mf624_init(SimStruct *S);
+int mf624_check(SimStruct *S);
+int mf624_done();
 
 #endif
index efd2f3184e0285231d0647d7c60f34b5832cabf5..21ff7708a7724112380af8c72fe2b8afa97dc846 100644 (file)
@@ -185,7 +185,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     int i;
     int res,res1;
     
-    if (mf624_init(S) != 0)
+    if (mf624_check(S) != 0)
            return;
 
     // Activate trigger to start conversion
@@ -255,10 +255,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
  */
 static void mdlTerminate(SimStruct *S)
 {
-    if(mfst != NULL){
-        free(mfst);
-        mfst=NULL;
-    }
+    mf624_done(S);
 }
 
 
index 987a67c326318c4c92f500515e4bfc3dc0d0bfae..d6d89a861405c76932157e423d3dcadca2442186 100644 (file)
@@ -166,7 +166,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     //mf624_state_t* mfst = ssGetPWorkValue(S,0);
     int out;
 
-    if (mf624_init(S) != 0)
+    if (mf624_check(S) != 0)
            return;
 
     if(u[0] > 9.9988){
@@ -222,15 +222,15 @@ static void mdlOutputs(SimStruct *S, int_T tid)
 static void mdlTerminate(SimStruct *S)
 {
     //mf624_state_t* mfst = ssGetPWorkValue(S,0);
-    if (mf624_init(0) != 0)
+    if (mf624_check(NULL) != 0)
            return;
 
     /*At the end of simulation disable D/A outputs*/
     mf624_write32((mf624_read32(MFST2REG(mfst, 0, GPIOC_reg))
                   & ~GPIOC_DACEN_mask), // disable output,
                  MFST2REG(mfst, 0, GPIOC_reg));
-    free(mfst);
-    mfst=NULL;
+
+    mf624_done();
 }
 
 
index c0a6c4837a68e09b352613fee1145fb5cd642a9f..81c06077864daa189e0945e32e8c2f964754c4b1 100644 (file)
@@ -164,7 +164,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
 {
     const real_T *u = (const real_T*) ssGetInputPortSignal(S,0);
 
-    if (mf624_init(S) != 0)
+    if (mf624_check(S) != 0)
            return;
 
     if(u[0] > 0.5){
@@ -219,10 +219,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
  */
 static void mdlTerminate(SimStruct *S)
 {
-    if(mfst!=NULL){
-        free(mfst);
-        mfst=NULL;
-    }
+       mf624_done();
 }
 
 
index ac193e40f58f6ab9b853dc445ef087030349f7bd..fcd406ece4f53d14bedea7a8f7f8167699a18358 100644 (file)
@@ -173,7 +173,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     unsigned int period;
     unsigned int c0,c1,c2,c4;
     
-    if (mf624_init(S) != 0)
+    if (mf624_check(S) != 0)
            return;
        
     c0 = mf624_read32(MFST2REG(mfst,4,CTR0));
@@ -233,22 +233,11 @@ static void mdlOutputs(SimStruct *S, int_T tid)
  */
 static void mdlTerminate(SimStruct *S)
 {
-    if (mf624_init(NULL) != 0)
+    if (mf624_check(NULL) != 0)
            return;
 
-    /* FIXME: This is ugly! */
-    if(mfst!=NULL){
-        mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL));
-        free(mfst);
-        mfst=NULL;
-    } else {
-        mfst = malloc(sizeof(mf624_state_t));
-       if (mf624_init(S) != 0)
-               return;
-        mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL));
-        free(mfst);
-        mfst=NULL;
-    }
+    mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL));
+    mf624_done();
 }