Skip to content

Commit e3f1e17

Browse files
author
Alexandr Lutsay
committed
Use HELM, gud, projectile. Update readme
1 parent 3069714 commit e3f1e17

File tree

2 files changed

+105
-124
lines changed

2 files changed

+105
-124
lines changed

Readme.md

Lines changed: 22 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,73 +2,44 @@
22
***
33
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
44

5-
Some functions for work with stm32 arm microcontrollers in EMACS.
5+
Some functions for work with ARM microcontrollers in EMACS. All functions works in respect of projectile project and uses HELM for selection.
66

7-
Video of work: https://youtu.be/M7RBQsq5_lc
8-
9-
here is an overview of how it works, the starting and loading process to the microcontroller.
10-
11-
![Projectile Demo](assets/overview.gif)
7+
- `stm32-start-gdb-server` starts openocd gdb server with selected config
8+
- `stm32-start-gdb-elf` starts openocd gdb server with selected config and `arm-none-eabi-gdb` session with selected `.elf`
9+
- `stm32-flash-to-mcu` executes `load` and `cont` commands in GDB session
10+
- `stm32-kill-gdb` stops openocd and GDB session
11+
- `stm32-open-cubemx` open CubeMX with selected `.ioc` or without
1212

1313

1414
## Required:
1515
***
16-
- irony-mode https://github.com/Sarcasm/irony-mode
17-
- rtags
18-
- python
19-
- cmake
20-
- clang
21-
- https://github.com/SL-RU/STM32CubeMX_cmake
22-
- (optional) st-link https://github.com/texane/stlink
23-
- (optional) openocd
24-
- (optional) Ninja
16+
- openocd
17+
- arm-none-eabi-gdb
18+
- [helm](https://emacs-helm.github.io/helm/)
19+
- [projectile](https://docs.projectile.mx/projectile/index.html)
20+
- [friendly-shell-command](https://github.com/p3r7/friendly-shell)
21+
- [s.el](https://github.com/magnars/s.el)
22+
- (optional) CubeMX
2523

2624

2725
## Install:
2826
***
29-
0) install and configure irony-mode and rtags
27+
0) install and configure helm, projectile and other deps
3028
1) clone repository to /.emacs.d/stm32
31-
2) execute "git submodule update --init" to clone STM32CubeMX\_cmake to /.emacs.d/stm32/STM32CubeMX_cmake
32-
3) Change paths to yours in stm32.el
33-
4) add to your init file (require 'stm32)
29+
2) add to your init file (require 'stm32)
30+
3) customize if needed
31+
3432

3533
## How to use:
3634
***
37-
WORK IN PROGRESS!!!
38-
`STM32-Emacs` can use two diferent tools for debuggin
39-
40-
### GDB and st-link
41-
***
42-
1) Create STM32CubeMx project and generate it for `Makefile`
43-
2) <kbd>M-x</kbd>`stm32-new-project`<kbd>[RET]</kbd>*select CubeMX project path*
44-
3) open main.c
45-
4) C-c . C or <kbd>M-x</kbd>`stm32-cmake-build`<kbd>[RET]</kbd> to compile
46-
5) connect stlink to your PC
47-
6) <kbd>M-x</kbd>`stm32-run-st-util`<kbd>[RET]</kbd> to start gdb server
48-
7) start GDB debugger with <kbd>M-x</kbd>`stm32-start-gdb`<kbd>[RET]</kbd>
49-
8) in gdb) "load" to upload file to MC and "cont" to run. Or execute <kbd>M-x</kbd>`stm32-flash-to-mcu`<kbd>[RET]</kbd>. For more see https://github.com/texane/stlink
50-
9) good luck!
51-
52-
**NOTE**: The step 6 can be omited as the step 7 cheks if `st-util` is running and starts it if it's not running, but it is recommended the first time to run the steps one by one in case of configuration errors, once you are in the debug window you can skip step 6 in the next debugging sessions.
53-
54-
### GDB and Openocd
55-
***
56-
Openocd requieres a .cfg file to properly function you need to provide the file in this case it must be called openocd.cfg(you may change it in the custom varible `*stm32-openocd-config-name*`), and example file is provided (openocd.cfg) the file needs to be located in your project root.
57-
58-
1) Create STM32CubeMx project and generate it for `Makefile`
59-
2) <kbd>M-x</kbd>`stm32-new-project`<kbd>[RET]</kbd> *select CubeMX project path*
60-
3) put the board.cfg in your project root(an example file named board.cfg is provided in this repo)
61-
3) open main.c
62-
4) C-c . C or <kbd>M-x</kbd>`stm32-cmake-build`<kbd>[RET]</kbd> to compile
63-
5) connect stlink to your PC
35+
Openocd requieres a `.cfg` file to properly function you need to place `.cfg` in any directory of current project.
36+
37+
1) Create project and compile `.elf`
38+
2) <kbd>M-x</kbd>`stm32-start-gdb-eld`<kbd>[RET]</kbd>, select openocd config `.cfg`, then select `.elf`
6439
6) <kbd>M-x</kbd>`stm32-run-openocd`<kbd>[RET]</kbd> to start openocd server
65-
7) start GDB debugger with <kbd>M-x</kbd>`stm32-start-openocd-gdb`<kbd>[RET]</kbd>
66-
8) in gdb) "load" to upload file to MC and "cont" to run. Or execute <kbd>M-x</kbd>`stm32-flash-to-mcu`<kbd>[RET]</kbd>.
40+
8) in gdb console execute `load` to upload file to MCU and `cont` to run. Or execute <kbd>M-x</kbd>`stm32-flash-to-mcu`<kbd>[RET]</kbd>.
6741
9) debug your project and good luck!
6842

69-
**NOTE**: The step 6 can be omited as the step 7 cheks if `openocd` is running and starts it if it's not running, but it is recommended the first time to run the steps one by one in case of configuration errors, once you are in the debug window you can skip step 6 in the next debugging sessions.
70-
71-
**NOTE**: You can manually select executable to debug using `stm32-run-openocd-gdb-custom-path`
7243

7344
#### RTOS support
7445
***
@@ -89,15 +60,6 @@ If your RTOS is supported you need to do the following steps for enabling debugg
8960
***
9061
Once you are in the debuger window you can load and test your prject, but the default gdb window acts like a terminal and is not very helpful in regards of context and data, so its a good idea to use gdb in many windows mode you can activate it in your startup config file with `(gdb-many-windows 1)` or with <kbd>M-x</kbd> gdb-many-windows <kbd>[RET]</kbd>
9162

92-
### Compilation funcitions
93-
***
94-
You can build or clean and build your projects with the following functions.
95-
96-
- <kbd>M-x</kbd>`stm32-cmake-build` <kbd>[RET]</kbd>
97-
this is the equivalent of cleand and build of most IDE's and it recompiles every source file of your project
98-
99-
- <kbd>M-x</kbd>`stm32-make-build` <kbd>[RET]</kbd>
100-
the equivalent of build of most IDE's with this you can compile only the modified source files of your project scince the last compilation, this is useful if you only changed a couple of lines in your project as it makes the compilation proces faster.
10163

10264
### Closing stm32-debugger
10365
***
@@ -110,10 +72,6 @@ This will kill the gdb process and the st-link or openocd proces depending on wh
11072
After CubeMx project regeneration or adding new libraries or new sources you need to do M-x stm32-cmake-build
11173

11274

113-
# IMPORTANT
114-
***
115-
If you have error in cmsis_gcc.h do <kbd>M-x</kbd>`M-x stm32-fix-vfpcc`<kbd>[RET]</kbd>. It will change some lines in cmsis_gcc.h and will create backup cmsis_gcc.h.bak.
116-
11775
# License:
11876
***
11977
This program is distributed under the terms of GNU General

stm32.el

Lines changed: 83 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
;;
1818
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1919
;;
20-
;; Required: helm, friendly-shell-command, projectile, cl-lib, s
20+
;; Required: helm, friendly-shell-command, projectile, s
2121
;;
2222
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2323
;;
@@ -53,7 +53,7 @@
5353
:type 'string)
5454

5555
(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 "
5757
"Command to run gdb for gud with openocd remote port."
5858
:group 'stm32
5959
:type 'string)
@@ -64,112 +64,135 @@
6464
:group 'stm32
6565
:type 'string)
6666

67-
(require 'cl-lib)
6867
(require 'gdb-mi)
6968
(require 'gud)
7069
(require 'friendly-shell-command)
7170
(require 'projectile)
7271
(require 'helm)
7372
(require 's)
7473

75-
(defun stm32-select-file (root filter)
74+
75+
76+
(defun stm32--select-file (root filter)
7677
"Select file using helm in ROOT directory and find by FILTER."
7778
(let* ((out (s-split
7879
"\n"
7980
(friendly-shell-command-to-string
8081
(s-concat "find . -type f -name '" filter "'")
8182
:path root)))
8283
(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+
89120

90121
(defun stm32-start-gdb-server ()
91-
"Run gdb server."
122+
"Run gdb server with selected config. Config files are filtered using '*.cfg'."
92123
(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*"))
100127
(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)))
102131
(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)))))))
108138

109139
(defun stm32-start-gdb-elf ()
110140
"Run arm-none-eabi-gdb and select elf."
111141
(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")))
118149
(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)))))))))
120152

121153
(defun stm32-flash-to-mcu ()
122154
"Upload compiled binary to stm32 through gdb if gdb has been started."
123155
(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")))))
130164

131165
(defun stm32-kill-gdb ()
132166
"Kill all gdb or openocd processes and buffers."
133167
(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)))
136172
(when (get-buffer-process "*stm32-gdb-server*")
137173
(kill-process (get-buffer-process "*stm32-gdb-server*")))
138174
(sleep-for 1)
175+
(kill-buffer gud-comint-buffer)
139176
(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*")))
143178

144179

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")))
150180

151181
(defun stm32--start-cubemx (&optional file)
152182
"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)))
165188

166189
(defun stm32-open-cubemx ()
167190
"Open current project in cubeMX or just start application."
168191
(interactive)
169192
(save-window-excursion
170193
(let ((root (projectile-project-root)))
171194
(if root
172-
(let ((file (stm32-select-file root "*.ioc")))
195+
(let ((file (stm32--select-file root "*.ioc")))
173196
(if file
174197
(stm32--start-cubemx (concat root file))
175198
(stm32--start-cubemx)))

0 commit comments

Comments
 (0)