|
17 | 17 | ;; |
18 | 18 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
19 | 19 | ;; |
20 | | -;; Required: helm, friendly-shell-command, projectile, cl-lib, s |
| 20 | +;; Required: helm, friendly-shell-command, projectile, s |
21 | 21 | ;; |
22 | 22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
23 | 23 | ;; |
|
53 | 53 | :type 'string) |
54 | 54 |
|
55 | 55 | (defcustom stm32-gdb-command |
56 | | - "arm-none-eabi-gdb -iex \"target extended-remote localhost:3333\" " |
| 56 | + "arm-none-eabi-gdb -iex \"target extended-remote localhost:3333\" -i=mi " |
57 | 57 | "Command to run gdb for gud with openocd remote port." |
58 | 58 | :group 'stm32 |
59 | 59 | :type 'string) |
|
64 | 64 | :group 'stm32 |
65 | 65 | :type 'string) |
66 | 66 |
|
67 | | -(require 'cl-lib) |
68 | 67 | (require 'gdb-mi) |
69 | 68 | (require 'gud) |
70 | 69 | (require 'friendly-shell-command) |
71 | 70 | (require 'projectile) |
72 | 71 | (require 'helm) |
73 | 72 | (require 's) |
74 | 73 |
|
75 | | -(defun stm32-select-file (root filter) |
| 74 | + |
| 75 | + |
| 76 | +(defun stm32--select-file (root filter) |
76 | 77 | "Select file using helm in ROOT directory and find by FILTER." |
77 | 78 | (let* ((out (s-split |
78 | 79 | "\n" |
79 | 80 | (friendly-shell-command-to-string |
80 | 81 | (s-concat "find . -type f -name '" filter "'") |
81 | 82 | :path root))) |
82 | 83 | (files (delete "" out))) |
83 | | - (when (> (length files) 0) |
84 | | - (helm :sources (helm-build-sync-source "test" |
85 | | - :candidates files |
86 | | - :fuzzy-match t) |
87 | | - :buffer "*helm find stm32*" |
88 | | - :case-fold-search helm-file-name-case-fold-search)))) |
| 84 | + (if (> (length files) 0) |
| 85 | + (helm :sources (helm-build-sync-source (concat "Select " filter) |
| 86 | + :candidates files |
| 87 | + :fuzzy-match t) |
| 88 | + :buffer "*helm find stm32*" |
| 89 | + :case-fold-search helm-file-name-case-fold-search) |
| 90 | + (user-error "No matching files")))) |
| 91 | + |
| 92 | +(defun stm32--close-process-buffer (process signal) |
| 93 | + "Close process buffer when PROCESS sends exit SIGNAL." |
| 94 | + (when (memq (process-status process) '(exit signal)) |
| 95 | + (kill-buffer (process-buffer process)))) |
| 96 | + |
| 97 | +(defun stm32--start-process-buffer (buffer-name cmd) |
| 98 | + "Run CMD in the buffer named BUFFER-NAME." |
| 99 | + (let* ((output-buffer (generate-new-buffer buffer-name)) |
| 100 | + (proc (progn |
| 101 | + (message (concat "Running " cmd)) |
| 102 | + (async-shell-command cmd |
| 103 | + output-buffer |
| 104 | + "*Messages*") |
| 105 | + (get-buffer-process output-buffer)))) |
| 106 | + (when (process-live-p proc) |
| 107 | + (set-process-sentinel proc #'stm32--close-process-buffer)))) |
| 108 | + |
| 109 | +(defun stm32--kill-gdb-if-started () |
| 110 | + "Kill gdb and openocd if running." |
| 111 | + (gud-set-buffer) |
| 112 | + (let ((proc-ocd (get-buffer-process "*stm32-gdb-server*")) |
| 113 | + (proc-gdb (get-buffer-process gud-comint-buffer))) |
| 114 | + (when (or proc-ocd proc-gdb) |
| 115 | + (if (y-or-n-p "Kill currently running gdb? ") |
| 116 | + (stm32-kill-gdb) |
| 117 | + (user-error "GDB already running!"))))) |
| 118 | + |
| 119 | + |
89 | 120 |
|
90 | 121 | (defun stm32-start-gdb-server () |
91 | | - "Run gdb server." |
| 122 | + "Run gdb server with selected config. Config files are filtered using '*.cfg'." |
92 | 123 | (interactive) |
93 | | - (let ((p (get-buffer-process "*stm32-gdb-server*"))) |
94 | | - (when p |
95 | | - (if (y-or-n-p "Kill currently running stm32-gdb-server? ") |
96 | | - (interrupt-process p) |
97 | | - (user-error "Stm32-gdb-server already running!")))) |
98 | | - (sleep-for 1) ;wait for process being killed |
99 | | - (let ((root (projectile-project-root))) |
| 124 | + (stm32--kill-gdb-if-started) |
| 125 | + (let ((root (projectile-project-root)) |
| 126 | + (buffer-name "*stm32-gdb-server*")) |
100 | 127 | (when 'root |
101 | | - (let ((file (stm32-select-file root "*.cfg"))) |
| 128 | + (let* ((file (stm32--select-file root "*.cfg")) |
| 129 | + (cmd (concat stm32-openocd-command " -f " (concat root file))) |
| 130 | + (output-buffer (generate-new-buffer buffer-name))) |
102 | 131 | (when file |
103 | | - (with-temp-buffer |
104 | | - "*stm32-gdb-server*" |
105 | | - (async-shell-command (s-concat stm32-openocd-command " -f " (concat root file)) |
106 | | - "*stm32-gdb-server*" |
107 | | - "*Messages*"))))))) |
| 132 | + (async-shell-command cmd |
| 133 | + output-buffer |
| 134 | + "*Messages*") |
| 135 | + (let ((proc (get-buffer-process output-buffer))) |
| 136 | + (when (process-live-p proc) |
| 137 | + proc))))))) |
108 | 138 |
|
109 | 139 | (defun stm32-start-gdb-elf () |
110 | 140 | "Run arm-none-eabi-gdb and select elf." |
111 | 141 | (interactive) |
112 | | - (let ((root (projectile-project-root)) |
113 | | - (p (get-buffer-process "*stm32-gdb-server*"))) |
114 | | - (when (not p) |
115 | | - (stm32-start-gdb-server)) |
116 | | - (when 'root |
117 | | - (let ((file (stm32-select-file root "*.elf"))) |
| 142 | + (stm32--kill-gdb-if-started) |
| 143 | + (let* ((root (projectile-project-root)) |
| 144 | + (p (get-buffer-process "*stm32-gdb-server*")) |
| 145 | + (server-started (when (not p) |
| 146 | + (stm32-start-gdb-server)))) |
| 147 | + (when (and 'root 'server-started) |
| 148 | + (let ((file (stm32--select-file root "*.elf"))) |
118 | 149 | (when file |
119 | | - (gud-gdb (s-concat stm32-gdb-command " " (concat root file)))))))) |
| 150 | + (save-window-excursion |
| 151 | + (gdb (s-concat stm32-gdb-command " " (concat root file))))))))) |
120 | 152 |
|
121 | 153 | (defun stm32-flash-to-mcu () |
122 | 154 | "Upload compiled binary to stm32 through gdb if gdb has been started." |
123 | 155 | (interactive) |
124 | | - (if (and (get-buffer "*stm32-gdb-server*") |
125 | | - (get-buffer "*gud-target extended-remote localhost:3333*")) |
126 | | - (progn (gdb-io-interrupt) |
127 | | - (gud-basic-call "load") |
128 | | - (gud-basic-call "cont")) |
129 | | - (message "No gdb has been started"))) |
| 156 | + (gud-set-buffer) |
| 157 | + (let ((proc (get-buffer-process gud-comint-buffer))) |
| 158 | + (or proc (error "Current buffer has no process")) |
| 159 | + (with-current-buffer gud-comint-buffer |
| 160 | + (save-excursion |
| 161 | + (interrupt-process proc) |
| 162 | + (gud-basic-call "load") |
| 163 | + (gud-basic-call "cont"))))) |
130 | 164 |
|
131 | 165 | (defun stm32-kill-gdb () |
132 | 166 | "Kill all gdb or openocd processes and buffers." |
133 | 167 | (interactive) |
134 | | - (when (get-buffer-process "*gud-target extended-remote localhost:3333*") |
135 | | - (kill-process (get-buffer-process "*gud-target extended-remote localhost:3333*"))) |
| 168 | + (gud-set-buffer) |
| 169 | + (let ((proc (get-buffer-process gud-comint-buffer))) |
| 170 | + (when proc |
| 171 | + (kill-process proc))) |
136 | 172 | (when (get-buffer-process "*stm32-gdb-server*") |
137 | 173 | (kill-process (get-buffer-process "*stm32-gdb-server*"))) |
138 | 174 | (sleep-for 1) |
| 175 | + (kill-buffer gud-comint-buffer) |
139 | 176 | (when (get-buffer "*stm32-gdb-server*") |
140 | | - (kill-buffer "*stm32-gdb-server*")) |
141 | | - (when (get-buffer "*gud-target extended-remote localhost:3333*") |
142 | | - (kill-buffer "*gud-target extended-remote localhost:3333*"))) |
| 177 | + (kill-buffer "*stm32-gdb-server*"))) |
143 | 178 |
|
144 | 179 |
|
145 | | -(defun stm32--close-process-buffer (process signal) |
146 | | - "Close process buffer when PROCESS sends exit SIGNAL." |
147 | | - (when (memq (process-status process) '(exit signal)) |
148 | | - (kill-buffer (process-buffer process)) |
149 | | - (message process "stopped"))) |
150 | 180 |
|
151 | 181 | (defun stm32--start-cubemx (&optional file) |
152 | 182 | "Run CubeMX in the buffer and open FILE." |
153 | | - (let* ((name (concat " *CubeMX " file "*")) |
154 | | - (output-buffer (generate-new-buffer name)) |
155 | | - (cmd (if 'file |
156 | | - (concat stm32-cubemx " " file) |
157 | | - stm32-cubemx)) |
158 | | - (proc (progn |
159 | | - (message (concat "Running " cmd)) |
160 | | - (async-shell-command cmd output-buffer) |
161 | | - (get-buffer-process output-buffer)))) |
162 | | - (when (process-live-p proc) |
163 | | - (set-process-sentinel proc #'stm32--close-process-buffer)))) |
164 | | - |
| 183 | + (let ((name (concat " *CubeMX " file "*")) |
| 184 | + (cmd (if 'file |
| 185 | + (concat stm32-cubemx " " file) |
| 186 | + stm32-cubemx))) |
| 187 | + (stm32--start-process-buffer name cmd))) |
165 | 188 |
|
166 | 189 | (defun stm32-open-cubemx () |
167 | 190 | "Open current project in cubeMX or just start application." |
168 | 191 | (interactive) |
169 | 192 | (save-window-excursion |
170 | 193 | (let ((root (projectile-project-root))) |
171 | 194 | (if root |
172 | | - (let ((file (stm32-select-file root "*.ioc"))) |
| 195 | + (let ((file (stm32--select-file root "*.ioc"))) |
173 | 196 | (if file |
174 | 197 | (stm32--start-cubemx (concat root file)) |
175 | 198 | (stm32--start-cubemx))) |
|
0 commit comments