上次已经开启了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/,,这个路径就可以,直接继续安装。# e3 T i) J7 Q$ y2 W% [
- [2 p$ v/ _0 C
然后就学着官方文档的样子去验证下SDK是否安装成功
( u/ Q0 {- d( g# M, m& R* R
! q0 x: D6 ]; Z, x
以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。 首先拷贝官方给的demo程序,基于GTK得hello world。 - #include <gtk/gtk.h>
% K, T F j% F
2 L3 x% Z4 J/ g1 M. X- static void
) D4 f' U- S6 [/ k - print_hello (GtkWidget *widget,! h9 S( b7 r& l! j% h- ]9 A
- gpointer data)
[5 D' n! G$ V$ ?5 s - {
! ~( ~0 B* R" @* Q$ q - g_print ("Hello World\n");4 Z, \. X6 j2 z- l0 O% v# v6 B. L
- }3 P0 e- \% p0 `4 i9 k- ^
4 O# I, ~( q# r1 Z- static void% f4 d8 N7 K# ^, P8 b
- activate (GtkApplication *app,
8 }; s. A+ h: x* h- | - gpointer user_data)5 V1 d9 @- `( | @4 s6 F6 S
- {1 O4 g1 D, _8 n e/ w2 X2 U G& z
- GtkWidget *window;) W7 v' @6 K/ y2 v6 [: C' y
- GtkWidget *button;
/ w6 W9 `: l' I. G& ~( p - GtkWidget *button_box;' `7 {1 |! @* u+ g
8 [( o6 y( `* t. f7 u- g- window = gtk_application_window_new (app);7 i3 P6 B; g8 y; \* x5 k0 Q
- gtk_window_set_title (GTK_WINDOW (window), "Window");
; Q$ |. V% l1 Y2 Q: V - gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);7 ]4 r7 u, O! G6 K H1 P9 @
- ) ~; Z2 o; H; e# o( [
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);; X) B3 O$ a) `( Q8 ?& ~: Q2 B
- gtk_container_add (GTK_CONTAINER (window), button_box);
9 U; @ s+ }# I! J
1 l7 u. @" @9 g- button = gtk_button_new_with_label ("Hello World");( u; G2 S' B% Z& ^; P
- g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);' m& r# I/ B! m# k$ y0 V3 ?8 k- t. S
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);2 f7 `& ~+ L# x, `8 W
- gtk_container_add (GTK_CONTAINER (button_box), button);
7 `7 w3 a, l9 A1 j) z/ y8 ~
3 g6 F' g- K3 k% f& I. p- gtk_widget_show_all (window);
( u( o% S; }9 r. h0 p1 }1 Q9 C - }/ I$ V. s2 ?. k6 x& K: h
- 4 s/ }$ B; p5 @% z
- int
+ J8 d2 y" U! B. A - main (int argc,. Y0 V5 O% u: V' d5 f: j* ~& G
- char **argv)
5 d l- c$ Q* S7 D& K8 [3 o - {' [/ Z+ [" V7 f/ w- r% @
- GtkApplication *app;
9 p, J6 A0 F6 W - int status;0 G! `+ L7 ~ O/ `0 ]% d* x
- 3 ?/ S5 v9 t! y$ P% S# {
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
; N( h6 g! {- g3 p$ e. n& {. C - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
* w0 v' n, A4 |! {* Y" \ - status = g_application_run (G_APPLICATION (app), argc, argv);
6 p, C6 |9 F* s _* i: e! j( ] i7 C - g_object_unref (app);6 n5 g8 ?/ Z5 s( l) y
- . c5 V: w1 [" ?; O
- return status;
4 P6 F! r/ O1 q T0 M, r$ Z - }
/ z5 j. b) k0 |1 y# Y/ N. G) P9 d6 F
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 ) D# ?9 B. m0 H. }/ y/ z+ u
- PROG = gtk_hello_world
8 ?) e% O0 O$ L( x7 O% O& S - SRCS = gtk_hello_world.c& I6 s" |. \% S+ S, n, l
- 1 ?; d# `" d2 r; A
- CLEANFILES = $(PROG)9 h' ~ ?. b5 O9 V/ q( e+ l
- " X) u0 y4 H4 T4 A7 i3 g2 w
- # Add / change option in CFLAGS and LDFLAGS
& f7 F* i/ m, i- G6 _1 }8 I - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
* q5 b1 a8 k9 N - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)4 f3 Q+ c/ W/ l9 D) t/ ~- C
- " V% q% ~4 Q' y# n0 K1 \
- all: $(PROG)* c ` b7 n6 |9 D3 |5 G
$ h3 g% K. t8 Y$ G; o% `5 r- $(PROG): $(SRCS)( G/ ], F( r$ z6 \
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)0 I3 g6 Z* ?* A% C
- 2 A7 s4 y0 `' S( Q- `
- clean:
$ d3 ?. R6 G- b! ^1 B+ I9 S8 O - rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
/ W5 Z: y3 V" M! S
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
" }3 A, O4 i* k ]8 M; H2 U/ i' ~
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。
& L( g) v2 z3 Z7 X& W* J) N
" B/ p" W- i) _5 |3 m4 V5 O
" P" \ l' E. [: Y- #include <gtk/gtk.h>. @, a5 s% q1 P# y( y0 j' K
- #include <stdio.h>6 t0 x5 f! e5 c* U" k; `! a/ p6 O
- #include <string.h>
& `- P F: i3 `, A5 D
w7 |6 D# m1 A6 h- C' M0 _( F: M- char buf[50] = "";
) o+ D* s; c# e; m4 T/ a
0 H! `" u' J& \: ~8 j! w7 {- void calc(GtkButton *button, gpointer data)5 N( v$ q. p& E$ Q8 P, k% }
- { b+ ^/ A* I* n) P5 W
- const char *text = gtk_button_get_label(button);
+ k% U+ M& p# b: p1 t - # [3 p) S! u8 s8 \+ m
- //退个操作8 o Y* k9 J" h% l$ {9 e
- if (0 == strcmp(text, "c"))
6 |% q) c5 r; V3 p - {+ N# s; {# g, X5 {+ |
- buf[strlen(buf) - 1] = 0;$ f [7 e; t" X8 G% J
- }else{
) k: l/ I, p1 z* J1 B
+ \0 Q! F7 E; [; M2 K- int a = 0, b = 0;
; Y& U! p/ [' [ - char c;; N' }0 R' J; r G1 y8 |* H
- strcat(buf,text);
* C* P* y0 [3 d' X
! K- \3 g& U& K, Q4 d- if (0 == strcmp("=", text)) {+ O" T2 v0 ?2 B7 U5 u! s
/ l7 p- I1 a0 }9 U% }9 I) R- r+ D# p- sscanf(buf, "%d%c%d", &a, &c, &b);1 D; S+ Y4 U/ e) b% j1 G
- 3 S+ O' u) `: d
- if ('+' == c) {4 A# x, _( i1 l, {1 z0 n
- sprintf(buf,"%d", a+b);
* i' I$ C2 Z5 }% W# A) n6 y - }
! F7 H4 l' f, Q8 g( ]( K - else if ('-' == c) {$ C& D! f' L. j
- sprintf(buf, "%d", a-b);$ N/ a" W% a0 ^
- }3 O+ s4 ^5 Q- i/ |+ g, ]7 l
- else if ('*' == c) {
8 ~4 W1 F2 y) s - sprintf(buf, "%d", a*b);
9 y" Q4 W# `7 ^6 } - }8 v; h9 w: ^- w
- else if ('/' == c) {( f- t, z8 H+ }+ j3 @
- sprintf(buf, "%d", a/b);; g3 g3 l6 F, X$ Q& e" {! r9 R5 B
- }( H% p7 d+ z* @/ O5 ~, o4 i
- X# C! [2 I. z" I$ @7 R4 `, C0 U- }* r( g7 Q9 Z6 k
- } b; T; K+ f! y d& q
- $ Z0 _' X1 ~2 b" E
- gtk_entry_set_text(GTK_ENTRY(data), buf);
& P b0 R- s6 b" m4 A" d
! x3 P4 n# f4 H C- return;
" ^/ L' v7 T' J( ]9 ^ - }
7 J9 w8 B2 g0 e7 C- Q3 ]
! g( f# T( S) y4 E% a3 v' T; h, I- int main(int argc,char *argv[])4 f& H8 _; l6 x# P) J
- {, ^) `3 v1 l+ p c# z8 Y
4 j' @, V. T6 I/ t! X- gtk_init(&argc, &argv);5 Y- `3 [( a' d' b
. @9 @9 V( a J" r
( |; N$ m7 C3 m" V- [; N- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1 {1 U8 m0 V; `7 G# r - gtk_window_set_title (GTK_WINDOW (window), "calc");- G6 I$ V7 B- t3 ^8 W! P
, l% b1 B" w: s) H- //创建一个表格容器5行4列. Y# p( Q/ y- _: {: d0 U# j
- GtkWidget *table = gtk_table_new(5,4,TRUE);
2 B; I4 t" v T- ^: u9 P* k5 V5 N
2 V4 [% j& U( a' [. n+ [" U- gtk_container_add(GTK_CONTAINER(window), table);* }: w! t5 H0 }6 y
- " _* G5 _- q- m- \
- //创建一个行编辑
9 L* O& j1 Y: q - GtkWidget *entry = gtk_entry_new();
( B" Q; B2 q" {* u
& H9 F! H6 c1 g9 o D1 W- gtk_entry_set_text(GTK_ENTRY(entry), "0");. K0 g/ M) R! {) w: q5 @
1 i) f1 r8 n) o5 O- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);1 X5 V h2 U6 G8 g, N \8 ]
- ; w6 ~4 G, c% W8 b. B( Z$ y
- //创建多个按钮; O, p8 ^' S, v# ?
- GtkWidget *button0 = gtk_button_new_with_label("0");% u5 }6 q- A8 B
- GtkWidget *button1 = gtk_button_new_with_label("1");) `) n. G: o) z* k
- GtkWidget *button2 = gtk_button_new_with_label("2");5 N* x# U; k* l5 O
- GtkWidget *button3 = gtk_button_new_with_label("3");
1 m& R6 X4 A6 w/ S! Q9 ^9 x - GtkWidget *button4 = gtk_button_new_with_label("4");9 ^! R+ k$ z7 Q: H' [) ?$ k5 K/ ^) T
- GtkWidget *button5 = gtk_button_new_with_label("5");
( U1 c- n. f! i# w# `9 k& ~. V - GtkWidget *button6 = gtk_button_new_with_label("6");
( |% t C4 u/ {# @4 _- R7 _ - GtkWidget *button7 = gtk_button_new_with_label("7");3 r5 @1 O+ T, W
- GtkWidget *button8 = gtk_button_new_with_label("8");
: z+ V2 m9 Q3 X4 ~- v - GtkWidget *button9 = gtk_button_new_with_label("9");
7 h& l8 X; K8 l' ]2 u. M - ! L/ R. R) G( u
- GtkWidget *button_add = gtk_button_new_with_label("+");
- S( S( y' G- ]2 A - GtkWidget *button_minus = gtk_button_new_with_label("-");. s V$ e, U4 r7 t
- GtkWidget *button_mul = gtk_button_new_with_label("*");
' X; Z9 Y! Q+ \% ^+ c1 T - GtkWidget *button_div = gtk_button_new_with_label("/");7 B1 l* {! |! O" Z5 T
- GtkWidget *button_equal = gtk_button_new_with_label("=");# o. K2 i( B- H/ r8 s
- GtkWidget *button_delete = gtk_button_new_with_label("c");
/ m6 W/ c3 E0 V$ n" Z
* D Z6 Q) K% p8 n' L! `& K
; m" d6 x) l1 s5 G; h: a5 f7 t- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);
3 r& a- M+ w" ?# I - % N, m }6 A7 w( K- Y9 }' i. m
- gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);
2 G9 u& ?0 `5 T7 I" k' V - gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
$ H: }' W3 g9 v4 O5 }6 X! J - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
) Q& @6 ~7 v& y3 I; T - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
6 k/ p$ O' J$ i! o! k, S& T - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);# J) |8 h- ^6 O
- gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
# `- ~" W# ~ g. c& A" N - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);
K# ^; E% J% ]- z0 Q; |7 b - gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);! F; B& L7 m& r) {' B, s1 E2 Y
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);$ f( `9 H6 f5 v
- gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);
/ M j9 Y. \8 ]1 g% X0 r. O - 6 S2 ]/ x5 q2 A
- gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
2 @0 e1 A7 W. `/ L- C - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);4 n* d' q9 C4 V
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);" U* h' G& r* i' }6 g: m
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
; ? x; J) C8 p$ i3 q( g, M - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
4 ?' j2 r j: p* h - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);
2 x8 y9 i& n ^. k) ~) m0 x - ; h+ M! b& T2 i* M9 V. \; O( X
- //注册信号函数,calc()
% W' H+ x! y, ? - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);
& F4 U6 K7 ~3 [; i+ k \% B% \ - g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);9 a' N4 e" `5 r8 u! a1 `+ I
- g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);
. p$ c4 l o/ y O* L0 e - g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);, ~8 w6 c# E U% R4 k" a
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);
6 b" \$ u' f& |2 }6 N# l- O - g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);& z0 Y' B y' {! c* U$ s4 Q
- g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);
% l7 x5 z: {6 j% l! b# F4 a8 r - g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);% |% L X* C- b- y
- g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);" U; ^& t6 ?, Y8 |( }* d
- g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);. }1 m T* @3 [/ C8 h; p1 _
- 5 C- V0 z$ U9 }
- g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
$ Y1 Y, ?2 H {" C' \2 @ - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
* O6 }: A' l% A$ ^3 c5 O6 t - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);5 J( Q A1 ^8 G$ ?9 M5 Y9 ~
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);
9 n! D3 P) V e6 j - g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
& H: ]/ X& p) I" v9 O. Y. ^$ M9 _ - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);
$ B5 ?) l" r* @2 { - 9 y Y( ]( k5 W2 U
- ; T5 i7 F6 G' ^/ s% `) l# d
- gtk_widget_show_all(window);$ E5 O t* \/ e2 Q4 G; Y6 V' J
- 8 K! \, W5 |% A% u! g
- //主事件循环& B* o! G& D$ y' f, i/ B
- gtk_main();* a9 e8 z2 Y2 A+ G
: U% F4 [* ~/ I/ `- return 0;) B) G/ C3 d5 n p
- }3 H7 f4 N' ]5 @7 J: M
复制代码 以上程序,编译运行后,就可以有以下得效果
) K# ?$ k9 i. X% k( @3 I+ |
( I, D& \3 }' N5 O- o
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。 |