上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。
) c) X g+ L* m9 a2 D 基于Ubuntu18系统,补充安装所需要的库和小工具- L6 s! f# z3 I! t
更新软件列表 安装python3
- Q* U3 ?& C; {% @- sudo apt-get install gawk wget git diffstat unzip texinfo gcc-multilib chrpath socat cpio python3 python3-pip python3-pexpect
复制代码 其他工具- sudo apt-get install libssl-dev libgmp-dev libmpc-dev lz4 zstd
复制代码 编译器等组件 - sudo apt-get install build-essential libncurses-dev libyaml-dev libssl-dev
复制代码 默认使用python3 - sudo apt install python-is-python3
复制代码 其他有用的工具 - sudo apt-get install coreutils bsdmainutils sed curl bc lrzsz corkscrew cvs subversion mercurial nfs-common nfs-kernel-server libarchive-zip-perl dos2unix texi2html libxml2-utils
复制代码 执行完以上内容,就可以下载和安装SDK软件包了。从以下地址获取最新的SDK https://www.st.com/en/embedded-software/stm32mp1dev.html#get-software$ l& R* ?0 A- h8 q4 B* i
我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。/ ]( w8 G/ V# Z6 v0 t
6 r) ^3 i% a' e. A
然后就学着官方文档的样子去验证下SDK是否安装成功。
# S5 [% u8 ~, u. s
2 }/ n! S T# m6 H+ u9 ~# V8 } 以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。; _1 g) ?* a: y6 d$ e
首先拷贝官方给的demo程序,基于GTK得hello world。
& k. l) I, {- u
. ]8 K: T9 M* X( f9 ^- #include <gtk/gtk.h>
9 ~. l0 P, q: M& |( o - $ D# y2 P+ U# S8 v
- static void i1 S. T5 T( f S T
- print_hello (GtkWidget *widget,
; f; N1 [! q& N- a& D. |, b+ W& D - gpointer data)
9 e7 N1 A9 G% h2 w5 c - {' C9 P$ _) ^# k6 \$ E! I Z# X
- g_print ("Hello World\n");7 O2 T7 {& U1 f8 M9 T
- }
2 X r! T3 }$ I- ]: h( t. F9 {
K( M1 K) C* V1 J1 y, ]5 m# z- static void
/ Q' t6 \8 P7 A - activate (GtkApplication *app,
3 }1 L- L3 ]+ T0 o6 T$ i# [ - gpointer user_data); w6 _, B1 Z/ h: ]
- {; e+ J! i) Y* ]) F/ {& i3 a; {$ \
- GtkWidget *window;8 U0 }" j* p8 c: g- G7 y1 N- n) [
- GtkWidget *button;
& `' `8 e0 v! U9 P$ l - GtkWidget *button_box;
" y5 H) i" k" m; L - ; Y" j2 K9 F* Q5 \+ E
- window = gtk_application_window_new (app);3 G1 d6 ~3 \& r4 N3 K" e
- gtk_window_set_title (GTK_WINDOW (window), "Window");5 I/ ~$ s; k$ T) ~; F
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);6 t% b5 C5 G, N& ~2 y, m! M
- 5 e, q: n, e! t2 B' u
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);0 O ^5 k* d5 v$ v' S$ ?
- gtk_container_add (GTK_CONTAINER (window), button_box);
! ?/ P. Z# _# {& F3 e# i - % M5 [0 ~4 u0 l F& ~( p, u5 a
- button = gtk_button_new_with_label ("Hello World");# \5 C% G2 i; e/ T5 A& n* L+ D! u
- g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);( R5 I% v+ U8 L h/ ]/ C: N
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);' _& w% E! H# Z4 C w. X
- gtk_container_add (GTK_CONTAINER (button_box), button);/ G7 S0 M1 o. t+ g/ X3 n9 ?
1 l+ y6 q( l+ n* l& K1 h- gtk_widget_show_all (window);
9 A: B2 K# M& N3 v4 O2 K' O - }
9 X& p" S' u! D8 s* Z - % S, a: @" w, j1 D0 Q6 @7 [1 L; u, d
- int
6 r- c9 j7 G) ^7 f. m, f9 f - main (int argc,* k! D) Y: Q" G
- char **argv)
. L* H+ e/ l! h1 g# o6 E - {
8 Y+ E0 Y [) V4 ^: U - GtkApplication *app;
) f! w* u6 D/ J4 y. j - int status;
! X8 w! N7 d4 y6 N; m - 6 d4 c3 U: K5 R: X; W- L
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
8 f, V( G7 D9 x8 x; H8 n - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);' W _+ [# G- k
- status = g_application_run (G_APPLICATION (app), argc, argv);; |3 e1 Q7 o3 m$ t
- g_object_unref (app);- G4 ]. M7 A, k0 Z6 }1 c
3 J$ B' K- e0 y6 N& H- return status;
/ k0 r1 [ ]- d ?. a; D/ J - }
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 - PROG = gtk_hello_world- x7 j: H4 Z* }* {" U* T# M1 c
- SRCS = gtk_hello_world.c c! S7 r" F2 Y% |$ U: Q2 w
" y2 e) S5 L. \. {( F" L v6 K% W- CLEANFILES = $(PROG)5 y& r+ L/ j$ @+ k, k$ {( J
* `6 A8 y2 K. ]' I: e. h, `- # Add / change option in CFLAGS and LDFLAGS4 `; s% x0 g* z4 n: a
- CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
! E2 x$ u' }; ]& d% C% C! F - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)
7 _6 A5 j( Q/ B0 P8 c# e - ' s) s7 o" `6 y- k( E- b
- all: $(PROG)
( x) x3 Y$ K2 y - : v$ y6 V; _; K5 U9 R7 a6 ^
- $(PROG): $(SRCS)" t( L' L* I g1 Z% ^
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)8 N w' f9 k+ v* Q3 V
+ y/ z( }& A& ]' c- clean:; k2 W+ `! E' \; K/ o! l
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。9 ]- \. @* V& e! @4 V, j: @! y
; A3 E2 @# _% {2 k. i7 ]6 l: g
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。
! E- R1 ?' p, G. ^& M ~6 E) }/ `9 Z+ p$ c; i% m
- #include <gtk/gtk.h>
% p& Q' k. Z% G5 |$ s - #include <stdio.h>
1 h# s( p& v+ Q' I - #include <string.h>
- S! h: [2 l8 v6 `, \ -
9 B6 C) _' Q& W' b4 z5 L - char buf[50] = "";9 n- m4 b9 k" i
-
7 }1 k) G+ X/ S6 q/ n' b& v5 O - void calc(GtkButton *button, gpointer data)
( |- ?' p* X1 P - {
. u8 @2 J7 ~$ m5 H5 O9 ?3 t* Z - const char *text = gtk_button_get_label(button);
& m/ g; @) m. F+ [* m -
% O O; K$ C. S4 O- B+ X - //退个操作
( y7 @! P" p+ o/ @5 K' J - if (0 == strcmp(text, "c"))
# r& g' c" {/ M# h8 w3 Z! z5 @ - { P; C1 t' T1 R( L, l1 Q9 s9 j
- buf[strlen(buf) - 1] = 0;
" v9 x- V/ X( f8 N - }else{- a! f% p7 c" r* n( F0 }8 @1 g
- # \+ J5 x$ h- O5 F
- int a = 0, b = 0;
4 ]$ M) I* F& C) l' [1 w - char c;- |/ T- M- E+ B2 K
- strcat(buf,text);
' }2 Q+ \2 R l+ ~% c" m -
; h v0 o9 B9 q3 w8 N- ~& S. u - if (0 == strcmp("=", text)) {
. Y7 W. f+ V/ H* i* A7 |, ?6 N -
( U% w6 W" ~+ B+ R - sscanf(buf, "%d%c%d", &a, &c, &b);
' c9 i) B$ M2 {% \ - . J; P/ q9 L6 m! Y
- if ('+' == c) {
! @* x/ B* }3 S* i+ E$ m - sprintf(buf,"%d", a+b);
9 [* V& I- H. O! T - }& U6 J% L- B5 E
- else if ('-' == c) {
/ h0 I5 Q- N+ U; `9 }+ L - sprintf(buf, "%d", a-b);
' M' z* m1 a! P1 w# l" |0 L' w - }
! Q4 J) y; g6 D1 n% j' J& h; i6 X" b - else if ('*' == c) {( `3 a$ Q, g( X7 W* o, O' y
- sprintf(buf, "%d", a*b);2 J0 l$ v$ n- z' y, M
- }
/ m/ G: X! g0 |; {- B - else if ('/' == c) {' p) D# o% L. J$ [; n" f B
- sprintf(buf, "%d", a/b);% T v. ?3 d& v
- }- \4 w- a! b: z3 C
-
; u: C+ S* p* M - }
9 P( v1 _" s9 I7 X1 T% o- d - }
V0 U, h# m( j2 z - $ ? }1 R; O s
- gtk_entry_set_text(GTK_ENTRY(data), buf);8 k' Y2 U; Q$ i$ r6 f
-
4 s* u) {5 K- B. l& I* D - return;" S- V9 R8 ]3 X- I" t9 c
- }
8 A0 C4 F6 Y" y p7 P* ^7 M -
+ U* K; A! f% I - int main(int argc,char *argv[])
8 @4 C) G, q8 Y$ N: V$ ` - {& }. d# \( t" z g
6 r0 ^' h( U5 ^; k, |. z- gtk_init(&argc, &argv);+ g1 m; u: k: C" s) m( F$ e5 a
- * v2 @1 d7 ~* B; r; k3 B/ I; d" u
5 O" \7 k' b( f9 b+ r1 }/ z4 _" P- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
7 ^; h0 F9 {0 q+ j% a# t) F - gtk_window_set_title (GTK_WINDOW (window), "calc");: b1 B$ M1 I, d7 y b
- 5 i7 @4 o7 l& Y' D+ F
- //创建一个表格容器5行4列
, u% |7 u, a9 \: E - GtkWidget *table = gtk_table_new(5,4,TRUE);6 ^4 P# q! F9 s- `+ g
0 V- n( P" i8 L) A' A) z- gtk_container_add(GTK_CONTAINER(window), table);4 p+ z8 U* T7 _4 b" A; n
- ' S1 s$ V3 K7 w( {- y& S
- //创建一个行编辑
2 }6 q( g9 R3 z1 t/ W - GtkWidget *entry = gtk_entry_new();
9 B( f C6 t1 S. j0 g) b - ; o4 t7 j' e1 K& l5 z+ ~+ |; ~
- gtk_entry_set_text(GTK_ENTRY(entry), "0");
8 ~4 m2 Q% i: i& r$ j5 e - + t" t4 ?; ^; d8 P
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);/ k% F, g! i" g
-
8 p* y5 D8 r0 g: Y8 A - //创建多个按钮$ x! \: z% s; N7 a
- GtkWidget *button0 = gtk_button_new_with_label("0");
7 g' Z& [5 `# k) P5 C0 r4 b/ I; I( c% k - GtkWidget *button1 = gtk_button_new_with_label("1");6 v3 V( \& s" T% B+ s
- GtkWidget *button2 = gtk_button_new_with_label("2");
7 F0 W l! Z9 ^" s9 s; V9 f - GtkWidget *button3 = gtk_button_new_with_label("3");
5 d7 f1 Q' Z' E - GtkWidget *button4 = gtk_button_new_with_label("4");
6 i! {2 u. _6 }1 X0 b: Y& c - GtkWidget *button5 = gtk_button_new_with_label("5");. `; f! F6 U4 R ?
- GtkWidget *button6 = gtk_button_new_with_label("6");
3 U% y+ p+ }* Z0 l5 M& V5 i - GtkWidget *button7 = gtk_button_new_with_label("7");
4 H* R) k( w1 U6 D* G3 D$ E - GtkWidget *button8 = gtk_button_new_with_label("8");
k# o0 F% Y! s& p6 E - GtkWidget *button9 = gtk_button_new_with_label("9");
% r3 Q: E$ N% Q/ h8 A+ R! d) v - / V9 I7 j. C' \
- GtkWidget *button_add = gtk_button_new_with_label("+");
7 w" D3 R, m1 R* i - GtkWidget *button_minus = gtk_button_new_with_label("-");& g- H. B& `( K# h
- GtkWidget *button_mul = gtk_button_new_with_label("*");
% b# s4 r4 ]; `' d; s - GtkWidget *button_div = gtk_button_new_with_label("/");2 r( b& K6 J2 ^+ u( h. S
- GtkWidget *button_equal = gtk_button_new_with_label("=");7 E1 t* Y u+ D/ |: r" f
- GtkWidget *button_delete = gtk_button_new_with_label("c");
) D2 y! ?; R0 d9 Y I -
. G: L$ R2 E: ?& Q+ i- W$ l- U
! `: W. N( Q, ^ b- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);
5 c8 J$ _5 l% g6 D5 z - ) m) l( \9 c8 _3 p% [
- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);# p+ G) c1 E b/ v/ ^) {% m9 N3 U
- gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
; ?6 ^0 T# x/ @( C8 n8 [' t x - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
5 A1 l; E9 W7 J# F - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);! f& z: O; P/ ?" I/ @0 g, K" n
- gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
& B4 ^3 e# G$ v9 F5 @ - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
" y0 \5 ]" y% ^9 C1 V8 S9 p( r6 g2 E5 ^( ` - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);7 \. ^. R" }% h3 W7 ~
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);
5 ]9 P I) ? q( a* l0 u" f L4 a m - gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
* n- k: w6 a5 S$ ^7 v: s) ~' j8 W( [ - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);
( K& W) {+ |2 J' I - ( ?9 Q- s3 V4 j( v" l/ I
- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
# y3 k$ k- ?% S - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);
6 @$ y5 r1 ?( B+ | - gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);9 H, y; y* t$ N$ j% A% E4 m. o$ s+ O8 V1 f
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
% C$ q/ ^5 ?, ~: d7 \) B3 C - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
. ^0 H4 K' g; @) ? - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);, f) h/ O- u8 `% ]* y' [ V
-
- e" {- { h2 _8 a - //注册信号函数,calc()
& G1 O7 F2 J! J- z; r' |2 | - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);
# Z6 X4 Q+ c+ k/ e: ^ - g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);
( F/ ]! r4 w/ o4 H# Z) x6 ` - g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);' g$ v3 t* } Q8 [& Y9 b" y: E6 _- E& y
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);" T( m( r' S9 `6 f
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);( l9 V' U E5 r$ g9 f
- g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);9 R+ {/ b- ]8 e& ~7 b+ B- B
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);; P y2 a/ v2 X( [1 K5 {
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
, @) V& |" a' T9 D - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);$ \& @) F4 S, @
- g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
, j5 j: w' T+ r H* t# { - n0 @ q5 U: O/ D, Q
- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);9 p8 Y; I& D: K9 H& u$ ~
- g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
- @9 N k) x/ T6 }, l - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);
3 x0 B: ]5 V7 \4 A; x0 M - g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);) u( _' N+ A, u( E
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
/ d$ O& N/ x" Q% ^$ X6 X* l+ p& D - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);; V) @8 W% H0 ]
-
% {: Y# v# b% E8 ~: w, y - 9 e) N% }$ N; q( ]8 d3 {9 `6 ]
- gtk_widget_show_all(window);" _5 l& K a' z3 V4 a' @
-
. _( i1 s9 X% T O) C1 R+ b - //主事件循环+ }1 q. p) I; u7 r
- gtk_main();
) ?- j2 R0 e: B4 ~8 k -
4 N6 p8 q: F: W1 ^( {3 \ - return 0;
* ^% J' H& J9 @8 U% } - }
复制代码 以上程序,编译运行后,就可以有以下得效果。 0 ?' N' L8 j3 \- {
. Z% t/ t v2 D. M, C 操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。4 s* a6 e/ K; z! v% P# s
搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。6 v5 |# C/ o; h, C
* t- Z. m6 o7 j# b) C |
官方板子不错,这么快就上手了。我的是odydess资料太少了。正在学习