上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。 基于Ubuntu18系统,补充安装所需要的库和小工具 更新软件列表 安装python3 - 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 我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。- x- j8 Q) B# d: ]! f' B! d
% u6 ]% V- z- u6 x
然后就学着官方文档的样子去验证下SDK是否安装成功% x) j2 ^: y4 F
9 [4 N' O" [* \7 ? 以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。 首先拷贝官方给的demo程序,基于GTK得hello world。 - #include <gtk/gtk.h>
, A. B, u7 u: q) g: ^- p4 ]8 N& h
7 M2 Q/ e% M9 Q5 m& s D7 B, }- static void/ a7 G E. S( o& U# V
- print_hello (GtkWidget *widget,
$ x$ z! i/ U+ ^/ u; P - gpointer data)" K5 F& J; [$ U: X& b
- {% C( g# ` g5 q7 J
- g_print ("Hello World\n");5 J6 t3 F- ^. R1 B* g$ L+ ~4 p) v
- }
. e0 A* m; s# t" z0 I( x
9 s& u& k$ V0 u2 G- static void
6 ^( Y, z: v" Z2 F3 {/ s - activate (GtkApplication *app,, m+ Y& Y' M) k9 F# ~3 d% A! W
- gpointer user_data)
1 T: j e1 }8 G, U4 R6 S8 R5 w% I( Q - {7 W1 e5 Y% [5 V. c# o; x S) t4 m
- GtkWidget *window;
, Z! }; w' C( J$ F" q }/ k - GtkWidget *button;8 y+ R5 _( P( P' ~
- GtkWidget *button_box;
. G, [& s; Q- r# a: c7 H' \! g8 f; n
4 N9 j9 R! b0 a- \$ s0 q- window = gtk_application_window_new (app);
) H/ K7 b/ e5 p- H - gtk_window_set_title (GTK_WINDOW (window), "Window");7 V! V8 J5 w- ~7 k+ b
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
, s8 ?# ~. [" U) } p) T - 8 `# v# T1 S; ^9 a4 Y* P* C* V
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);0 a+ Y: o6 Y2 [% v
- gtk_container_add (GTK_CONTAINER (window), button_box);/ C4 ]/ Y$ v3 {2 \
- % b5 _1 \8 K: H8 @
- button = gtk_button_new_with_label ("Hello World");
5 p# c3 N. |# s4 a: T+ @) T - g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
* U) N$ M. E) L9 t; e* C$ U - g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
- E* C! R& L+ p) x - gtk_container_add (GTK_CONTAINER (button_box), button);
0 J0 N9 Y6 L2 f - ! d: ^$ g, @1 D9 r
- gtk_widget_show_all (window);$ p1 r. ?. `. h# W4 R# w8 K/ m
- }
& z; Q$ V+ Y3 V$ e$ k) E - 2 X- ?( B5 A H
- int
2 \) Q, j% L g8 Y3 z1 n - main (int argc,
( Z5 ?; ]0 n' ?! x2 \" g - char **argv)1 l: {; R# z/ b
- {
- Q9 c7 F. d/ j0 d* x' { - GtkApplication *app;- i: W/ ?5 o) n5 o" R, B" W; O
- int status;: B+ q1 O3 N% x# z+ S8 f
- $ T6 I& n5 k* i4 S5 ]) s
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);9 m4 _1 ]' I5 y
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
% M8 G y; d- D - status = g_application_run (G_APPLICATION (app), argc, argv);+ u9 Z. g: f' Y$ x. G2 [0 k
- g_object_unref (app);- g$ j' Y; z& y$ D/ w! h+ E' X
- 4 A9 ]% k$ G) `! U
- return status;
# L8 n! X0 ?; j- u0 h& C - }4 e5 A+ D$ m N0 e5 J. f
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。
5 L( h9 M; o5 b9 X/ Z0 f6 {8 b- PROG = gtk_hello_world G( W0 S" I& {) t, {' Z
- SRCS = gtk_hello_world.c0 f0 @5 S0 X/ }6 g5 T9 m) i) ?
# ? o, N0 j; i- CLEANFILES = $(PROG)
5 f; E& Z, ~/ `2 N. N
( [, h/ @; p0 @$ a4 B+ \- # Add / change option in CFLAGS and LDFLAGS
$ p8 [( N( N) s, ~$ \" z - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
' A" d% P- `& ^$ y& K - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)8 Z3 l7 H% N1 d P0 @% N4 t
. B( I! D# }' D3 [- F- all: $(PROG)
4 ^& h3 P) j( S+ d7 J( F
: t7 D4 X: ~& l8 h8 S: z- $(PROG): $(SRCS) o+ s; Z% E6 {3 H6 V; i- o, Q2 Q2 N
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
- Q) E/ B- u6 Q& C/ s+ M - 3 a; z8 J1 o p% [* @! z
- clean:
" K7 C" C% \& M9 {/ V9 Q1 N* j1 D+ S - rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))# E( _4 @0 o% _! D" U( U' V9 M
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
# E/ L9 q+ f1 A0 C6 O
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。
# }0 W4 ^: c2 t0 p. j8 i
p# i$ t& [ Y( w # R4 T) z/ v+ @1 z) M" b$ m0 `5 |# d
- #include <gtk/gtk.h>% X; U7 _0 j! m `, @. @( z
- #include <stdio.h>' j( s9 _! |, k5 Q8 {9 M2 i
- #include <string.h>
4 J+ }" s! K9 n8 E - $ H6 r8 y6 E, A% m6 z( a
- char buf[50] = "";
# U, C9 l5 }& C. ~& u# H - 0 C1 v' I( t1 W, c- s7 j$ b$ x
- void calc(GtkButton *button, gpointer data)# Z3 `8 M( w" D6 P5 d
- {# U+ n( W* O0 x2 v
- const char *text = gtk_button_get_label(button);+ O" p+ z8 y' i: [* q
) j# f5 \7 g5 A- d$ R M3 d% y- //退个操作
+ y+ s( @. K! y6 w - if (0 == strcmp(text, "c"))
/ _$ \9 l( u, A1 o9 D) R - {
" j2 r: N% G1 L$ W$ `+ y0 M* ~: }. O - buf[strlen(buf) - 1] = 0;/ u% \; ^& c9 M D6 p1 q
- }else{
3 E$ P) E* }0 _ - . ~2 J/ \. A4 _; }
- int a = 0, b = 0;
l j; v2 O; b3 A7 ] - char c;
2 Z: w9 z4 Y6 }1 ^; ~( L - strcat(buf,text);
7 \8 ~1 n6 D/ J( B8 j' E2 S# } - ( L6 K, d, G8 i- k0 F R- u1 h d
- if (0 == strcmp("=", text)) {8 q* D1 w7 ?! D4 w% Q1 L
: N4 }0 D' V* B6 ]- sscanf(buf, "%d%c%d", &a, &c, &b);
" F2 j" U/ K9 a$ J$ J" b, b4 h - ' @( Q" [% Y4 B1 c1 S; L- H
- if ('+' == c) {) w* N1 k R7 v7 ?
- sprintf(buf,"%d", a+b);& e4 ?4 b; I& H( z* g& l1 W# L, ~
- }$ f" d7 J& c5 O
- else if ('-' == c) {( W4 E9 m- V. `
- sprintf(buf, "%d", a-b);
A$ P$ L& {" S: J1 j4 N: P2 x' E3 ?1 T - }
2 w6 N9 B& l+ D! y8 \ - else if ('*' == c) {
4 H6 o! o+ J- I) O - sprintf(buf, "%d", a*b);2 X2 |5 R, U/ l
- }
7 |* q2 i3 A! D; R$ `) {' ~ - else if ('/' == c) {
- M H0 w& z! L' w6 f - sprintf(buf, "%d", a/b);( A/ s7 G' ]" s* r4 n. S2 O
- }
/ z; [/ f6 X0 Y% C
+ u" W' y/ s5 I2 Q- }
8 u. ~8 z! j! i - }
8 J6 ?/ l1 M1 H% A+ _! {5 e$ u3 ^ - 7 W# i% M+ m) C( i* Y* e' s ^
- gtk_entry_set_text(GTK_ENTRY(data), buf);
; R }0 s* G- e6 ]
6 J9 o2 w: y; q: N; b/ ]5 ]# V- return;( x* ^4 O! v) z
- }( T$ z8 Z; B1 ?( c# B3 F
- $ e w2 p1 x6 v0 M3 h! c5 I, g7 h. C
- int main(int argc,char *argv[])
9 C1 x# E2 Z, c; y1 X1 ] - {
# p" A, O k/ y* w - * u' \( {+ X9 E4 L' g# l
- gtk_init(&argc, &argv);/ u9 g# L3 _+ e' v
- S2 q' }) D& f2 E1 w- - A# Z7 X; i6 z0 O6 ]# U
- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);' N' N5 p! M2 \; l2 L+ N; Y
- gtk_window_set_title (GTK_WINDOW (window), "calc");
9 r3 Q& k) Y( Q- z7 l7 ?
5 t) X) _/ r3 ^ }$ v- //创建一个表格容器5行4列; k& \8 F$ G3 s. R) \! g
- GtkWidget *table = gtk_table_new(5,4,TRUE);
/ L6 i8 p y! B7 n- k2 _( X/ P - . H8 }# h7 ~: F3 O$ g; U( @ n
- gtk_container_add(GTK_CONTAINER(window), table);2 ]9 u) i) H, v$ J) `& N: j8 L
% S- N# Y2 J: b. y9 s ^! f! \- //创建一个行编辑0 V& ]4 D* l3 `) u% f1 \$ c8 r
- GtkWidget *entry = gtk_entry_new();
: T6 p) E0 b& ^1 P4 {2 Q; X
' O2 ?' N6 H6 `5 [/ ~: G2 I- gtk_entry_set_text(GTK_ENTRY(entry), "0");
: @ ^ d5 m, ^# H" }
4 P3 W2 \$ b# E( z& h3 G0 q- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);" ?9 E* K" v! x( q, E
- q- l6 w: c# W3 R8 g- //创建多个按钮9 o3 B$ q1 k' f# n/ e
- GtkWidget *button0 = gtk_button_new_with_label("0");
$ M8 W! @' C' P8 K" a# d - GtkWidget *button1 = gtk_button_new_with_label("1");
7 ^& Q" B, k5 b' j - GtkWidget *button2 = gtk_button_new_with_label("2");
( U0 ^9 ~% h. `3 ~' h - GtkWidget *button3 = gtk_button_new_with_label("3");
! i' e; E9 j1 }+ L4 ^- v - GtkWidget *button4 = gtk_button_new_with_label("4");
: s- q# ?3 G4 C - GtkWidget *button5 = gtk_button_new_with_label("5");
" Y4 A9 f2 g8 y$ |! u9 B - GtkWidget *button6 = gtk_button_new_with_label("6");
8 h& u/ I; x8 i7 \. N6 h - GtkWidget *button7 = gtk_button_new_with_label("7");) Y. S n: }3 I
- GtkWidget *button8 = gtk_button_new_with_label("8"); X" v- o! P" N) p* Z; I$ ]8 N+ e
- GtkWidget *button9 = gtk_button_new_with_label("9");
! j& Z8 m! b8 q - * i' v5 _' ?5 s( |+ S/ M: l
- GtkWidget *button_add = gtk_button_new_with_label("+");# \, W( e2 O7 f- R% v& H" d/ p: v
- GtkWidget *button_minus = gtk_button_new_with_label("-");
0 Z- B2 H7 `* Q1 X g& {, L - GtkWidget *button_mul = gtk_button_new_with_label("*");/ ?1 e) E0 Z/ u" \
- GtkWidget *button_div = gtk_button_new_with_label("/");* T1 \' b" v$ K4 P, E
- GtkWidget *button_equal = gtk_button_new_with_label("=");
1 ^5 B5 N3 {( Z ]# ^, N9 a9 @ - GtkWidget *button_delete = gtk_button_new_with_label("c");+ D; u. c+ V0 s h) u7 D
- - q: p+ h) O7 T: E2 L# {
- " F1 x4 w3 ?8 P, \7 X
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);8 J. \( G7 ]/ _* s% B4 f
, e- p' `. v/ V$ x+ V1 E- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
) F% I T2 R' v* x - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
2 b0 F: K- b) j2 [# J - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
' ~: X" X8 g' y* P* w* ] - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
1 j; {8 |- E7 e& M7 g# P4 h - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);' h6 I0 W2 E9 T0 T% s3 S. K
- gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
; p$ X R6 ?. ] - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);7 M1 I5 G( K8 D$ p: @7 l
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);6 H+ u1 m. E; B! X
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
; b. p4 ~+ C+ y0 K H- F - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);
8 w* S& L) F* P2 i& F6 Q
) Z6 U6 h" U1 ~- ]/ C8 A- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
. x. j. P4 }) x - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);" q5 K( @# ]* W; L' ^) u9 a
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);
1 c, D( \' L$ E, M - gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
7 @* b9 n7 V% _, \* f& A - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
! ~& C) R) l* [# g. L k2 @ - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);" R* o% f2 N5 E# Y+ x6 q: h3 \! Q9 Q6 A
- . o2 D! j1 D5 S8 u
- //注册信号函数,calc()
% J% U, v$ a/ T - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry); U. K- M3 B# O
- g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);
5 P* z& ^! Q6 O4 G - g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);4 \5 \$ A, w* a6 Y l! ^
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);
$ u8 H6 {+ B3 U8 Q. d6 L! L - g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);
+ A/ D/ b0 D* I; W9 x - g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);9 q! s- P! I* n# Y! S. N H
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);, W% _* d( E$ }. `5 V3 P* k
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);& H6 B' T0 B6 P
- g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
6 i* l" i: b& }8 v$ G - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
6 v2 a: \$ M4 w1 h! h - 2 I; ]' T; Q' U: u
- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
2 o% Y! |, D# u8 _3 i3 s8 C - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);: K& g8 s+ | F" W
- g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);: e1 A6 B. v. k0 K$ }$ R7 v
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);4 `* l0 a3 m9 N$ M# X) h/ g
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);' P" Y$ F: a; U* H! r8 b9 @- `
- g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);
. E9 J9 Q# C6 o. K: q" I$ m
2 t, k7 \! J. a0 z3 ~
4 K% T) V% r+ R0 j- gtk_widget_show_all(window);
8 z. R3 E0 j. y, l; r - : s$ k( O3 v7 A i
- //主事件循环
2 g' P: X# M5 X7 ~. Z - gtk_main();6 T% U- S3 _+ k, n z
- 0 V2 w! `- T5 g( B
- return 0;5 E1 @% Q2 m8 y" m
- }) ]) V7 ~; Q( \; p4 L
复制代码 以上程序,编译运行后,就可以有以下得效果
; O' X8 r. ?; E. N1 J
; P @8 U; v8 Z2 ], m# B/ x
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。 |