]> git.sur5r.net Git - openocd/commitdiff
server, target, cortex_m: add deinit_target to the API to free resources
authorPaul Fertser <fercerpav@gmail.com>
Wed, 11 Feb 2015 08:08:40 +0000 (11:08 +0300)
committerPaul Fertser <fercerpav@gmail.com>
Mon, 9 Mar 2015 08:34:46 +0000 (08:34 +0000)
This should facilitate dynamic target creation and removal.

Currently it helps with getting 0 bytes lost report from Valgrind on
exit (after talking to a nucleo board). However, 1,223,886 bytes in
5,268 blocks are still reachable which means the app holds pointers to
that data on exit. The majority comes from the jtag command queue,
there're also many blocks from TCL command registration.

Change-Id: I7523234bb90fffd26f7d29cdd7648ddd221d46ab
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Reviewed-on: http://openocd.zylin.com/2544
Tested-by: jenkins
Reviewed-by: Stian Skjelstad <stian@nixia.no>
src/server/server.c
src/target/cortex_m.c
src/target/cortex_m.h
src/target/hla_target.c
src/target/target.c
src/target/target.h
src/target/target_type.h

index 9832762f640dcb69838a60f233fac88527cb6328..73d8b5b652c97636055d72243574fc61e70d72ef 100644 (file)
@@ -559,6 +559,7 @@ int server_init(struct command_context *cmd_ctx)
 int server_quit(void)
 {
        remove_services();
+       target_quit();
 
 #ifdef _WIN32
        WSACleanup();
index 028bfd80850da5697ec00a03488d3d2fcffd3ed5..4dc92c834e549395f91758a88d99d102c2444fd8 100644 (file)
@@ -1685,6 +1685,15 @@ static int cortex_m_init_target(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
+void cortex_m_deinit_target(struct target *target)
+{
+       struct cortex_m_common *cortex_m = target_to_cm(target);
+
+       free(cortex_m->fp_comparator_list);
+       cortex_m_dwt_free(target);
+       free(cortex_m);
+}
+
 /* REVISIT cache valid/dirty bits are unmaintained.  We could set "valid"
  * on r/w if the core is not running, and clear on resume or reset ... or
  * at least, in a post_restore_context() method.
@@ -2362,4 +2371,5 @@ struct target_type cortexm_target = {
        .target_create = cortex_m_target_create,
        .init_target = cortex_m_init_target,
        .examine = cortex_m_examine,
+       .deinit_target = cortex_m_deinit_target,
 };
index 8a284bd9887f8ff90544e8b587fdbd667f15092e..28189e02e978f57690fcf7787b93690262e90ec1 100644 (file)
@@ -210,5 +210,6 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo
 void cortex_m_enable_breakpoints(struct target *target);
 void cortex_m_enable_watchpoints(struct target *target);
 void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target);
+void cortex_m_deinit_target(struct target *target);
 
 #endif /* CORTEX_M_H */
index f778d23aa7cdf3a84c43c9da1089fd9b468ea619..a05a99ff5fa83f3ab4b71406a32b14b23d0fd8f1 100644 (file)
@@ -780,6 +780,7 @@ struct target_type hla_target = {
        .deprecated_name = "stm32_stlink",
 
        .init_target = adapter_init_target,
+       .deinit_target = cortex_m_deinit_target,
        .target_create = adapter_target_create,
        .examine = cortex_m_examine,
        .commands = adapter_command_handlers,
index b559a51555b8c45e1c1b834fb3cf42dc91267bd9..5c88384d83eb202211dfd328f7b7be99d347cd13 100644 (file)
@@ -1800,6 +1800,31 @@ int target_free_working_area(struct target *target, struct working_area *area)
        return target_free_working_area_restore(target, area, 1);
 }
 
+void target_quit(void)
+{
+       struct target_event_callback *pe = target_event_callbacks;
+       while (pe) {
+               struct target_event_callback *t = pe->next;
+               free(pe);
+               pe = t;
+       }
+       target_event_callbacks = NULL;
+
+       struct target_timer_callback *pt = target_timer_callbacks;
+       while (pt) {
+               struct target_timer_callback *t = pt->next;
+               free(pt);
+               pt = t;
+       }
+       target_timer_callbacks = NULL;
+
+       for (struct target *target = all_targets;
+            target; target = target->next) {
+               if (target->type->deinit_target)
+                       target->type->deinit_target(target);
+       }
+}
+
 /* free resources and restore memory, if restoring memory fails,
  * free up resources anyway
  */
index f709d6a5a760f5a5e0abc6f0989004a568bd4fb0..fbce19f5194d97622150fe997c80af9d46e5fa15 100644 (file)
@@ -615,6 +615,11 @@ int target_free_working_area(struct target *target, struct working_area *area);
 void target_free_all_working_areas(struct target *target);
 uint32_t target_get_working_area_avail(struct target *target);
 
+/**
+ * Free all the resources allocated by targets and the target layer
+ */
+void target_quit(void);
+
 extern struct target *all_targets;
 
 uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer);
index cf3c864c80f072c326682c898b79466c4110c485..234cdfb0071fce12e8885cd2eff2467a4a83997b 100644 (file)
@@ -225,6 +225,13 @@ struct target_type {
         * */
        int (*init_target)(struct command_context *cmd_ctx, struct target *target);
 
+       /**
+        * Free all the resources allocated by the target.
+        *
+        * @param target The target to deinit
+        */
+       void (*deinit_target)(struct target *target);
+
        /* translate from virtual to physical address. Default implementation is successful
         * no-op(i.e. virtual==physical).
         */