上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。
' u. _6 U( f8 X. J 基于Ubuntu18系统,补充安装所需要的库和小工具
. R4 s8 |! Y5 J2 z( r! D: x 更新软件列表 安装python3
4 ~ v( _3 }; K9 u( ~' x6 S; T4 X- 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
% V: d7 N6 D, e1 m, N$ z 我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。
! D5 F" @* ^4 x" L5 J; r( R
& ^/ N, v+ u. x+ A' n
然后就学着官方文档的样子去验证下SDK是否安装成功。/ o2 E/ T7 O' c& `5 t0 L
7 o: p! ?: h0 U, w 以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。
* k( Q+ s$ H0 b 首先拷贝官方给的demo程序,基于GTK得hello world。7 V/ g8 M3 B Y/ P3 u
% g6 j' e% E6 J$ M- #include <gtk/gtk.h>
+ b* I/ \ @5 Q4 P# p+ k( v; A) b - 0 }; e( g7 l1 G
- static void# l/ w! v. k8 A) T/ h9 @5 ?( Z/ K
- print_hello (GtkWidget *widget,* b: y% `" c( m) j9 d
- gpointer data): J/ W$ w# X0 y$ \. _
- {! T; Y, L# }! c6 N: ~" o; `3 J
- g_print ("Hello World\n");; T6 X4 o- m& V1 B6 k; @/ Y
- }
( c5 X2 ?, n5 h) h, G - % j) s% C# k) F. e
- static void( ?& b6 Q5 F" a! O9 Y9 e
- activate (GtkApplication *app,
6 p: X9 y' O E, r1 N# S - gpointer user_data) U9 V6 A0 w- }! _9 e6 f! B" w
- {
7 }5 G9 U; u( Z! ^2 B0 l; s* K B - GtkWidget *window;& U! ~8 w) G+ s- @% b9 t
- GtkWidget *button;
# A0 X- |3 u& w$ _6 x: h2 | - GtkWidget *button_box;8 G0 M% u" x& k# x4 T/ r8 U
- ' u: O9 m) `' w$ F2 {
- window = gtk_application_window_new (app);: d- q% Z5 Y8 Y: C, ~& C8 Q& K* u
- gtk_window_set_title (GTK_WINDOW (window), "Window");4 _( H' j1 l4 O' H2 J1 |/ t+ l
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
0 G) b$ E/ B. r
$ {9 W5 d1 W5 p4 @! R7 W- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
' q2 R9 A9 l8 }6 ]5 } - gtk_container_add (GTK_CONTAINER (window), button_box);( ^1 o7 y/ O. g4 Y, @* }
# O" V: Q: S ]* G4 D" E. P- button = gtk_button_new_with_label ("Hello World");! _% H! V' E# `! |; z
- g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);. a- H; w. Y: i6 U! r
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);$ M8 _# e4 u5 q% J1 J% Y0 I4 b2 [ O' P
- gtk_container_add (GTK_CONTAINER (button_box), button);
4 c% K$ k7 F Y3 }+ C. ^ O# Y
_8 {3 w0 a+ l: u$ ^: J3 }8 z- gtk_widget_show_all (window);
) v$ P. G# b; H+ d - }
' D5 N u% y3 Q- Q1 a1 a s. s, P - 6 J! a p4 X% ]9 ]7 }
- int
* `, g ?1 u8 `3 K# t. z& z* y/ G - main (int argc,( \: n% o/ A/ b/ K
- char **argv), Q X( C* |& r8 \7 ]
- {- u; e p, A0 P' E! \8 O
- GtkApplication *app;, J% i; F, s. o* A: w2 K$ _
- int status;
' W+ i. l, k8 n5 ? - 0 q8 [ x0 [8 g
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);7 E3 u q. \+ t% w; L" l% V
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);5 O$ c3 f$ z( R
- status = g_application_run (G_APPLICATION (app), argc, argv);- X$ {! \4 @# p
- g_object_unref (app);$ p0 _( r, k; |8 `2 Y) q
- , l& M* N) n5 `7 K5 I3 x
- return status;6 Q R; D7 G* X1 t3 Q
- }
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 - PROG = gtk_hello_world3 R; g7 x/ c1 o
- SRCS = gtk_hello_world.c- G$ p# \: B$ B6 T L
- : P5 z' l: c' z: @) q, Q% s* {5 F2 \
- CLEANFILES = $(PROG)
, z+ J: c' ~1 y8 @8 p
7 P. d0 s# Y' P' c7 [ i- # Add / change option in CFLAGS and LDFLAGS
2 Q4 O6 o6 b: J% K) |* x) z' A - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)+ c+ H1 q% [# A6 ]
- LDFLAGS += $(shell pkg-config --libs gtk+-3.0)) Y: d- \# ` m) l5 L( b
$ s/ p8 {, @0 |' ?1 C- all: $(PROG)5 c# i* W) m) a
- ) p4 L `6 _4 L' M. v1 ~( B) l J
- $(PROG): $(SRCS), t8 ?3 K. |8 `( J& m, g. K/ s
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
/ l1 D- R( S) r2 _+ N; a - . O5 ]6 i+ j9 E1 z! S
- clean:
p% ^, h: j) V5 A) O0 G - rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
0 a& L, N3 V# N" P& j* d
8 C( \) e: B3 p: Q* g: \+ N$ Y/ b 接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。; ~" v4 P" t" S4 b+ M1 ~9 s) H1 {- z
T3 y+ _5 x7 l! I, K7 d% O- #include <gtk/gtk.h>, q! W, c# d6 C7 Z. J# f4 n
- #include <stdio.h>' c+ o6 V4 P6 Y9 w2 f+ P
- #include <string.h>
9 a7 y3 @1 \5 u' p( c: N: I - : z$ u7 A! y% T& s2 s* b0 a6 [6 u
- char buf[50] = "";& ?" d2 t9 H8 B. L) I
- ; v8 Q! d {4 }/ f0 v& B4 S+ Q
- void calc(GtkButton *button, gpointer data)
! O5 I" d$ [2 `5 k - {
$ j0 z$ k) d0 a: D. m$ e - const char *text = gtk_button_get_label(button);, E' s/ B0 l% S3 }' J
-
, e/ K( x9 S2 D: H1 Q" v" S - //退个操作
% w1 B, W0 L4 P, ~: h- C1 b, P - if (0 == strcmp(text, "c")) # o' O3 v D# d- i# b
- {
h. n K: m* {7 S; t - buf[strlen(buf) - 1] = 0;
5 d( F2 S" J g) z/ ? - }else{+ `. G, i' M' U' t8 Q) a$ i. U
- B T, l- G4 L: R
- int a = 0, b = 0;
7 F2 |2 Q9 F* @5 `# \5 I - char c;( P5 d$ W( b+ x" e
- strcat(buf,text);
& W, m: K9 ]( C4 h+ { K) w4 ] -
+ y) R7 c8 j& c0 W$ x+ d - if (0 == strcmp("=", text)) {
% C* l8 g- f4 Z0 a6 @0 S - 7 Y' X. f) \9 Y, ?+ k2 [# a
- sscanf(buf, "%d%c%d", &a, &c, &b);! `* O2 c- T& K4 g
- 0 }) S; @- _& o! l& c, k2 {
- if ('+' == c) {
) Z/ |6 Q, O5 }4 x& I4 n - sprintf(buf,"%d", a+b);
; ^. S1 B* ]% G1 _0 A - }
/ K5 V5 {& L" L7 G+ D - else if ('-' == c) {9 Y% w- ^ k. m+ R2 s( ~
- sprintf(buf, "%d", a-b); f' a+ q; p& ?) b/ C/ S4 ?
- }; A4 C* v( x" N% p- Y" c
- else if ('*' == c) {
+ {9 G& g# K! h8 l- C$ t$ [ - sprintf(buf, "%d", a*b);
, \8 m3 {" @ Y" p$ t5 b - }/ v1 v- C, E# i) }2 d# Y6 \+ `
- else if ('/' == c) {
- c/ t& b) D+ w- M- Z - sprintf(buf, "%d", a/b);
4 z4 a/ n; e$ p9 t2 ~* @( o - }
1 S4 X6 n' I. M$ D, G -
0 D/ e: Z/ S7 C' @/ `" c& E1 b& m - }/ }1 n2 m: a" h+ O z' V
- }
2 x! U' {' t. y7 z5 l - " F! d0 H4 ~% \2 h
- gtk_entry_set_text(GTK_ENTRY(data), buf);
+ P8 e, S' r, a! n - . A, ]6 i, G4 V6 t& x) X4 D
- return;( s9 U8 W9 o" |& J
- }
( w& x Z1 }; K: w - / v* H' W% y) Z. S" @1 A2 E- X
- int main(int argc,char *argv[])
# U& `* `" l, y( b* i+ h - {0 ]3 V+ a) q2 I1 Y
3 Z9 f- W' J/ j5 o2 }: G( S- gtk_init(&argc, &argv);+ m+ a# n; u) B5 ]
- 6 I+ |* S- g. c8 s! h" N
' n1 {% L3 |' ]( {- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);) \2 ]1 Z# b5 e% U5 I: [$ b2 w
- gtk_window_set_title (GTK_WINDOW (window), "calc");8 Q# r) n* j0 Y1 n( z3 P E: H9 u
- 1 I0 C$ b3 J( \* s3 n% u& G
- //创建一个表格容器5行4列
5 W: s# c2 [9 v - GtkWidget *table = gtk_table_new(5,4,TRUE);
. ?6 D- W% P" C2 c1 j" e - - l9 W" ~- v' \7 K7 T! y3 `
- gtk_container_add(GTK_CONTAINER(window), table);
E% [" w0 L. V+ A, |# q -
, s! H3 i8 E& _/ i3 }6 D& q - //创建一个行编辑
1 V6 w3 Z0 I( t2 ]# j% V - GtkWidget *entry = gtk_entry_new();
+ M$ U" x: C9 |5 H - + u* G2 u) w/ Q. F% e$ j
- gtk_entry_set_text(GTK_ENTRY(entry), "0");
0 C! G. t! [2 F l% b, @
?; x8 L) `+ G! x( H- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
* K7 W) Z6 S8 P! S5 s -
/ x) L1 d$ H, ] t- p' O - //创建多个按钮
9 F0 {. ]- H9 o& D( ?$ s0 v - GtkWidget *button0 = gtk_button_new_with_label("0");
r( D Q- [* d# a1 ] - GtkWidget *button1 = gtk_button_new_with_label("1");; ?( v$ ]7 u! X& b/ G& X& |
- GtkWidget *button2 = gtk_button_new_with_label("2");1 f' }' i* v% E1 P' p
- GtkWidget *button3 = gtk_button_new_with_label("3");; l/ I2 E- S, f. O
- GtkWidget *button4 = gtk_button_new_with_label("4");# W" _( F1 C# Y4 q! X
- GtkWidget *button5 = gtk_button_new_with_label("5");
$ I" k5 n3 n/ Z3 f. B' d( H - GtkWidget *button6 = gtk_button_new_with_label("6");2 ~* [6 d* L* ^" b; n
- GtkWidget *button7 = gtk_button_new_with_label("7");
5 w, E) J# A% w6 N - GtkWidget *button8 = gtk_button_new_with_label("8");; M5 M$ I3 [ \% m
- GtkWidget *button9 = gtk_button_new_with_label("9");
& ^* w5 g+ B7 ^% k0 B7 I -
3 a( j9 U1 f2 [# F8 a - GtkWidget *button_add = gtk_button_new_with_label("+");
) d; f* k" W$ y' | - GtkWidget *button_minus = gtk_button_new_with_label("-");
' A2 q2 Y I! \/ R2 v2 }) \) p - GtkWidget *button_mul = gtk_button_new_with_label("*");
8 M& ^$ \: D4 j% d - GtkWidget *button_div = gtk_button_new_with_label("/");
5 L1 [8 z1 x# N1 B - GtkWidget *button_equal = gtk_button_new_with_label("=");
1 O/ j( j( `( l* o - GtkWidget *button_delete = gtk_button_new_with_label("c");) G' D6 |3 w( w$ T9 |3 Q
-
: |* j0 V1 o. U. M# X - 8 b: g+ O7 a! X9 f; D5 M6 F
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);
$ m# s+ G$ d# A+ g/ x -
. `/ K n7 C+ @; a9 m - gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
$ u, C0 Y% y2 ^+ S - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
/ [, ~5 J8 }' k7 q: |" | - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);3 L1 k8 R/ V) o2 T }# ^- `
- gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
, M. j9 P5 y# A- G - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
G! `& t5 ?+ H - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
) L# W5 G3 Q( A* |, r7 j* @ c- `2 D - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);& m' ? X4 n: y% Z8 H2 N5 Z! i
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);( ?" ^8 j* G% j6 }
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);/ \' R! M% v7 U# h
- gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);
1 @# K( L3 n4 Z! Z8 K. M' e* d -
- n! q( j1 W5 x& g - gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);3 n( m& A* f; c. I7 C
- gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);
% b! H \9 _% @6 L7 q - gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);8 |6 r0 L Z( j$ C
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);% j" Q9 [; P! Y" H
- gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
/ ^& e7 b, q- d9 v - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);. n+ f3 O0 I' o7 ?8 J
- 2 Q- E! n0 o' }* w
- //注册信号函数,calc()3 Y6 ~7 _* v8 q- q& E3 b( s
- g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);* F3 K* e* z9 J- X
- g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);7 V# H- ^+ j8 C; Z! C4 x S
- g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);# [; T9 Q4 B+ K9 d; a9 J# b
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);3 ~7 p: s, v: A6 ]6 q" n
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);" [7 m" S2 v3 d, o. F2 h& a
- g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);1 `- {0 Q3 l) \; _: c6 x
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);
# {% A* I0 y. F! w - g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
8 x: O6 J, }& ]! }0 E& _; a% G& B - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
$ t9 D# q6 x3 o/ Q }6 b - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
( G: r" t+ w7 }. }) u -
5 T+ P( X! ]- X6 x - g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
3 s+ W$ w" h. s8 H. x! q - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
7 a8 R0 f( r4 M1 x! j7 E" g. m2 } - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);4 `2 W4 P3 P, ~2 v, F
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);
: m ^5 P# D. k* A$ A6 W. A - g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry); @; Q1 R4 y, ~* L. P2 d( O
- g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);* C8 r2 h: J7 o: y
-
3 Y8 e& a' y4 ` - 1 c1 `% H2 t6 {" D( K( u
- gtk_widget_show_all(window);
. s* s6 @! {9 j( [1 I - ( h9 d8 ]8 V+ F4 c7 a
- //主事件循环
( `$ @3 F j. n) ~0 d6 }$ F: ?3 q - gtk_main();
) j' R: o$ w) R K' J7 A v - ; V: X: T' M7 ]" L3 ]- ?9 W
- return 0;
2 |! y8 h2 Z K) [3 P+ e/ p# L2 {4 @ - }
复制代码 以上程序,编译运行后,就可以有以下得效果。 7 _3 b% o: E1 v- J/ ]1 v, H& i
+ a* i7 E- ?# u1 j- g$ v3 S' W 操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。, O; [7 g% T- ^7 h" ~, F3 F [' y7 z
搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。6 s9 Y& @+ j, W) F/ X+ @
7 U4 N' @; ^, l) U2 _, H |
官方板子不错,这么快就上手了。我的是odydess资料太少了。正在学习