上次已经开启了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/,,这个路径就可以,直接继续安装。- O9 E) p! I( c6 c
1 F1 ~# a7 l- G" R! n3 Q/ G 然后就学着官方文档的样子去验证下SDK是否安装成功
9 {! [" b7 a! `8 L4 J% s
) w3 F1 z4 e8 W( Z; S# h
以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。 首先拷贝官方给的demo程序,基于GTK得hello world。 - #include <gtk/gtk.h>$ k5 w. m8 p, K" D# K( |7 e
- / P1 t8 U" S& v: t7 @3 e
- static void" J9 [4 V7 E: p% {2 ?1 j
- print_hello (GtkWidget *widget,
+ ^& r6 D; Q* n1 V9 R! f3 h% n$ @ - gpointer data)
/ [0 J! b' c9 W& W( w# j/ e% G: [3 v - {
" O. J- q$ o% o& k4 Z- R/ n3 F - g_print ("Hello World\n");
% E: T. B7 A$ c1 K: D - }
2 Z, z2 L0 L# e
: ~, E% s$ N6 ]1 S3 Q' x- static void
" x7 h( I D6 F( h: p1 N, L - activate (GtkApplication *app,( H" e5 U3 Q, d1 R& K1 P8 H# }
- gpointer user_data)
0 w W& ~+ p6 S+ o- C - {
- q6 R( j. H) i& x3 T% c - GtkWidget *window;4 ]1 C' _5 G4 m$ x
- GtkWidget *button;
7 _: v- V. a( j, W( j- B; d - GtkWidget *button_box;
. u$ l+ o0 z; F# Z! ~( x6 s
; y1 Z F& k G1 k# z- window = gtk_application_window_new (app);4 O; Y( J" O1 Y" |$ }7 D1 D8 b; L
- gtk_window_set_title (GTK_WINDOW (window), "Window");
6 Q( i# ]9 z# G: Q) r - gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
. X3 }" l3 k# c5 u* k9 S6 m
* l9 H, D( C: G- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);1 g7 X7 n1 h9 y! m. x' t8 L; h# s
- gtk_container_add (GTK_CONTAINER (window), button_box);
! f& Y, t# w* t' F6 x6 T
2 D$ q4 g8 d& M4 d+ M. `$ A- button = gtk_button_new_with_label ("Hello World");
1 | i& g8 M$ T3 A, J6 a - g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
) p' b6 y" r& |( L+ z7 s: q7 i- { - g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);2 V9 h/ p# q$ T
- gtk_container_add (GTK_CONTAINER (button_box), button);; e2 W5 W; Y1 G1 M# Q
9 R0 e- \+ @( e; {- gtk_widget_show_all (window);- i# O5 [3 M6 o& Z# w7 T/ N: A! a
- }
. x; c! D( _+ w/ E
6 r0 T/ Y2 F9 F' g- int; v5 f3 W4 M9 ` g$ P0 F* g( F
- main (int argc,
+ @* I7 {8 N( a4 R3 ? - char **argv)
# r# i" ~1 n0 }) K! s( p - {! T% {- S+ K* [+ V1 B! q& N+ W
- GtkApplication *app;$ Z, t2 x) T6 K l' z2 I5 k
- int status;+ a3 L9 O0 J! F) A! n
- 5 A) A6 k* M5 X* u5 k4 l
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
7 M6 A5 i: @7 C$ Y. Y( Q7 r - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);! v+ _+ T7 g. |2 e* w2 ^* e
- status = g_application_run (G_APPLICATION (app), argc, argv);0 ^% t2 j6 p. i7 Q' o
- g_object_unref (app);
; O, ?+ m! K4 j, \
% Y5 _& N6 @" E' N- return status;" l- Y- L; O9 b2 R
- }; P5 t# Y) c9 T5 r- @, ?+ ], d
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。
+ Z/ q2 g! }. J$ _% }9 J' G! r c- PROG = gtk_hello_world/ N5 M U6 J, X S
- SRCS = gtk_hello_world.c( l. H6 q9 I) Y+ U
- C& z& n8 x% _/ p+ s# I- CLEANFILES = $(PROG)( b- R& H! B2 M$ r
! r( r" q. g7 |3 U; e# M- # Add / change option in CFLAGS and LDFLAGS
1 _: n, P% B- h - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
* Y0 M0 v& L& Z6 p }0 W3 t* f - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)
) k# x0 u" z! U( K5 o" Z
/ u' |, N& N/ j# O. w- all: $(PROG)4 F$ a5 C% k3 j! K$ R" v, A8 I
+ f* `1 w, k: ?9 D1 I) O- $(PROG): $(SRCS)% i8 P5 J$ w5 t2 ?
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)% Y' B7 j) Y0 T5 @/ e- O
2 M$ m8 n. y/ v0 D- clean:
6 h( T ^) i3 b0 u# ]3 O Q! n - rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))7 W1 u. q& G& i' V- n1 l; N7 d
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
5 I s2 z- Q( c9 a; d9 p 接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。+ _* M! ~3 t9 K
: \1 p# y* G0 M2 C9 v, O 3 E7 F3 k7 G5 v, }7 L
- #include <gtk/gtk.h># e! j& q& @% L1 l5 ~* H
- #include <stdio.h>4 L6 P, B* I8 L: h! K2 E7 o
- #include <string.h>
5 k5 l$ q. h( E" t# o - # ?7 |6 ~: f1 Z$ m/ a
- char buf[50] = "";& d; q1 h7 m3 n+ J: ~! p
% J! H8 x8 _+ K p4 |- Q- void calc(GtkButton *button, gpointer data)
- q4 b0 n F( A9 W( v - {
/ V( y* J+ i2 K' N% c. Q - const char *text = gtk_button_get_label(button);
/ h! ~4 k* ?, B5 b( h' ^
9 j, w" N' J3 J' F; b- //退个操作
0 J) {/ A/ n2 s7 Q, W; s& f2 Z - if (0 == strcmp(text, "c")) Z( x+ ^( b9 Z8 K* ?; e: L4 Z4 T: M
- {# @0 m" z( W5 q+ W+ m
- buf[strlen(buf) - 1] = 0;7 b5 ^5 s: d9 d
- }else{* f: v3 ]. Z7 h1 Q
7 v# }+ S5 E9 V8 a" J: o/ d- int a = 0, b = 0; d; X& n3 Y% A: n' f! W. q. T( E
- char c;- m0 a% k6 x2 x! P4 c0 ?" D' S) g& i
- strcat(buf,text);3 R6 |" H' J. n& m% |
7 e% o1 N) A% J" b- if (0 == strcmp("=", text)) {
9 K- `' t" K/ b - j/ o3 N5 }% Q* U
- sscanf(buf, "%d%c%d", &a, &c, &b);
0 [7 d+ o7 ?0 A9 B: Y
$ {; N) z: q' g" \- if ('+' == c) {
; j B, x3 ~# ^; U" R( k - sprintf(buf,"%d", a+b);
, e+ @7 c5 b, m' s0 V0 B6 c" f - }7 s. y, q. j( F6 I* |
- else if ('-' == c) {
0 w3 y2 I1 ^" M1 w+ U4 @2 O - sprintf(buf, "%d", a-b);; h7 o2 C f9 G& Z/ |, l
- }' z6 a9 d1 U9 T+ U
- else if ('*' == c) {
7 f& d& \- e, g - sprintf(buf, "%d", a*b);# f2 A3 |) q. c) M
- }
6 k" a( B& c$ K( h/ b - else if ('/' == c) {
& k% Y! h* W6 L, I+ T8 ~ - sprintf(buf, "%d", a/b);0 s6 k/ x6 U5 A, L) ?
- }
. O: u5 d! H8 k9 U- p7 l - c$ q7 T2 [, A0 M1 s& x2 n; w$ m
- }
# t2 Z1 H. Y" R - } l* \- n3 I, G, |( C
8 ^ k5 j& L! m. |+ Z7 K- gtk_entry_set_text(GTK_ENTRY(data), buf);) S& c8 e' a" ]. R' ?
% u' J) K0 i1 G' t- return;) d! u; @9 C* _8 A
- }
1 ^ d* K2 n. l3 C
- h( `/ V+ {' _7 |) [- int main(int argc,char *argv[])
1 u) s/ Y; s$ t8 _1 }$ [ - {3 F! q3 A2 g% y/ d5 V5 |- X
- ; e, Y j+ }( W
- gtk_init(&argc, &argv);; @: \6 s, b0 v" Q; M8 ^
- $ R/ F j- g& s, m1 r
* ]$ |2 I* T/ c3 C; K- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);$ U0 c- ~+ C8 c h" n8 j X
- gtk_window_set_title (GTK_WINDOW (window), "calc");8 P% _3 L# h$ F" m: n
- 4 l! w% C6 C$ h1 H' d
- //创建一个表格容器5行4列+ F' H, k5 c+ g7 o" z7 }1 k
- GtkWidget *table = gtk_table_new(5,4,TRUE);( i7 A6 X3 d, N, m
- 7 ]3 B) Z5 w- H# [
- gtk_container_add(GTK_CONTAINER(window), table);
% r' q L8 ?1 x4 j# H) H - * [- f# v9 m" B9 a3 ^! I4 G
- //创建一个行编辑
/ Z: H0 A. {$ N5 D3 g - GtkWidget *entry = gtk_entry_new();
w8 }! K2 r' ` v
# S: D1 t1 t2 r& B- gtk_entry_set_text(GTK_ENTRY(entry), "0");
. r% [! ?4 b) F9 @
8 H& |% X9 F+ p, U1 K( \" B- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
- G4 Q& J- ^! ?8 U6 _* N
$ h0 Q% G# }6 Z& N0 m- //创建多个按钮
1 K( ~$ i+ e8 P% o - GtkWidget *button0 = gtk_button_new_with_label("0");
2 K1 ?3 d; d: z' r- X - GtkWidget *button1 = gtk_button_new_with_label("1");8 c& u& V* W7 b" n2 i* D1 a; n( r" G
- GtkWidget *button2 = gtk_button_new_with_label("2");% R0 K5 M* r4 P( K$ r
- GtkWidget *button3 = gtk_button_new_with_label("3");. V2 D- r+ r3 ~( U
- GtkWidget *button4 = gtk_button_new_with_label("4");; D1 R8 q, i8 j4 I
- GtkWidget *button5 = gtk_button_new_with_label("5");
3 b- }( a: P* t - GtkWidget *button6 = gtk_button_new_with_label("6");4 X2 I0 H3 v! F1 K: N
- GtkWidget *button7 = gtk_button_new_with_label("7");
' i9 q7 }+ F. s$ N - GtkWidget *button8 = gtk_button_new_with_label("8");- b: [4 c+ O, n. J9 q7 [4 ^' d
- GtkWidget *button9 = gtk_button_new_with_label("9");9 M1 X8 H) \% X2 {
% i( J& v, H. x" @! P- GtkWidget *button_add = gtk_button_new_with_label("+");6 t3 Z8 `) V" K$ I# g
- GtkWidget *button_minus = gtk_button_new_with_label("-");( p+ C* _3 f( [" D- H; \) O! H9 C
- GtkWidget *button_mul = gtk_button_new_with_label("*");
3 o2 l V0 a; b5 \. L. n- h$ A - GtkWidget *button_div = gtk_button_new_with_label("/");
% b$ q) r& E+ U. S - GtkWidget *button_equal = gtk_button_new_with_label("=");; s" d" k1 L* Z! ~$ X
- GtkWidget *button_delete = gtk_button_new_with_label("c");0 [" ?, A* r. ^# Z
2 T/ t0 r4 V' r4 `, |- 5 l3 f& z0 T& a+ k
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);
h! `$ j' n3 d: a4 G8 F8 u+ h' S - 0 w8 X: g: Y, S+ g" n
- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
" D7 g% X' N9 Z" B* y3 t/ v - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);: Q$ R9 s" y% Z4 t
- gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
2 s5 M) }! e' ?7 i( Y* [% | - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);/ w- ~$ |, i8 }6 v9 ^! U9 n
- gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
. ~: J3 B* F6 O - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
2 r' R& {) ^ F& g - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);2 W# ], |( q( B5 g: h
- gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);, C j3 ?* |9 o
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
( A: J1 ^6 a5 K% p* e+ a9 D - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);( j/ }: a- O' k' d1 }$ c
9 g. h* V* v+ h- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
% a$ I# V: A6 f4 ?" x - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);
1 ]; h7 @! d- W) x D( R% B - gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);6 l7 ?- n' k4 q! W# A1 @, g: a
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);. c, }9 Q+ g- M$ v+ @
- gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);- H2 A+ n2 V9 M, `8 E
- gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);
0 X, ~# l6 z6 ~. }
; a; a0 e/ a# X A- //注册信号函数,calc()4 O3 F0 ~. n% x' ^. }6 B
- g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);/ t( o8 d) ~: [4 m9 X
- g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);. j$ o, C9 q7 w, _. \2 d5 p# P5 n
- g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);2 @# G+ n' A% O0 I: Y+ a$ |
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);% J& ~( ]! K- K
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);1 T$ e8 J) E$ h4 H. |' M
- g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);
3 k6 G5 a# ^7 x/ w4 C - g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);# H7 \- _0 x B- e o- l0 v& k
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
. v: m6 Y% W2 h' n2 u8 h3 K7 z8 H$ J - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
" {% Y$ I! a4 R9 g Q - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);: H+ r p5 \% Z* L W- M
- . d$ e# `' T, w, D4 H+ D; S
- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);$ Z1 A4 H3 Z1 }2 i
- g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);/ ?4 }) V6 Z8 n8 m* ]4 B
- g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);; o9 t( }3 |% Z) L
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);- v0 O0 f7 c! U* C
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);9 M1 K8 j! Q* }; D
- g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);, c7 E+ a* T, d5 X+ Q
8 d9 X# ~4 l1 z, u& Q7 e
% _& d! [8 K* [5 g2 g2 V$ |- gtk_widget_show_all(window);
+ j$ i/ Z$ G# X - d% K+ a" s$ v; Q& j1 _: i/ w
- //主事件循环" F6 x% S4 N' c% Z$ c
- gtk_main();
* j# E+ {$ G, s% R
: a7 }( I3 R7 m( B! i2 h. f- return 0;
3 u9 B' V% J0 L7 `+ u - }
8 n% B' S; Y! Z
复制代码 以上程序,编译运行后,就可以有以下得效果
. `- `" m; X& F3 l3 H |' I9 p; t- p9 a5 L! }. M) c- L
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。 |