上次已经开启了Linux系统,并且有GUI桌面,虽然不是比较熟悉的Qt环境,但也是可以做个小应用感受下stm32mp135系列产品的特点。 首先要搭建开发环境,毫无疑问安装个SDK就行了,官方WiKi页面啥都有。
1 ]1 u9 Q6 t7 Y2 W* t 基于Ubuntu18系统,补充安装所需要的库和小工具
' _3 x; E, z" e" s 更新软件列表 安装python3
8 i$ U8 c1 t- L5 J% I- 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
8 B6 K0 c4 {5 G0 J8 G0 j& n2 O 我还是在windows下面下载的,然后拷贝到了虚拟机使用。使用tar xvf 解压该压缩包。chmod +x 赋予可执行权限。然后运行安装就行了,默认的目录是/opt/st/stm32mp1/,,这个路径就可以,直接继续安装。9 b0 k% B% I6 J' Q4 r
$ r5 i! i, M$ x U' C) m
然后就学着官方文档的样子去验证下SDK是否安装成功。3 i: z) b! ]- G& R
) a9 {. V2 I% Q
以上就完成了编译环境,至于说开发环境,一般还得有个IDE或者其他编辑器加调试工具。这里打算做的小程序使用gedit就行。$ ^) L3 I6 M9 H7 Z- a( l
首先拷贝官方给的demo程序,基于GTK得hello world。) H! _5 q0 v3 O9 B& j1 g
- V$ U' t2 y! { m7 ~- #include <gtk/gtk.h>- Q: _/ ~4 @: V& d
, A0 B$ Z9 b1 e6 y8 |) u- static void
& X# i' ~* x) i" K- c) t - print_hello (GtkWidget *widget,
. ?$ ~$ Z0 Z, z: s" Z, p - gpointer data)
z. u' n; a7 `0 [* V, H - {' S6 Q3 V# U' b, T9 O
- g_print ("Hello World\n");! ~. c+ C, ]' u9 A/ j
- }
0 U* _+ }& ^0 \' X5 z$ M& R - l9 ?4 P0 H: h" [) o
- static void2 e6 t% ?+ |: |
- activate (GtkApplication *app,
/ q) e$ C% c8 K/ N7 C - gpointer user_data)$ d) x0 U3 c D! p! O" t
- {
5 U/ x. [& ~+ d - GtkWidget *window;
: ], b) Q1 Z7 q. k) M - GtkWidget *button;4 t& R( F0 S- g6 X8 s4 g: A# \
- GtkWidget *button_box;' p/ |1 q; @$ T, |7 ^# t
- " |& L9 I& t. }3 {
- window = gtk_application_window_new (app);* C O q, c1 p) {
- gtk_window_set_title (GTK_WINDOW (window), "Window");
& p( `8 y3 C2 @# f" S - gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
5 b# v: C" \( o2 ~7 S0 S- O - ) A9 u5 N9 r* H$ [$ S+ H$ \6 Z1 }
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
) t% M5 y) P! |% E2 e5 F - gtk_container_add (GTK_CONTAINER (window), button_box);) q" W/ N: D D& @$ S; c; a3 S7 d
- ( T2 C. h6 U3 X5 C( t: J; T
- button = gtk_button_new_with_label ("Hello World");
% ?4 T2 P3 w/ ?# D - g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);# g' L, g1 N u, X
- g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);' s7 q9 [+ W9 T
- gtk_container_add (GTK_CONTAINER (button_box), button);
" ^! o% Z' d; w& {
9 K' G4 D# d% z! B5 O9 w- gtk_widget_show_all (window);! v! G0 |1 L ^5 @% T
- }
4 k w1 P9 l4 x1 ? - ; }" ]0 w6 d" x0 @+ j, j
- int5 z8 H# ^, c4 k* w3 e! P: h; X
- main (int argc,
8 |( H& ?% P7 q3 B2 f - char **argv)
: R9 E6 j6 }* n! Z) m/ o1 ~5 C9 F - { Z7 _ ~, q/ G, X* L* ~; F' ?! X
- GtkApplication *app;! J7 \$ `0 j8 o0 T2 [
- int status;
% W0 {! x; D/ u, n$ k
8 Z) K" x3 ?+ B, @- m$ n. |- app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);7 y- D& v6 j( r2 u; H
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
) P0 X4 h, @& y% M, R, E - status = g_application_run (G_APPLICATION (app), argc, argv);9 s/ J# j3 e$ Q0 i3 H9 S% g% x
- g_object_unref (app);
1 o0 b+ l9 S( j5 k0 Y! x4 m - $ R5 J1 A9 x, J3 A% b. `. a0 L& a6 N
- return status;5 b n: h7 p$ j; R* b5 h8 l
- }
复制代码 然后也复制一个makefile文件,其实单个文件,直接使用gcc命令也可以得。 - PROG = gtk_hello_world
+ ]' @$ j3 N9 \9 h; @8 z; z - SRCS = gtk_hello_world.c
- S1 Y) T& S3 Q) _, M - 9 P( h+ s, Y6 g8 k3 s4 |9 \
- CLEANFILES = $(PROG)
4 e7 u2 Q* d8 o% M/ U8 `
# X) J2 p5 e; B" A- # Add / change option in CFLAGS and LDFLAGS
& ^9 b( S6 l' l - CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
~- U! {/ \) |$ Y* w0 x7 c - LDFLAGS += $(shell pkg-config --libs gtk+-3.0)4 i% \5 Q8 H! v9 Q8 s, h7 I# q
: c" I9 o' I4 g9 E1 U" ?/ W- all: $(PROG)
7 a4 P) }9 v8 {5 x1 X - , y) P; M% }* R4 e2 b8 x1 ]
- $(PROG): $(SRCS)7 P- D; V9 }9 L5 Q3 S' z9 T _
- $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)( H1 p3 {5 {! s# u0 ~- P- M! \
- 4 h- |* |0 h) D9 M7 g8 [6 h/ e9 u9 P
- clean:- K2 p0 [0 B0 q/ y. w2 M. `
- rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
复制代码 然后make,scp到开发板执行程序,就可以看到一个hello world窗口出现在之前得桌面上了。/ B7 T8 W. w! I
4 I8 I0 u0 Q( p; p
接下来改程序,说实话没用过gtk,不过看了下helloworld得程序可以看懂,所以也百度了一下,就基本做出来了。9 w! V& e3 b- ]" t0 u: P
" Y. M" @9 k Y' p1 B# b( H5 H- #include <gtk/gtk.h>
+ O6 V1 b$ c5 s; C: m8 v& D3 y - #include <stdio.h>
/ g: ^9 Q5 w3 a8 i& k - #include <string.h>
/ x( \5 N9 t8 m -
- }, u0 F& Y, ]. m8 z# |" I - char buf[50] = "";
" m0 a; N. ~, s - 1 |. N$ O4 Y" K# B
- void calc(GtkButton *button, gpointer data)
E* a( c* _2 X: Z+ @ - {
2 C" s) o6 ~/ b' ?3 _ - const char *text = gtk_button_get_label(button);
! c6 l7 J b8 K. k+ h7 S -
! m W* ^! I) M" E9 | - //退个操作
+ T4 `/ c' T7 ?% | a% C - if (0 == strcmp(text, "c"))
8 f [) p) j# Q - {
0 f" G/ @; }- p, @2 b6 K6 i - buf[strlen(buf) - 1] = 0;4 m# w: J1 `( U1 n* |8 y
- }else{
- I+ I6 I( }6 G/ F& w2 ] -
5 O& T. d# C1 j: S - int a = 0, b = 0;1 k$ M2 c; F% I
- char c;
/ o5 y" R m) z) @8 R9 B - strcat(buf,text);( o+ z' ]5 q' }9 `
- ' B- P' O& s! T! E7 u6 @
- if (0 == strcmp("=", text)) {
: b5 O3 w+ b. l -
b9 }2 G# [3 k$ J; v - sscanf(buf, "%d%c%d", &a, &c, &b);1 o3 M+ D: x; ~: f" n0 x: t; y
-
+ i7 O+ u3 ?% X9 h9 b% W5 B' p. s" u - if ('+' == c) {2 L0 } t1 H8 h( `5 G
- sprintf(buf,"%d", a+b);8 m* a6 q0 L3 \
- }! k2 k& Q: r% Q+ @) A% Z
- else if ('-' == c) {
+ Z% C8 |* M$ c" L - sprintf(buf, "%d", a-b);, K9 ?0 b+ s% [" Y9 ]: U! l& y
- }$ p9 p% f( b: f2 A0 ]7 B" g' F5 r7 S
- else if ('*' == c) {* h# U- }2 C8 G# h
- sprintf(buf, "%d", a*b);
% n; V: @" P; a+ M; p& s* S0 w) | - }: m2 M+ K* M0 c5 b: y- F0 R
- else if ('/' == c) {- W' g1 h3 p; j' X, Z
- sprintf(buf, "%d", a/b);
! K; J; U2 M3 c* C# u - }0 A6 O+ T) D$ {! h# s
- + [/ N! j5 j$ Z- j( F* W8 l
- }% D. G' R: E) u" t( z
- }! B l; {1 }9 b: M
- 4 X* z$ R3 r0 W" T6 s
- gtk_entry_set_text(GTK_ENTRY(data), buf);
( x- h8 M& r0 M! T4 v' z -
I" L2 O r( C `5 T% q# d) a - return;
$ @2 ~" d$ C; j( `5 G - }2 A P# G9 Y' o1 H: L: @5 j+ b
-
. `1 j9 ]& Q& g6 F - int main(int argc,char *argv[])
- X2 l* }) o5 G0 C3 R- X5 W - {9 s$ f8 B8 X/ F& U) f; a
- * F @) K! \- F `
- gtk_init(&argc, &argv);" X9 H' G1 S: M7 N9 k
- 5 o& V2 B% M5 E# e) R
- : G0 z0 _* @' w% h# A9 k
- GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
! ~- u. r+ x! e( }, `1 f6 e8 @ - gtk_window_set_title (GTK_WINDOW (window), "calc");: `6 n4 S: ]( D: z |' |
- ) U+ H* a# X3 t. P2 B1 O
- //创建一个表格容器5行4列7 l$ P$ K2 n8 l4 W
- GtkWidget *table = gtk_table_new(5,4,TRUE);- ?9 I4 Y3 F0 L' y: J
- - M- G# N7 [, z) `
- gtk_container_add(GTK_CONTAINER(window), table);
/ X! y' q( \4 m$ w3 r -
9 H8 E# ~) e$ t2 Z( d$ T h7 |' F - //创建一个行编辑
* g1 @6 T: T/ n0 {, w% {+ P @ - GtkWidget *entry = gtk_entry_new();1 x- @3 p3 y5 N
- 3 P: m* c# r9 u. l' y
- gtk_entry_set_text(GTK_ENTRY(entry), "0");5 \8 m3 C* \6 ~! z
- , s, B8 h9 d- G
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);2 u. R' r0 b W' T3 l
-
" o( l$ h- h/ i+ S R0 ^* v - //创建多个按钮0 |" d4 A) ?3 f* f8 p2 @" g
- GtkWidget *button0 = gtk_button_new_with_label("0");
5 k5 X: z7 U% e* o6 d1 a4 Y - GtkWidget *button1 = gtk_button_new_with_label("1");0 `5 d2 ^8 `. E' S' E' U0 \
- GtkWidget *button2 = gtk_button_new_with_label("2");1 S3 h% H5 \5 |# h3 S! d, h
- GtkWidget *button3 = gtk_button_new_with_label("3");
# x2 H5 }5 Z h) C- ^8 {" s3 @3 h - GtkWidget *button4 = gtk_button_new_with_label("4"); T& x5 u% }1 z1 X; }
- GtkWidget *button5 = gtk_button_new_with_label("5");* W! X( S G; X9 M& i
- GtkWidget *button6 = gtk_button_new_with_label("6");) \! _0 U! z3 C, E1 E$ E: M
- GtkWidget *button7 = gtk_button_new_with_label("7");/ i; r1 o% s9 Z# O8 u" |8 B( M/ D( p
- GtkWidget *button8 = gtk_button_new_with_label("8");" b" g' d1 x1 y. c
- GtkWidget *button9 = gtk_button_new_with_label("9");4 V- B3 E0 w: U! a3 S: T
- " y/ d. \: n+ U
- GtkWidget *button_add = gtk_button_new_with_label("+");+ d' x+ j, j2 l: P: v5 z3 @0 m
- GtkWidget *button_minus = gtk_button_new_with_label("-");: G+ Q' J) I& r" \
- GtkWidget *button_mul = gtk_button_new_with_label("*");
( g3 [, m9 b) T9 I - GtkWidget *button_div = gtk_button_new_with_label("/");+ [5 o; b0 H7 h X* J4 c- m& Y
- GtkWidget *button_equal = gtk_button_new_with_label("=");9 ^, S b$ _3 ]5 R: T0 g
- GtkWidget *button_delete = gtk_button_new_with_label("c");9 O9 l* S4 D+ ?& j, u2 R# m, h# B0 T
- 5 c7 m+ c+ d* @! L! V4 q
, M: u+ X7 N% T c0 R! l2 e- gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 4, 0, 1);
( D$ e- q: ?- ^& f q8 f% v, T -
" q! {4 f8 F& F k( c - gtk_table_attach_defaults(GTK_TABLE(table), button0, 0, 1, 4, 5);' g1 ]1 r0 H# {7 q
- gtk_table_attach_defaults(GTK_TABLE(table), button1, 0, 1, 3, 4);
7 Q. z' s. }: C5 {( C5 ^0 @6 | - gtk_table_attach_defaults(GTK_TABLE(table), button2, 1, 2, 3, 4);
) L- T D- S0 f3 m- o - gtk_table_attach_defaults(GTK_TABLE(table), button3, 2, 3, 3, 4);
" I- Y1 Z1 w2 v' M1 x3 | - gtk_table_attach_defaults(GTK_TABLE(table), button4, 0, 1, 2, 3);
' m/ T$ J6 I! ~0 [; j( [3 } - gtk_table_attach_defaults(GTK_TABLE(table), button5, 1, 2, 2, 3);! M# _8 l5 b& e8 h0 b
- gtk_table_attach_defaults(GTK_TABLE(table), button6, 2, 3, 2, 3);
5 [8 }1 i, e& _' F7 U' \ - gtk_table_attach_defaults(GTK_TABLE(table), button7, 0, 1, 1, 2);* o- n9 B- S" ~ i n* U. T: v# G0 E
- gtk_table_attach_defaults(GTK_TABLE(table), button8, 1, 2, 1, 2);
4 J' c. v2 {, v4 w) I - gtk_table_attach_defaults(GTK_TABLE(table), button9, 2, 3, 1, 2);3 p* f7 E- k' k8 U9 H) D. O# \
-
6 t8 N: w9 w) q0 e$ ?& H4 m$ r - gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 2, 4, 5);' l7 Q- Q8 U% |" C4 _" h" T+ w0 F
- gtk_table_attach_defaults(GTK_TABLE(table), button_minus, 2, 3, 4, 5);! p$ Y1 m7 [ D1 C
- gtk_table_attach_defaults(GTK_TABLE(table), button_mul , 3, 4, 2, 3);
. ]4 r0 e/ O# k9 g9 \8 {. g - gtk_table_attach_defaults(GTK_TABLE(table), button_div, 3, 4, 3, 4);% U" R' U- O* Q J: y! U$ ?3 P
- gtk_table_attach_defaults(GTK_TABLE(table), button_equal, 3, 4, 4, 5);3 ^5 i9 A6 P4 {- ~+ j4 i
- gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 3, 4, 1, 2);
& E' H$ j7 P3 h5 z; ?8 \ - * N( a6 W' b( c4 y5 x, @
- //注册信号函数,calc()2 A/ J( X. {/ [
- g_signal_connect(button0, "pressed", G_CALLBACK(calc), entry);
- D9 `* g* E J - g_signal_connect(button1, "pressed", G_CALLBACK(calc), entry); |7 Q; f X, o7 e) N, a
- g_signal_connect(button2, "pressed", G_CALLBACK(calc), entry);; N$ i1 e0 B! ]- X9 {1 d9 P/ P
- g_signal_connect(button3, "pressed", G_CALLBACK(calc), entry);
+ v( l$ m* _* f& s - g_signal_connect(button4, "pressed", G_CALLBACK(calc), entry);/ m; I4 y- s( M8 X% y5 a4 }
- g_signal_connect(button5, "pressed", G_CALLBACK(calc), entry);
N& R6 ]+ X4 l% l; F4 M - g_signal_connect(button6, "pressed", G_CALLBACK(calc), entry);6 a) P1 b* ~9 ~, M) g
- g_signal_connect(button7, "pressed", G_CALLBACK(calc), entry);
$ m6 l; F! d+ K5 M; W [: Z - g_signal_connect(button8, "pressed", G_CALLBACK(calc), entry);
3 l' F) H; ?' F3 @& i - g_signal_connect(button9, "pressed", G_CALLBACK(calc), entry);, @9 V G4 y' O z- d
-
9 t" r% l( t) Y+ I$ ?5 `* m* T - g_signal_connect(button_add, "pressed", G_CALLBACK(calc), entry);, f$ _. ~; c; `/ w8 b
- g_signal_connect(button_mul, "pressed", G_CALLBACK(calc), entry);
1 T4 h- T* i' k' e - g_signal_connect(button_div, "pressed", G_CALLBACK(calc), entry);
+ ]+ E S: J3 J: a, [; X7 N$ x. L5 B - g_signal_connect(button_minus, "pressed", G_CALLBACK(calc), entry);* _% o4 }4 G) g( y. B- \
- g_signal_connect(button_equal, "pressed", G_CALLBACK(calc), entry);
8 T! J! o& p/ K+ [ - g_signal_connect(button_delete, "pressed", G_CALLBACK(calc), entry);% @: S4 M+ k) u
-
( Y( a# v6 X/ Z5 q u% X
9 S! O3 p$ S1 o* e( y- n- gtk_widget_show_all(window);- g' ~; B9 V2 f# ~' V
- . v+ p0 f, `7 H/ B, ^, ^3 a
- //主事件循环
! d( T. l0 x4 ] H2 G - gtk_main();
2 p5 V. c4 X$ e -
" L$ l- ^$ ^/ P! A - return 0;
2 D/ N; w8 U- w( V& U. W - }
复制代码 以上程序,编译运行后,就可以有以下得效果。
2 l# `2 I( _0 \
" f) k; p5 m4 i0 x
操作和UI都是比较简单得,就不演示过程了,系统得触摸驱动也是做好的,gtk只管做应用就好了。操作也算流畅,毕竟也没涉及到复杂的图表渲染。
0 |2 l* I( }' M6 i# Q; ] 搞到这里,发现其实不复杂得GUI程序用这套现成的框架倒也是挺方便。Linux系统下其实资源很丰富,软件开发方式也很多选择,所以不多做逗留了。这款开发板还有一大特点就是可以按照以往STM32单片机得方式进行使用,所以后面感受下1GHz的单片机开发方式。
K# H5 B% y; ?
+ u% p' I5 @4 k( Y* U* [) Z |
官方板子不错,这么快就上手了。我的是odydess资料太少了。正在学习