上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。
$ Y7 w! A3 Z* T, o 基于Ubuntu18系统,补充安装所需要的库和小工具
/ n2 {; Z% F5 F8 _, t+ ~$ B 更新软件列表 安装python3
" Q n Q/ s* [- G; P7 G6 N# P- 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
8 w Y2 T/ @% H! n' z; \ 我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。. n: L8 U3 `3 t* S* G
- Z7 U' t8 Y$ z0 N3 R3 C 然后就学着官方文档的样子去验证下SDK是否安装成功。! D* ~" j9 u0 ~, F; |
& r3 ~) z" w9 p
以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。
3 i7 }- I- h0 R" ^9 ~ 首先拷贝官方给的demo程序,基于GTK得hello world。 a. D- o+ x1 v4 d4 y
' }; d/ I" o% {3 o
- #include <gtk/gtk.h>$ c$ m& {3 F+ e F1 V* A
; y5 I; G2 J5 Q3 \: g- static void% x2 [" \5 L- R {1 b) i% |0 T3 u
- print_hello (GtkWidget *widget,
2 a/ k( |4 l8 F$ w2 d q - gpointer data)
$ Z/ x8 _6 N) j2 u5 f. e, q - {$ r/ N# x! d; k: Y t
- g_print ("Hello World\n");4 g1 Y9 B8 E o/ g
- }9 t; J9 h: f' X* {4 t. F
7 G0 w( ]' L, h( J" i- static void6 P% i# g; ]/ t
- activate (GtkApplication *app,
! F, l1 n% S$ p - gpointer user_data)8 e) t9 v0 x" e7 k! J V0 w. ]/ F
- {- ]- n+ _: D: ?% N3 u: e+ L1 z% `# Y
- GtkWidget *window;/ ]3 _/ O3 }1 y7 o) t: C
- GtkWidget *button;
# s. S' f) X1 m h1 V# g - GtkWidget *button_box;
* Z; B' `% a/ i* r. j
7 t* J! H3 O+ I5 N: L- window = gtk_application_window_new (app);
; T3 S5 y3 M4 R5 ~) G. B6 P4 U - gtk_window_set_title (GTK_WINDOW (window), "Window");+ S Z0 \& H4 n0 D
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
. t7 g& w& x, z6 p/ f- v - : }* m9 D+ l4 s3 N* J
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); I; N) V$ ^+ ~! A
- gtk_container_add (GTK_CONTAINER (window), button_box);- |$ g& `9 z) ~
7 ^6 t8 |- X; a# {4 E5 \6 @- button = gtk_button_new_with_label ("Hello World");
3 S7 o# ?$ l5 D1 ?5 U2 }( o - g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
+ J1 u5 c0 V" u9 {& K - g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);: q0 B' u8 O9 a/ _2 t
- gtk_container_add (GTK_CONTAINER (button_box), button);4 u2 C u4 u& }* E
/ g s. }5 z& H2 ^/ e( s* Y- gtk_widget_show_all (window);
7 z- V6 }7 J4 O) r8 } - }
0 @4 T. }; ]0 D4 l1 n
1 r0 y0 L' ?6 F0 O! ~3 Q- int
" w0 r# w) A0 r: M - main (int argc, x0 `2 N8 U( K; i1 m, R' B8 U5 }
- char **argv)
! ~9 ~* L& k0 G" ` - {- ?% w% a& c; m9 t
- GtkApplication *app;
, ]/ J# S$ ]$ ?; I - int status;
3 Z" r) H5 u7 A( Y; _& _
2 M! Z* v% F3 o+ F! T( R- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
& H- C# }' m+ C# Z4 T' c - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
8 }$ I$ N& s0 U. q9 C3 P - status = g_application_run (G_APPLICATION (app), argc, argv);
q) g8 h; X0 Z( \! e/ F - g_object_unref (app);( u# q0 @* W9 n( g* S5 f7 C i
- . E' F/ g$ V, t9 h/ G
- return status;! L" X7 \) o0 g- a" y" A8 f
- }
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 - PROG = gtk_hello_world* `% i3 G) j% l( a4 q
- SRCS = gtk_hello_world.c
! W$ w5 k4 t4 r5 e
! w# e( H" A8 f! L& v9 O- CLEANFILES = $(PROG)
' j6 Z7 g5 {. t
6 \% Y8 a$ q7 m4 K6 s/ s- # Add / change option in CFLAGS and LDFLAGS7 z% L; J) H" C3 [0 ]3 I
- CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
$ F$ r" S/ {3 n# y! @ - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)
5 ~3 K) P, Y( D6 l! W0 c7 G - % z5 G% j( {& a* y1 q6 i6 u
- all: $(PROG)
/ c) X+ _0 g- w2 \& q2 L) [
; R& {8 A. ^5 G' M/ d- $(PROG): $(SRCS)
0 x2 W# @5 \; r8 M" @6 L# Y) Q - $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
# K. |4 G' G$ m! ^0 t+ P - ! k5 G' k4 e4 O& r( l* ]3 u4 f
- clean:0 ^" Y1 {) ~$ n% H' z5 E5 j0 s
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
' Z! `9 ^& _/ C; h ~ S
5 P. i, E. q* Q) r4 a# o
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。% \( m+ b% m# k' s2 {2 y5 b
) i' L0 N- S' \" ~
- #include <gtk/gtk.h>
& a& i8 T) c/ ]) a$ t - #include <stdio.h>
6 S! ~4 a% j- @9 \% i- f - #include <string.h>
, r- {$ x3 A! Q# m; o( T0 N1 Z3 X -
1 Y" u. |- P3 S' @9 h/ g1 m - char buf[50] = "";
6 [8 n! Z/ q2 C' ^ -
( v8 t y/ ^ d+ ? - void calc(GtkButton *button, gpointer data)) \; i' A5 c; ?2 y# O. O& y
- {. j; K, h/ e) P5 }
- const char *text = gtk_button_get_label(button);
- _5 E$ `. v8 b) {4 B - 1 S# D0 I) S8 L; Y0 B7 ]1 b2 i
- //退个操作
* |( d( s7 R9 T3 E - if (0 == strcmp(text, "c")) - ?2 f- ^$ |6 @8 o# i* c G* s5 A
- {7 a( E5 T, @2 H8 o) I
- buf[strlen(buf) - 1] = 0;
: O; N; c9 m: q- W1 U( D, d - }else{
5 t. r E* Z/ @! U% S' |5 S - 9 d: u* j8 M9 [1 F# V& e) i3 f
- int a = 0, b = 0;; J2 @6 ?# a, u. W5 k7 F
- char c;
1 ]1 K9 X4 P6 r$ W8 `7 E - strcat(buf,text);% _7 C( p2 Y0 [: `& m5 h/ G5 B
- / M" {1 R1 s& F# k+ `& v/ W% q
- if (0 == strcmp("=", text)) {8 F! ~2 `# Z1 s9 y7 T3 H0 s
-
2 I2 P) B+ o- e, f: r) [% ^ - sscanf(buf, "%d%c%d", &a, &c, &b);
1 d/ C+ g* e% G( X* o - / j; {' H5 f6 S$ ]' I P
- if ('+' == c) {
9 {( K/ q1 N/ O: r$ f+ Z, G - sprintf(buf,"%d", a+b); w0 g0 U6 g+ U6 a
- }) n, I/ D5 k# J- y( N
- else if ('-' == c) {
5 f; h" [1 }" l! }* P7 p, x! W3 o - sprintf(buf, "%d", a-b);
5 e3 o2 _% D, S u, T - }& s5 O3 b0 M6 q _+ r
- else if ('*' == c) {. k! ]5 n, e) T9 k# H$ z1 t% ~4 R
- sprintf(buf, "%d", a*b);
( V E9 j4 C4 T0 G( Z4 p( r - }
& l7 a% _: e/ N* s - else if ('/' == c) {% m8 o5 Z% Z7 ]4 h- f/ U+ E1 p
- sprintf(buf, "%d", a/b);' j8 r* _# @1 ~( I
- }# s& W' W/ [( `( w9 z1 ]; U K
- 2 | O, q% b5 N# H& `7 A+ r+ t
- }
7 i. k% e, i: m% L9 ` - }; X0 k/ M& E. W9 y2 Q* Q4 b* F
- ( K' w) b2 @; I
- gtk_entry_set_text(GTK_ENTRY(data), buf);1 Q! P t; X( h# `7 ~4 r
-
% ]4 j/ k6 N0 w3 x - return;
) }2 ?9 q' O5 @4 Q( E$ E" U - }
( k4 O; L7 H) e$ l& b. L0 O# W - + {+ U0 B7 L) [' f( g2 Q& Y* u
- int main(int argc,char *argv[])
' H3 h4 s% K S - {
6 U7 i3 Y5 J# a
# p9 a- [/ F) w# L2 D6 x0 D' K- gtk_init(&argc, &argv);8 ]; y1 S$ K' g+ ?1 Q" a7 {
-
2 H4 k) h' \: e2 ]8 T+ p+ i
! C/ D! R6 r- P6 O- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
4 }+ u1 u! z" |9 I' Z* l7 ^ - gtk_window_set_title (GTK_WINDOW (window), "calc");
$ F. q3 ~/ r# ^0 Y0 V" r) |2 d - o5 i' M8 e9 f5 H
- //创建一个表格容器5行4列: z- C- V* Z( h. K& e) a
- GtkWidget *table = gtk_table_new(5,4,TRUE);: K8 P4 D4 u0 X" I. @/ z1 n
- ; d' f3 j6 e/ K# x3 m" O
- gtk_container_add(GTK_CONTAINER(window), table);7 L3 F* m; P5 f& T$ e
- ) j' P4 m- K- K0 G. W& o! v+ j
- //创建一个行编辑
& ]! j1 G4 m; s7 ^1 X8 u - GtkWidget *entry = gtk_entry_new();3 h% q( m+ _( C. x/ W7 s! e. ~; f5 }
-
5 L( ^, K k; j$ g; q - gtk_entry_set_text(GTK_ENTRY(entry), "0");
8 k% Q' F D1 d8 S2 Q) i+ S3 V - # I: h g3 {' {+ B
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
5 h. R: ]- J) C6 M - 3 x( I9 X2 P8 E0 ?. G
- //创建多个按钮
; f1 C# W; X7 u! Z - GtkWidget *button0 = gtk_button_new_with_label("0");
; J! P k5 N' @, ?2 X& a - GtkWidget *button1 = gtk_button_new_with_label("1");- f0 A0 t# g* l1 D% |4 [4 L
- GtkWidget *button2 = gtk_button_new_with_label("2");
8 r4 a4 w9 @% T2 F - GtkWidget *button3 = gtk_button_new_with_label("3");
, f2 ]2 b0 w8 @% D - GtkWidget *button4 = gtk_button_new_with_label("4");
- a2 K, C! M# _4 `# W j1 a - GtkWidget *button5 = gtk_button_new_with_label("5");( E2 ^- J! P5 V; [2 c
- GtkWidget *button6 = gtk_button_new_with_label("6");
9 R# o) u4 f7 X B1 Y1 O, m/ F. o - GtkWidget *button7 = gtk_button_new_with_label("7");6 i1 r9 g/ N, g" K: e9 o
- GtkWidget *button8 = gtk_button_new_with_label("8");
( O) h& q) n M# q# d8 q9 ] - GtkWidget *button9 = gtk_button_new_with_label("9");
* Y4 b; ]# {, C& D* O& N - " M4 k H$ @" i! E5 G+ o6 G J2 S- u
- GtkWidget *button_add = gtk_button_new_with_label("+");
$ ^: P+ l; S: _$ ~+ C - GtkWidget *button_minus = gtk_button_new_with_label("-");# N. d9 t2 f0 b- G/ n
- GtkWidget *button_mul = gtk_button_new_with_label("*");) F& b4 K9 S% }4 o& b' e) r
- GtkWidget *button_div = gtk_button_new_with_label("/");; e- }+ F, S L9 a8 f& q4 Q, C
- GtkWidget *button_equal = gtk_button_new_with_label("=");
/ q9 r: d- U; G+ T& D. \/ k6 I - GtkWidget *button_delete = gtk_button_new_with_label("c");
. Y7 d% i3 z$ z# r3 y -
8 G% f/ ~ `: E0 O9 ]* U - % r1 X( l- C& _& _, n
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);7 z% ?% F7 c+ O6 K. Q
-
5 w/ W: f9 q5 o* n - gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
O* X9 o( F* r/ v y - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
. T, E2 J$ w! o. U - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
- y# w6 G5 \3 g8 v- k - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
7 L1 H5 ?0 X3 {, K) V4 c |* c - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
4 x7 C- T8 X( E. i7 [( P - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);$ n+ P" t) [4 n/ J/ J) J4 E
- gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);
1 a6 N3 {+ T8 Y9 ^) i - gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);! }9 y( o" |- K8 K0 a
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);" t9 c! p9 V0 H+ t& w6 \* {5 F* Z
- gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);- D$ [1 m8 z, u- [1 F1 B
-
2 o1 H0 X% U4 i7 `+ p - gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
5 D5 L+ T. ~( a4 W, @; E# R) `1 C - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);# o) {' H k7 k
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);
% A& g9 K; r) K) d% g" S - gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);; \$ S5 O/ z1 G6 }7 G
- gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);0 h6 W, s X. x' i
- gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);
" V' v; I: b1 W$ `! p -
8 P* x0 O+ J- h - //注册信号函数,calc()
3 J# I8 r" K' K2 v& ^2 n - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);" y7 m; \: w! S0 H! N/ q4 q
- g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);
4 F' A/ d A7 w2 \3 y, ` - g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);2 r5 N( k& u5 d. f
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);* E, X7 B8 h" y& s) D6 z+ s6 x
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);
* X: v9 K0 E7 E* D; S) t - g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);) J9 ?) ?. v$ D% X( B
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);+ c4 h& o6 b2 [) }" V& ]( \
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);0 d3 g; f! g4 ?4 ^
- g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
3 w9 Q6 X+ J; i/ q/ Z% V- q - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
) {" S2 j" p6 o% J$ _ -
" L' I W* S+ u0 P - g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);* N8 i/ G2 l0 {2 @/ ?
- g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);8 h" V! d. z# k
- g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);0 }2 U' ^) _; z8 D' a: W
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);
! ?0 K# Y' C% i) ]; b; o - g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);- Y% g+ j$ P' x' v8 t! @5 m
- g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);. N9 `% T6 `9 C0 R- ~/ R- ~
-
6 I2 |4 P( Z" G/ X! O - # y% O; T- v5 I0 f5 H& o- `
- gtk_widget_show_all(window);# u- v5 C3 V# A' d9 Q v3 u. r3 c
-
* f. o, r8 s/ k! u- d: b' H- t2 ~# X - //主事件循环& G4 N0 A& o$ T. ^) z1 h" o
- gtk_main();
9 Y- @2 G* V3 I6 J0 X" I; ^9 j - 8 O& n/ ] i- c0 C. G
- return 0;: ~" w& T- S& [& e/ r5 q
- }
复制代码 以上程序,编译运行后,就可以有以下得效果。 6 P2 {- ^9 w X2 P8 @/ o6 Z9 f
2 Q" S! O3 e3 I4 A' I, b- W: m
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。
& O1 @5 h" ]) }1 D V# v7 v 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。: v' B- m! I& n
' ^9 }6 E5 W% i7 I8 ?+ q) q |
官方板子不错,这么快就上手了。我的是odydess资料太少了。正在学习