上次已经开启了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/,,这个路径就可以,直接继续安装。
/ i( p6 ~7 i) D) t
0 a: a# Z& A& `3 B
然后就学着官方文档的样子去验证下SDK是否安装成功5 L, w, i9 f! U K/ E
2 T4 ?) R7 q1 t2 w 以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。 首先拷贝官方给的demo程序,基于GTK得hello world。 - #include <gtk/gtk.h>5 i+ h) B4 k( f
- ) S' y: L. P, N
- static void
e1 t1 M. Z$ }0 R0 m# Y2 D7 N - print_hello (GtkWidget *widget,8 M0 _3 K$ j8 L/ A3 F7 ^
- gpointer data)" ~! q1 a- [/ v& r2 X8 H* Z
- {3 C% h$ N: ]5 ^7 @* S
- g_print ("Hello World\n");
6 W% N9 J5 D l" _: Q1 @- m - }2 t9 X! D) R( s; B" Z
- 4 d/ q( D c' i$ r, q1 b
- static void
0 o& l" {2 }. X: z$ S4 R5 u( T: ~ - activate (GtkApplication *app,0 [1 J8 b' F# Z k0 I
- gpointer user_data)
& \3 a8 Z- |" E7 N9 n" i# h+ ?5 c6 l# t - {- |; @' N2 } D6 T9 A
- GtkWidget *window;
: c: t) `' s4 \7 y" M% l% u# z - GtkWidget *button;
1 u: q+ ]% p6 E' a+ B8 m - GtkWidget *button_box;
1 N" \8 u8 Y3 ]+ h' d
* o% E/ L8 K- D! I$ ]( k- window = gtk_application_window_new (app);
% D# a, e; m! Y/ z' l7 j ] - gtk_window_set_title (GTK_WINDOW (window), "Window");
! S8 L4 J1 s% {9 x2 P - gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);0 R: ^, e/ I* n9 a7 }
( C. [4 m6 C: |* v3 E* Q6 Z- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
! W) j/ }) o; r# c - gtk_container_add (GTK_CONTAINER (window), button_box);
+ k$ {% H3 j9 ~, ]' c. i; V - + B: }2 x! R+ k
- button = gtk_button_new_with_label ("Hello World");
3 i" K! h! h/ l( D, X4 \ - g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);, p4 k; Y& b) \ ?
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window); V0 |0 ]; }$ n J
- gtk_container_add (GTK_CONTAINER (button_box), button);
& {. {* s$ |6 N! W - 0 P& o5 m a6 \+ ~: o' @& V
- gtk_widget_show_all (window);* F: f6 Z% y+ }; t L/ ~* u1 c" b
- }; B" U0 ^' n9 v& C' P
- , [$ \- Q: _# V/ R" J0 o: i" L! W
- int# C4 R0 v2 k8 j m: I0 x. D/ [9 U J
- main (int argc,
/ A& b. Q' t; Z( t. X4 a& p3 ] - char **argv)7 d2 o" }7 ?" M- J: K( f
- {
3 n+ e( ^5 g2 c% w1 M9 c* A' c - GtkApplication *app;
4 |; H z% v+ T4 o' [4 t9 y! j0 ^ - int status;" ]3 Y* T) P( p( g& |
- ' ]" `9 S3 C2 r- J( G
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
$ h+ \0 H8 a2 H. Y% s% ]1 T - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);$ |8 Y% D$ | R+ Q
- status = g_application_run (G_APPLICATION (app), argc, argv);
+ l& H; x7 h" a8 H6 ^5 w9 u( F - g_object_unref (app);& E0 ]2 h. ^# r# g
- 6 D- K( q P2 K" r. t5 C8 B
- return status;2 J6 j+ T7 b: F
- }/ D1 @' l8 O5 x; O" i
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 3 W0 \) k& g. o( O
- PROG = gtk_hello_world* W3 T: d3 W, c; j' C8 m
- SRCS = gtk_hello_world.c* f" G2 K* }" T/ m( i! p2 t
; f6 V7 C5 p3 f; ^7 k6 p- CLEANFILES = $(PROG)
" G# @' M3 z' Y: d* O
6 C; L% _# q8 h% C( S- e. G7 ]- # Add / change option in CFLAGS and LDFLAGS
6 d9 }4 ?+ ~: _3 e - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)- v3 t/ k( ?0 l6 F! `$ R
- LDFLAGS += $(shell pkg-config --libs gtk+-3.0)
8 F: S, E/ F1 R
: ~1 w, O* S/ y4 O I1 @- all: $(PROG)5 `) G* Y6 z+ l- ~6 K
- 2 C2 a( J! x! ?' d! D t
- $(PROG): $(SRCS)5 G2 @. e! A+ n
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
2 c8 p8 U0 g# r: n$ V! d* ?
i# ~; Z. n! R8 c! y- clean:7 @0 h. Z5 P6 P8 \3 S4 e' N
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
7 L; W+ W4 Y2 `+ Y) ^
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
; O) A; X( l) c* ?5 F0 X
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。- }3 Y" m& C, o+ z
, c8 l. J8 \* @5 W. e5 |
' | ^7 o; J4 M2 l- #include <gtk/gtk.h>6 I5 z& {, ]4 h; t" y! ~5 z
- #include <stdio.h>
" U0 ] C* f% T8 g f+ w$ h - #include <string.h>, V6 M/ x& l1 c% @1 O% Y
- / N' g8 S/ ?( i: e
- char buf[50] = "";( U q; u8 b9 y% n1 E! i2 f
- ' M* B, q0 i8 u
- void calc(GtkButton *button, gpointer data)+ I* W; Z) B8 a% I
- {
' f) \3 q" ^2 ^( q4 p. G - const char *text = gtk_button_get_label(button);
7 G! U! L0 L' |( P2 L5 S: u - 4 z" u% f. D0 M4 n/ W {
- //退个操作
( Q0 d3 F p" N& T7 i/ L - if (0 == strcmp(text, "c"))
1 h" [3 _7 r! _' g - {' Q* E+ ^6 R3 Z% ^+ |) R7 {* [
- buf[strlen(buf) - 1] = 0;
; [5 r# |" B% s, [6 Y0 }& L h - }else{
4 K `8 I; f4 d4 R* ^# `
' S% V. f( M+ _6 ?( F- int a = 0, b = 0;( p' @+ w) K$ h! I7 Q/ i Z
- char c;" e. E- ]* j4 y! V
- strcat(buf,text);, V, G) M, `* _8 f" X! p/ @* a
- ) Q" ^! p, t9 A2 W' y& Y
- if (0 == strcmp("=", text)) {; H# f9 i; d5 k2 L) Y
% ?; T* T8 A5 q: I, F- [. `- sscanf(buf, "%d%c%d", &a, &c, &b); w* w8 Y; ?" S! G- @. m
- 7 o/ a" K; X% L. p, ?( K
- if ('+' == c) {) }* Y$ G9 V" q
- sprintf(buf,"%d", a+b);
?' i& L3 k$ D3 j/ C - }
1 j( X; X% t( V/ g8 z3 N - else if ('-' == c) {
T- }) _8 \6 p& c4 E" X - sprintf(buf, "%d", a-b);8 q. P5 r5 @+ {
- }
& W/ I3 s4 T* l - else if ('*' == c) {
' H7 J$ p1 q$ f2 ]8 p5 E - sprintf(buf, "%d", a*b);
. U7 G: h3 x) e5 Z, o - }9 _' s" _4 F( n% _& @
- else if ('/' == c) {
# H% J2 p8 \/ r6 U - sprintf(buf, "%d", a/b);: y# a8 g7 ~! f3 @, g3 u1 j: Z
- }
4 _1 ^; m+ }: c' b: ^- j! J7 m - 2 d: {6 N1 ^( K" Y+ P' @) M
- }8 {9 \; h( S' X% v5 \3 l
- }
8 F0 V3 B1 a7 n. s4 x# n3 p3 A8 S$ i - 3 }: g [# O" R8 Y V5 [
- gtk_entry_set_text(GTK_ENTRY(data), buf);
; ?( S5 T* }% n9 c. M4 [ - 4 S6 B. G2 l! R) U
- return;
$ T0 s/ j$ i2 W# s) U - }
! f/ U+ H3 ?. G; I
W0 s: z8 ?0 W# p3 P. u- int main(int argc,char *argv[])
) a0 H a6 w8 A& z: @& L9 | - {& A0 D: }9 G; U
7 w1 C4 j* O3 _, q1 e7 \- gtk_init(&argc, &argv);& b8 O3 k; _, \
+ `9 ~ n2 p: g1 J% r4 G- * A, R& Y2 y0 W7 a% g7 q# A L
- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);3 x' I3 n B5 S
- gtk_window_set_title (GTK_WINDOW (window), "calc");2 r4 o1 y, c1 q# m( |
9 }+ T1 f( h' w/ m; K- //创建一个表格容器5行4列
6 \* p( Z8 B0 w' r3 C - GtkWidget *table = gtk_table_new(5,4,TRUE);# v4 D% G$ ~( u: r
+ z9 H9 X# n0 u2 T$ `- gtk_container_add(GTK_CONTAINER(window), table);
" O! _9 j) v/ d8 ^ - # j, w0 f4 W! M- u+ ~+ J% ]
- //创建一个行编辑
& B! o2 g( {+ D( c - GtkWidget *entry = gtk_entry_new();' M0 G0 X! ~! n) ?
- " T6 g, f# g5 C2 i2 K
- gtk_entry_set_text(GTK_ENTRY(entry), "0");
' W/ b: m5 ^2 \ - - E% q! F1 }$ N
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
. O; E2 d# ~5 j7 q! \" J/ p
+ V9 N5 r8 N7 V8 d. w- //创建多个按钮
, Z- }+ `0 |4 u5 o4 \$ N- T - GtkWidget *button0 = gtk_button_new_with_label("0");% J! p+ y; @8 h* r `
- GtkWidget *button1 = gtk_button_new_with_label("1");* M3 r! w0 s' r7 N! c Q( _! ^: c
- GtkWidget *button2 = gtk_button_new_with_label("2");7 {! k1 w: P" }
- GtkWidget *button3 = gtk_button_new_with_label("3");; i" c% t1 l5 z1 a: ~
- GtkWidget *button4 = gtk_button_new_with_label("4");
) d3 _) C! N, h0 N# j, H - GtkWidget *button5 = gtk_button_new_with_label("5");3 [7 s. X) V+ j4 l2 n f
- GtkWidget *button6 = gtk_button_new_with_label("6");
5 S5 P9 B! ~7 `! @* J3 {# G - GtkWidget *button7 = gtk_button_new_with_label("7");6 ~$ m5 `3 c' H& j; O! R! X, ]$ y( k
- GtkWidget *button8 = gtk_button_new_with_label("8");7 p) s8 @# a2 k }' D
- GtkWidget *button9 = gtk_button_new_with_label("9");! H% ~2 n: W" M+ B* {
( ?4 h+ @4 U: E) A) j- a2 Y- GtkWidget *button_add = gtk_button_new_with_label("+");# ]- n) }' R. j' J2 b, A& i; B( `
- GtkWidget *button_minus = gtk_button_new_with_label("-");
7 L. |1 \5 a3 L - GtkWidget *button_mul = gtk_button_new_with_label("*");
$ s3 L, N" T' E0 r( I! k - GtkWidget *button_div = gtk_button_new_with_label("/");$ [- G0 j1 i' M! T" \' N' P4 ~
- GtkWidget *button_equal = gtk_button_new_with_label("=");
3 `0 G( D+ h* V, F. @ - GtkWidget *button_delete = gtk_button_new_with_label("c");
; D0 s* W' O4 P7 T7 o6 v3 D( N
# P& t. ^" s8 f
& T. ^* ` [$ }- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);. Q, H$ }4 z+ E- m2 Y7 l8 m8 e
- , q4 p, z5 m+ t0 j
- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
' D2 C5 S$ q2 w* u- }# M2 Y" S& ` - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
; W# \. u- m3 `" A8 e/ F! ] t5 L - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
6 {: a2 P6 Y- y4 n, O1 s+ V: R - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);; c0 f" Q4 N! L6 t
- gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);8 |; z& r5 v8 l p1 t3 i* B: z8 }9 i
- gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);' y- C# V5 \6 F. u! n
- gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);8 d- k& M; Y# i# G( p
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2); l- R4 a: b. W& z% u+ V- J
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);7 w6 g( o6 K7 y* x& z
- gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);
5 J) ?: X9 m( N/ b
, Q1 E9 U( R7 v0 c- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
2 S$ N" \5 Q3 L& W @ - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);6 K0 w i0 P/ Q( Y- [
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);, N. Y9 a p! Z' m* c4 G8 a( y
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
3 R* y+ L/ W6 v; o% d - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);" w6 R9 S g3 l( o) E4 m$ U5 `, {2 {
- gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);" Q2 c6 Z- k' M% J3 Z2 C
- - j' Q' H- k" ?5 c
- //注册信号函数,calc()
0 ~! A1 T! [# E$ M( J* J - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);; C3 d& \# [6 O- X& u) s
- g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);8 R( G" U {, [3 N' A: _% Q
- g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);' e5 U* W+ `) O, A( d. F% t
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);
1 k3 r6 s/ A* K/ ?; N - g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);
4 T0 D6 `+ { A - g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);7 z: i0 ]. {$ A+ w
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);
X" r. T4 g( z9 v7 m! q/ q - g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);# J! v1 H1 v( |( ?$ D) X- _* h; b
- g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
0 ^# ~9 y6 N6 Q7 ]8 A- w% f - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);2 K" A/ \. J: W. R
2 Q8 m! v; Y/ f) u0 q2 |5 U- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
" |/ @& F3 B8 V$ H6 K - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);' }& M' z" r* U6 {& _& ]
- g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);' f" V) p6 E! @1 S2 `) O4 A1 Q2 k, A
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);
+ W+ J O1 Y2 _+ ^ - g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
( S$ ]. Y1 t% q% L- r. S; l - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);" l- x7 e& X: p; j
- # b$ {( {4 q9 ]( N* |
- 8 |+ u2 O. j4 q2 H
- gtk_widget_show_all(window);
& C" @- t: x; G9 x( y2 W6 }
2 V" y/ \$ [1 B$ Z- //主事件循环
/ s8 y0 _* \, N0 U ` - gtk_main();
3 q- p' ?7 I1 O3 v, V7 }
o3 Y" o1 Q; l- return 0;2 M8 A0 t; q* b& Z8 V
- }
5 }# P( t/ `) ]" i2 w
复制代码 以上程序,编译运行后,就可以有以下得效果
0 X: w% o! M+ T8 L% ]
i. \' n* l/ ]% x' p" ] 操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。 |