上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。& O* i7 G W& {& }! Y
基于Ubuntu18系统,补充安装所需要的库和小工具/ D- w* h; O: A4 ^
更新软件列表 安装python3
1 g9 ^( n4 ~! r$ l! }! M9 @- 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-software3 R1 e/ j9 f! A* d* j$ b8 q
我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。! Y- t) N4 m% l% a+ r. A
2 e+ k7 ~6 L. k( d9 R: J8 i+ e- e 然后就学着官方文档的样子去验证下SDK是否安装成功。! z, d0 o* `' l X$ X( J! `
5 `7 {: q6 l$ x f8 n& ? a0 C' Q 以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。
6 o! }8 V' W. n$ t3 B/ r: F 首先拷贝官方给的demo程序,基于GTK得hello world。4 R9 U& X. `2 X! g
* v. l6 n; A; ~- #include <gtk/gtk.h>
( o: M R9 Q( T - $ d6 Z. a7 ?/ j! r/ U2 e5 e
- static void
- d" H% Y2 s' z - print_hello (GtkWidget *widget,& K) E9 w# S, |( C. |; K$ ]" _
- gpointer data)* f1 `- S, H, w+ {! x
- {
3 G( J( d/ P8 N0 M - g_print ("Hello World\n");( W) B8 b9 @; m$ h$ z
- } L1 I/ h8 f8 E1 Q) P
- Z5 V Y+ r1 S2 d1 @3 C! W+ U
- static void
% b2 i1 G2 B& ~, q - activate (GtkApplication *app,( s6 N( y) M1 I3 H( P) h
- gpointer user_data)
, i, R/ ^9 y6 c e6 M - {
t# a% ]; W# s# p6 F/ i9 p - GtkWidget *window;, f4 U# u8 a/ P% x
- GtkWidget *button;# ^' Q, R6 |$ U D/ T$ w( b
- GtkWidget *button_box;
' M* e% g; z+ `. u1 m; }8 `- z - 3 o3 |5 o6 X1 V
- window = gtk_application_window_new (app);( k, R$ p8 `+ A+ i
- gtk_window_set_title (GTK_WINDOW (window), "Window");$ S+ M% u$ A7 J1 z& s8 Z
- gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);- O# ?9 d& H+ l# N
- ; y" D Y7 F' _" S
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);. P6 @2 I5 p9 w
- gtk_container_add (GTK_CONTAINER (window), button_box);
$ b3 j7 R1 o2 P8 T2 G( z
* N/ g5 d3 z- P4 a P- button = gtk_button_new_with_label ("Hello World");; L$ `3 g+ A. H% d# l( L- C4 ~& w0 S
- g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);% B) P+ I& e2 { K
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);4 G% a, q ^7 D3 |* y2 A) A2 n0 p
- gtk_container_add (GTK_CONTAINER (button_box), button);$ ?) e' [- d" G
- 4 l x' u1 d0 x# `* d7 X
- gtk_widget_show_all (window);# I6 t* j0 u; e r. y% A' T
- }
2 [' }( P% j6 o/ w, S/ M4 w8 t
2 I% ^8 o/ L7 v* E# K: R- int
& ?& [4 r4 T# H) [% @ - main (int argc,) Y! ]1 A+ x; {5 ~4 F/ G! C( g3 U
- char **argv)" q: y+ e/ Z; D$ h, }0 {
- {- ~9 R) k& f, c: p& u( y1 A' h) u
- GtkApplication *app;* m9 q1 g% E- f2 f3 k5 B4 B
- int status;/ U" R) }4 O4 }& M$ e% N
- " }$ k, D# I. T6 ^: e+ T
- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);% p) o, o* ^. O5 Y W
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
* f$ ]6 f' g |# j* f9 L/ A, _ - status = g_application_run (G_APPLICATION (app), argc, argv);
/ l; ~0 V- s3 V9 a% v0 `" ] - g_object_unref (app);; q) O5 X' u. h7 R& G8 p) b
& c, ` \- V2 D. X5 g: o! S* h- return status;6 S2 l' x' n5 T! S) f
- }
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 - PROG = gtk_hello_world1 I# I7 p5 e: Y" D
- SRCS = gtk_hello_world.c
# ]0 R( R5 Q, ^; H - 0 ?2 B- P7 f: k
- CLEANFILES = $(PROG)7 w3 a$ h. n5 N+ R' m
1 J1 w+ ]3 X3 H/ s' L- # Add / change option in CFLAGS and LDFLAGS
, o k. Z" q+ K - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)2 N9 F) p$ `3 }! b' Y
- LDFLAGS += $(shell pkg-config --libs gtk+-3.0)& f2 A1 @/ ?. H" ]7 b* l
- # p! i6 y/ d- H. l, z7 F
- all: $(PROG)4 Y4 U+ A7 S g' s) _
- Y: \+ p+ T( ^7 j4 D+ [+ O# Y- $(PROG): $(SRCS)
, q8 M. E/ i0 Y2 W6 `- B" k: K - $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)9 c0 d' J+ b6 t0 l' F: X/ g
( c4 ?8 [& c* q# b9 p; K* ~+ R- clean:( {0 y7 z5 g Z9 j u+ `* ]
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。
+ k- L4 r7 F x% N$ U& z
* ]/ [) d H; q9 X
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。
' x$ {; i6 `3 f. T$ k
" ?: }/ l+ w9 B1 h+ m2 k1 O- #include <gtk/gtk.h>8 J" @9 q- k* s+ P0 ^9 l. ? {
- #include <stdio.h>
0 E5 u* [% Q: p7 |% T - #include <string.h>, W8 r* Y5 [; v0 T( t5 U
-
% l! ~, A' t- n* R) I% K - char buf[50] = "";
y5 P9 L3 C6 m) s3 U/ p -
$ X+ u4 C: e2 c5 R$ s& K- M - void calc(GtkButton *button, gpointer data)
$ p! @: w1 c* j: W+ }9 }) {# x& p( | - {
' t6 V1 Y* X, E# Z' v; o; _ - const char *text = gtk_button_get_label(button);, T9 a( o n% ]! k4 F" t9 }
- A, T4 A: c, g3 L+ p2 {
- //退个操作
Y3 `* A& ?/ ~ - if (0 == strcmp(text, "c")) 6 J$ L P" k* [9 p' v
- {" R2 c/ ?. }6 _% b, ^6 e3 J. y8 T
- buf[strlen(buf) - 1] = 0;
. v% q# s( x0 ^ - }else{
# O8 l* W4 A+ z) y' x7 h; n - & u }! W* _. }/ G# t/ f& j
- int a = 0, b = 0;
+ D) ?4 g1 f' F$ }3 O, { - char c;; M5 g& {, m& k
- strcat(buf,text);7 J3 o' W2 u" X# [. P j/ `! `
-
$ r( g" W/ \/ @1 s) r - if (0 == strcmp("=", text)) {( g7 g# p6 [" S4 R7 y
-
3 Q2 H K1 F! {7 |8 Z" l1 P - sscanf(buf, "%d%c%d", &a, &c, &b);: c0 t6 J. ~- s( Z9 O
-
$ c2 o \5 i, I2 d3 U - if ('+' == c) {, b! [. s) r$ h/ C w* Y: `2 r9 n
- sprintf(buf,"%d", a+b);
7 s% y5 C7 E" g: B* A - }
) \' c3 [% o& G1 M2 S1 d - else if ('-' == c) {
9 z# q7 }! Y' ?7 y% V$ W$ Q; C - sprintf(buf, "%d", a-b);
8 Z" U" }+ ~8 q0 { s - }
) [# t! R4 x& X3 t - else if ('*' == c) {& \# f; Z+ u. a) F9 P% Y5 P
- sprintf(buf, "%d", a*b);
1 [- ^8 t" ?1 e$ O" D1 F3 i5 ` - }, T; Y& o6 Y& e$ i8 m6 R8 B# s" Z' q% l7 L
- else if ('/' == c) {5 T- G* P* I/ \& f% F
- sprintf(buf, "%d", a/b);! A$ O+ K- T3 p$ K7 ]
- }2 \- C" w0 O5 V$ M
-
8 W( ?: o/ B2 l; \ - }0 b1 _" q: Q- e8 h. \
- }& N- v! R7 x- L- z
- 8 ^) b+ ^0 `- \0 |. ]/ O1 G* S
- gtk_entry_set_text(GTK_ENTRY(data), buf);
% e) m3 D6 @& z8 b' T: u -
$ Z R7 ?* B e" Q; F* i3 u! F - return; S- C) a" k! S2 |% E( n
- }
& Z9 c2 K5 o1 X, B1 ` - 7 t4 p; z0 f6 A
- int main(int argc,char *argv[])' }0 L* u# s ?8 R+ }6 F5 S
- {
' O( I/ W( b3 P) p6 Z
! d7 Z! Z+ \$ B" J2 f' M: D- gtk_init(&argc, &argv);
; t1 [$ ~7 q: k- \ -
+ n' \; x: q ^: z
. x: B6 n9 R, @' _1 r7 V- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- `9 h- P' `9 R: X# O7 C( b, H) m - gtk_window_set_title (GTK_WINDOW (window), "calc");9 Z9 D9 O7 m7 V) J5 M0 l
-
8 h5 ]3 {/ @. V - //创建一个表格容器5行4列: n7 ^& P; s' k8 I
- GtkWidget *table = gtk_table_new(5,4,TRUE);
* m3 o0 a) t! R - 0 {0 {5 ` s( p, D ^4 V
- gtk_container_add(GTK_CONTAINER(window), table);" o/ A' y3 m. {# d+ X0 O
- % L: Y& Y9 p$ A4 u9 U! E( T
- //创建一个行编辑
7 D! U; h* @9 k& U5 A, T( | - GtkWidget *entry = gtk_entry_new();
. w1 B# \1 D. I% r - k" d2 ^5 @) C5 C0 i
- gtk_entry_set_text(GTK_ENTRY(entry), "0");* }; t' @# y3 d3 Q( z# e
- 4 W' @+ n0 m' w$ x
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);9 A# N% q0 X- f9 P9 C% w$ ?+ @
- 5 ^$ _$ j: q3 g0 J, E3 F; a
- //创建多个按钮# ]1 \% u1 m5 A/ ?' P
- GtkWidget *button0 = gtk_button_new_with_label("0");5 o: b5 |# `3 c6 V" p4 q
- GtkWidget *button1 = gtk_button_new_with_label("1");
8 ]( y/ q4 `3 l' u. Y/ A/ j - GtkWidget *button2 = gtk_button_new_with_label("2");0 L* C' g) ?+ D. t. q
- GtkWidget *button3 = gtk_button_new_with_label("3");- e, Z+ p5 B- `5 G( R
- GtkWidget *button4 = gtk_button_new_with_label("4");, G* ~( @, m2 H0 F( X, Q- H
- GtkWidget *button5 = gtk_button_new_with_label("5");
6 `5 W3 U4 y2 \2 q( b- L - GtkWidget *button6 = gtk_button_new_with_label("6");
8 N4 b* y& D* j e% n# K: V - GtkWidget *button7 = gtk_button_new_with_label("7");' D3 _3 @7 C, @9 n2 b: q* q, `9 @
- GtkWidget *button8 = gtk_button_new_with_label("8");
% N4 H! C- S) |* k! C - GtkWidget *button9 = gtk_button_new_with_label("9"); i5 O5 N% D( X3 w4 \6 ~0 k. O
- 9 a9 t. }! H6 P1 F$ P$ j, q7 i
- GtkWidget *button_add = gtk_button_new_with_label("+");
; Q$ z! c( d: E4 |/ O - GtkWidget *button_minus = gtk_button_new_with_label("-");
: {/ N- S# e& b% E - GtkWidget *button_mul = gtk_button_new_with_label("*");
: I3 k8 X9 E0 \, P( b+ X. u - GtkWidget *button_div = gtk_button_new_with_label("/");; }+ x1 C" { A
- GtkWidget *button_equal = gtk_button_new_with_label("=");
! z" l, k1 X5 x: M/ s* {! C8 {8 B$ } - GtkWidget *button_delete = gtk_button_new_with_label("c");
4 M! j$ q$ V% q( I! O+ u: C0 c. R -
5 t) L, m& n' E) v/ J0 k, c - ) j! u. u! P' }5 u- v
- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);6 Y: D8 _" }6 J. y
-
: p/ C( W! x1 ]. B - gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);+ K- [0 M. X; o
- gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
7 m6 f2 G% q4 e3 _' i - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
) Q- R+ @2 B& E+ l: T - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);. T& i \/ v6 O: L7 L0 }, p* B& V6 }
- gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
6 a& H* T# E* K H4 i, ] - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);
% Q) j* c: y7 E9 X" n - gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);
4 } j/ \8 l+ n - gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);
/ h. g1 q( {( a2 f: Q - gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
2 d& r% T1 y/ j8 d8 k - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);! |/ ]! N% H- m! X+ v. ]
-
$ H6 H' m+ ^! ^+ i& e; D0 {9 m - gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);
2 Q# r* j2 n3 H7 V+ x" P$ G - gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);( p2 V( }# c. }" J
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);" c" b% ~# [- `, `
- gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);
! S4 c: j. O9 c5 [( d# W - gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);
* M; y9 M) z, z& g- C1 P. p0 h2 D" A - gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);& j6 }$ p! Z5 V% q3 ~4 ^( @9 D
- ; h. c! v' @- w$ Q4 H `
- //注册信号函数,calc()
1 ~/ b+ q6 J* i. Y/ k - g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);
) p; U) ?7 s, x* g5 { - g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry);
9 @, R# o* L! e3 @6 d# Y/ X - g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);
) P6 }9 T* n0 e4 w/ O# V - g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);% Z# w3 G4 [/ N9 m4 s
- g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);, j8 ?7 x2 j: s9 c- [9 u
- g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);
/ D$ y; A* {7 D, ~ - g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);2 j& b t- I4 _3 L( G
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
; x) R" `2 E) j - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);; u1 O' ?8 L( I0 c
- g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);
. x7 L( ^8 B; h9 J. A -
) Q+ @% ~+ m) X4 m! w+ O+ ~9 @1 @ - g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);
- h$ R% ~: G3 C: h - g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
# D7 X& d# ~" `" ^ - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);! T2 A+ a: |2 X; r
- g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);1 u0 s9 n" M* i: }# Q5 P4 U
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
% E' Y" T1 R j( M9 J2 ~ - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);
3 h, \$ O1 S! i- h3 r -
& x, B: }* F e# t: }% R( c
. x* L$ h4 I: M$ x, z) ]- gtk_widget_show_all(window); v2 T( z+ {% @, ?) Z; w
-
4 p$ _& g$ j& q! @6 E5 q) G# i - //主事件循环
: m$ S* c e6 ^% R0 J - gtk_main();
7 F/ J4 u8 C, C; l -
9 l* i) _! b% a - return 0;
5 M3 I. c+ t( A5 L1 \ - }
复制代码 以上程序,编译运行后,就可以有以下得效果。
8 l. t2 f) h4 R1 f" w* x
, A* i" g( j! \( D- T/ X" N4 }
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。1 i4 @; T+ w5 P, g
搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。- Z1 {0 k# b+ C3 N/ o& x# D
9 w0 r. k% t: s2 D, v8 y$ i3 T |
官方板子不错,这么快就上手了。我的是odydess资料太少了。正在学习