上次已经开启了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/,,这个路径就可以,直接继续安装。* r# L9 @ L7 D% G' v8 y* Q
/ h' g9 K1 t4 v; @ 然后就学着官方文档的样子去验证下SDK是否安装成功
& a2 y2 O0 I1 K; y; p8 W# x
. ]) X0 y& O$ b1 @$ |) s
以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。 首先拷贝官方给的demo程序,基于GTK得hello world。 - #include <gtk/gtk.h>$ J, R7 W5 W; d& `* U2 n
! _" X3 p$ A m+ l7 H+ \; W- static void8 S* F6 b8 ]$ y3 U0 k) [
- print_hello (GtkWidget *widget,
6 L( ^. g- \2 m - gpointer data). H; \$ K k% A% j- _3 |' q
- {
% V0 e2 P0 O! [1 A5 e# h$ w6 ~ - g_print ("Hello World\n");
W4 _! E0 u2 P; i \" `7 z3 f8 E% I - }
' ?& z7 ~% j5 L2 E - 0 k4 w) q0 a5 i8 N' a# l
- static void
/ I0 I6 Z. N( K3 _, c$ X& p3 B - activate (GtkApplication *app, V2 ^3 m2 t3 p2 |
- gpointer user_data)
" ?8 A+ T: `1 j/ _3 A8 y - {4 O( ]6 X3 y. a) K& X/ ]
- GtkWidget *window;
( w# m7 @6 @) `4 m, ?: L - GtkWidget *button;
( \0 X E5 l ?1 V( R - GtkWidget *button_box;
; K7 u. Z) L1 w$ x$ i' t5 n; p$ m
7 `% q. G- e. d8 d' g- window = gtk_application_window_new (app);1 C# G+ V) {: m) `6 `
- gtk_window_set_title (GTK_WINDOW (window), "Window");. R- F$ R. O9 ]( H
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);' d1 Q4 m* p) r; C4 J/ M$ c
- # }3 W: {% N" i H
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
3 u1 P. }! W6 t6 z! ?$ k' r - gtk_container_add (GTK_CONTAINER (window), button_box);
. @% z u2 w: U' ~' U4 [3 M2 e/ u
; o- q" h2 E) a& [5 P- button = gtk_button_new_with_label ("Hello World");" S/ i8 b. ~! J' k4 W! f. `
- g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
" }& S7 Y/ z' N( s/ y. w - g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);( L3 D ]2 D/ G2 r. G- p' T; M
- gtk_container_add (GTK_CONTAINER (button_box), button);. G7 j. S+ i2 r6 [
3 y, o2 L; N" `7 C- gtk_widget_show_all (window);
" ~4 h7 y, E* U8 e" \1 I5 z1 q p8 V - }
7 p0 I# f: k1 }
# L: Q# j2 P: G3 p- int* _6 K/ {" p; X% N( w( ?0 O9 A2 k
- main (int argc,+ c. j6 \ a* j! X6 E' O
- char **argv)1 Y9 j- R5 Z; D1 Y! ]
- {
5 O% u2 g1 S9 ~. m2 U - GtkApplication *app;5 j) \7 P- t6 a+ K# i
- int status;
# u# w6 G. Z E5 l% G7 b$ O. Q - ( u: E& Z9 l5 c% A( R0 n" r. }
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);( z/ t$ l- Y3 P7 ]3 u
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);% _/ |8 {3 ^( q2 g1 D8 j
- status = g_application_run (G_APPLICATION (app), argc, argv);: X& n- t6 M9 @: S( l# \5 E
- g_object_unref (app);/ {6 }" R. u- L5 g& ]1 S
# A/ Z" ?9 j0 |! R( B$ h; ^- return status;8 S$ S; a A. o' w. ^
- }
' K0 s2 ?3 h X3 I
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 7 }) L# B( o# j+ v {/ P# u
- PROG = gtk_hello_world
: `' a/ M9 F5 d) Q# m4 z ] - SRCS = gtk_hello_world.c
; A+ h/ _ y$ ?- s( \( s
1 I- Z- b/ l! i. }0 {! a- CLEANFILES = $(PROG)' z [( g8 B, \! U
- L2 x" x9 e2 u' H- # Add / change option in CFLAGS and LDFLAGS
3 J. \( @( m6 f2 K - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
& }/ v8 V6 E$ G7 c3 v! W: C5 P - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)6 _$ D x! p5 C" L6 q7 {0 {* m
- 2 `& |% x: w- j9 ?6 C4 h$ D
- all: $(PROG)6 q. e8 v; o/ ]( I0 L
- ) v: v# m( g! b& c1 `
- $(PROG): $(SRCS)7 b" [) @; k. U- d1 C: I: a
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
" i) \0 r) A& d0 Q9 g - # m: l" L) u/ [( R9 v8 g) p; p3 t `
- clean:1 R) f; j+ P% u
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))! y$ O/ f/ @3 V( ^# a, h
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
7 @2 K0 @! f: t b! v; U
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。
+ M2 W4 C. ~: D& _0 [3 S) ~6 N$ h% X1 [% d4 \
/ |* R0 z9 p. m0 {2 g
- #include <gtk/gtk.h> G5 p( D: y/ j; e( k& V
- #include <stdio.h>
0 o4 C& D9 I2 [( D - #include <string.h>
% Y1 q- N$ N) T9 }3 H7 m0 r1 \7 d
! ]0 O3 f9 ?) Z! w V0 A- char buf[50] = "";
% n" V; ^) b* y+ D7 W# L
, o+ }8 U' j, X- } W# w- void calc(GtkButton *button, gpointer data), y. k0 X' p) j+ o1 c/ A' x
- {% u. G9 L3 _' _# `
- const char *text = gtk_button_get_label(button);
, i% t$ i% I2 U( o* V$ V, { - 2 v! T, A* w2 A$ K( u" F
- //退个操作
- Z$ j' g4 j' b+ \' Z - if (0 == strcmp(text, "c"))& {0 i% m1 i" f
- {
! M6 t. Z) l: t. [+ Q - buf[strlen(buf) - 1] = 0;
8 h& _: i9 Q, @, ^8 a - }else{
. {% N3 ~; a/ t$ X - 1 P, F6 Y- `( a
- int a = 0, b = 0;) A! N' g. n; M
- char c;' Y5 C9 r" Q) ~) Q- a0 |) u2 Q
- strcat(buf,text);
( j8 _% y" \$ k& |3 r' Z; n* t( ]9 n
( V7 @8 i/ g+ @) _; \! o' Y% t/ z- if (0 == strcmp("=", text)) {
/ B' f# E- u- u4 j3 H6 a% g - 7 K) m2 S1 V; J# j3 H8 ?: k% }
- sscanf(buf, "%d%c%d", &a, &c, &b);+ ]6 N+ r5 z# n
- 5 r0 v6 k! w4 d
- if ('+' == c) {
6 t3 P7 F( \' }( s - sprintf(buf,"%d", a+b);# @- y. y- {& J
- }
5 x. e; a6 \5 ?4 G - else if ('-' == c) {
Z* W8 _2 D1 w" U1 M - sprintf(buf, "%d", a-b);
% N: S, K6 i- z! ~5 P - }
1 I+ d& u* A% X" s- I - else if ('*' == c) {# B. R9 q! W# k0 A/ I5 @
- sprintf(buf, "%d", a*b);6 k& j% {- R) [' o& j; I+ C& M
- }
7 D0 L8 `; b% T( I" ]/ a/ w - else if ('/' == c) {/ L. P) h- Y/ K$ A
- sprintf(buf, "%d", a/b);
! Z6 k# I* E/ m6 U- c# N0 S( N# c - }
2 A0 ?0 ?: q, O# d G
1 A. U5 C" E7 P3 g' f" i# g. x+ q- B- }3 W4 y5 C( L) R" N& i& @; B
- }
/ V. y- Q, o ~& r9 w3 q- Y2 i( h- n - 2 Q5 K+ ~: f8 p: G1 @8 R
- gtk_entry_set_text(GTK_ENTRY(data), buf);
' Y$ F9 N6 {5 y% K$ W$ z- v3 W
5 P. e8 y: ]# g/ r- return;
0 o+ Z/ p! d2 ~9 v - }( P. S. Q- \! O0 j9 Y3 |& G( L
- . F2 Y: |" P4 ^
- int main(int argc,char *argv[])
1 i8 K `" o7 i7 H, q/ [0 n" ` - {( V0 Q% P3 @/ U4 ?1 d
- . M% y1 |* `4 S E
- gtk_init(&argc, &argv);" @4 a3 J0 q. y5 n
- ; f4 q" @, z l6 Y9 T3 x
- : z" j- X/ ?: K5 v) Q
- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- W3 e; X) X, R8 k! C' u0 y0 _% | - gtk_window_set_title (GTK_WINDOW (window), "calc");
( R; D+ ?$ ^2 w4 S
3 X+ |3 {/ ? K" j0 E- //创建一个表格容器5行4列, @7 v* }, _" m
- GtkWidget *table = gtk_table_new(5,4,TRUE);* s9 N$ i+ q9 D& l& I" Z
- - `7 p. u* [4 D$ V/ J/ _
- gtk_container_add(GTK_CONTAINER(window), table);
1 C L$ i# ?" y3 t: G5 n% p' n4 A B
8 C; j$ p3 B5 x7 T, w- //创建一个行编辑
. [8 e# _1 X6 b7 a. T - GtkWidget *entry = gtk_entry_new();0 V* z/ a' {: W D& i2 U" g
_" k N N, P# b) W7 c- gtk_entry_set_text(GTK_ENTRY(entry), "0");
: X' p# k" B" g& h, U - 5 v) W. S9 o, Y# q# e6 `3 ?: X
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);- h6 W* C+ M% W8 n3 K
- }8 Z# @1 h, {; r1 F- //创建多个按钮3 D; }5 o1 C1 z8 A! W
- GtkWidget *button0 = gtk_button_new_with_label("0");
( O7 F/ E7 f1 d w: v - GtkWidget *button1 = gtk_button_new_with_label("1");* T% A7 `7 j% O, w6 r& J3 L, i
- GtkWidget *button2 = gtk_button_new_with_label("2");
: Y9 X9 A( A( K" L/ z/ c - GtkWidget *button3 = gtk_button_new_with_label("3");
* x" S7 k$ f- [% e& k/ L - GtkWidget *button4 = gtk_button_new_with_label("4");/ D: N- v! }7 q
- GtkWidget *button5 = gtk_button_new_with_label("5");
. O( m8 n/ ~& f7 A+ L$ { - GtkWidget *button6 = gtk_button_new_with_label("6");
) v3 Q5 J7 I* ~: v1 A5 \ - GtkWidget *button7 = gtk_button_new_with_label("7");6 ^ d7 V' x: |+ A
- GtkWidget *button8 = gtk_button_new_with_label("8");& u) l0 h! q6 d
- GtkWidget *button9 = gtk_button_new_with_label("9");7 s6 `& ~% S2 { t
/ F2 P6 S+ n9 ~8 u5 ] L0 q/ ~- GtkWidget *button_add = gtk_button_new_with_label("+");
, b( y. d% B- D8 ?: C - GtkWidget *button_minus = gtk_button_new_with_label("-");
0 Q9 q; \( s5 J# M! g# X - GtkWidget *button_mul = gtk_button_new_with_label("*");
6 v: y+ l' R, a$ p# W. k: I - GtkWidget *button_div = gtk_button_new_with_label("/");
" m, Z4 t5 T s4 n) n6 w - GtkWidget *button_equal = gtk_button_new_with_label("=");
2 k7 ~9 L; o- T, g+ \& J - GtkWidget *button_delete = gtk_button_new_with_label("c");
+ {) G: }; Q+ t - " v5 q" b% K# H8 I2 e7 {
- Z4 p2 ~1 C6 o& ~4 o- ~+ X- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);+ } N6 l, ^, G; F7 L0 i
- 8 X% S3 Y, N, L. f1 i6 x0 N) c
- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);! Z; Y! n9 t; O' }$ ?
- gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
2 J$ A& p! `, p1 E - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);% Z: \4 A3 i- l* L) }0 j7 e
- gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
! \1 p: W1 m5 B+ m - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
% h1 b) H% I! E& t - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
/ l6 z i D1 K" x. a - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);& A2 B$ D4 j5 i$ `5 \5 l6 S+ m6 \
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);& _! Y$ M% H; M# ~0 g
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
. C2 N" B. X# R+ C - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);$ d1 F* A/ S) w& K
: |8 k$ t- T; V' \! L/ R0 V- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
, O& [7 t1 ^3 J% A7 L - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);
( j( W6 D% Y8 W! W4 b& j9 \ - gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);: t2 T3 e; O1 e, A5 [! S
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
- x) w% G- n+ I4 a" Q6 { - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
0 q( H" W& h: g" w/ s. Q - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);. ~1 l. n- T6 W/ I" F8 W0 O
* g# Q6 h% j' {0 M- //注册信号函数,calc()
+ F m# }+ i. r# O& W8 p# I - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);
3 d0 l( ~+ N( C/ u: S4 D5 P' J: Q - g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);
! h! F. Z' Q. }5 N- |/ Q - g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);
2 I* H3 t; d3 K' d; I6 [ s - g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);5 Q$ n7 I: E- p9 n( D; p) `
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);
8 K6 {; b% K- F5 ?, M - g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);
; B/ P. m. ^$ |' G! |) ?3 n! ~- n - g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);
0 H; g0 k3 j3 ?2 F$ ]' Q2 |# p - g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
+ `. K) J3 W M$ k$ `( } - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
! T. d- h: |; b( G, A0 a; f" @ - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
2 `$ o, W$ l: c, h - 2 [+ R% n- D; |" H' V/ t
- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
) p- z" [/ B, t: T# L2 { - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
& r6 L, Y- i1 Y% ^. y# T - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);, g( V( g# p7 u3 d6 t9 Y Z) f) @. `7 v
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);; T- f. t* K7 g
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
. Z/ ^ o6 }, Z4 ~5 J6 b - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);
: I9 V. m% q7 K; X4 @
" G* N1 H* Y, E; k4 j: Y* y, M, M, ]/ ^- ' d& a ^9 K+ Q
- gtk_widget_show_all(window);$ @$ ^' a6 |2 G% F. }& r9 G# |
" I1 q) i: H+ u# ^) v- //主事件循环$ A; R3 i: z: E
- gtk_main();
* R9 J/ B. r9 M9 z) e, u; w - : Y) f" o- f6 `1 E# t- f
- return 0;
( d7 g. S6 m& J R5 V. c - }
. t1 @% N _3 a1 Z* w
复制代码 以上程序,编译运行后,就可以有以下得效果
* y% \( R5 n: w
2 q+ a' l3 s3 n$ ^ 操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。 |