bigbat 发表于 2020-3-26 15:05

STM32MP157A-DK1测评+HelloWorld与GPIO(2)

<div class='showpostmsg'><p><b>启程HelloWorld</b><br />
OpenSTlinux的环境让我感动的是:板子启动后直接显示图形界面,不会象屏幕输出控制台信息!这个很&ldquo;炫!&rdquo;。控制台信息让我很头痛。你给用户输出这些没有用的信息也闹心。<br />
参考ST的官网资料&quot;Create a simple hello-world application&quot;,创建程序。<br />
<strong>1、首先确认开发环境是否正确&nbsp;</strong><br />
$CC --version<br />
如果不正确,就使用环境脚本文件配置正确!<br />
source /opt/st/stm32mp1/2.6-openstlinux-20-02-19/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi</p>

<p><strong>2、开始编程!</strong><br />
使用你喜欢的文本编辑器。我的是<br />
vi gtk_hello_world.c<br />
输入以下代码</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">#include &lt;gtk/gtk.h&gt;

static void
print_hello (GtkWidget *widget,
             gpointer   data)
{
g_print (&quot;Hello World\n&quot;);
}

static void
activate (GtkApplication *app,
          gpointer      user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;

window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), &quot;Window&quot;);
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);

button = gtk_button_new_with_label (&quot;Hello World&quot;);
g_signal_connect (button, &quot;clicked&quot;, G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, &quot;clicked&quot;, G_CALLBACK (gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (button_box), button);

gtk_widget_show_all (window);
}

int
main (int    argc, char **argv)
{
GtkApplication *app;
int status;

app = gtk_application_new (&quot;org.gtk.example&quot;, G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, &quot;activate&quot;, G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);

return status;
}
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); left: 0px; top: -15px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>保存文件待用</p>

<p><strong>3、编译程序</strong></p>

<p>编辑Makefile文件<br />
vi Makefile<br />
<span style="color:#e74c3c;">注意不能直接考本的脚本!必须在&ldquo;命令前面加tab!!!&rdquo;</span><br />
这个是给linux开发新手看的。如果不懂那就快乐的学习一下吧。</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-makefile"><span class="hljs-constant">PROG</span> = gtk_hello_world
<span class="hljs-constant">SRCS</span> = gtk_hello_world.c

<span class="hljs-constant">CLEANFILES</span> = <span class="hljs-variable">$(PROG)</span>

<span class="hljs-comment"># Add / change option in CFLAGS and LDFLAGS</span>
<span class="hljs-constant">CFLAGS</span> += -Wall <span class="hljs-variable">$(shell pkg-config --cflags gtk+-3.0)</span>
<span class="hljs-constant">LDFLAGS</span> += <span class="hljs-variable">$(shell pkg-config --libs gtk+-3.0)</span>

all: $(PROG)

$(PROG): $(SRCS)
        <span class="hljs-variable">$(CC)</span> -o $@ $^ <span class="hljs-variable">$(CFLAGS)</span> <span class="hljs-variable">$(LDFLAGS)</span>

<span class="hljs-title">clean:</span>
        rm -f <span class="hljs-variable">$(CLEANFILES)</span> <span class="hljs-variable">$(patsubst %.c,%.o, $(SRCS)</span>)

</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); left: 0px; top: -15px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>编译文件<br />
make<br />
如果没有错误,就可以看到生成的gtk_hello_world文件了<br />
<strong>4、上传文件,</strong><br />
&nbsp;scp gtk_hello_world root@192.168.0.103:/usr/local<br />
替换你的IP地址。&lt;board ip address&gt;<br />
转到控制台执行程序。<br />
./gtk_hello_world<br />
在显示器上可以看到图形化的窗口。点击按钮,程序在控制台输出&ldquo;Hello,World!&rdquo;</p>

<p></p>

<p>本例程使用的是gtk库,gtk开发十分的麻烦,功能也不怎么丰富。据说可以使用qt5,有时间可以研究一下。<br />
<strong>GPIO操作点亮LED</strong></p>

<p><strong>1、GPIO介绍</strong></p>

<p>对于嵌入式开发者来说不能操作硬件是有点说不过去的。所以能够点亮LED才算是正宗的&ldquo;Hello World!&rdquo;对于unix系统&ldquo;一切皆文件!&rdquo;,linux系统下的设备文件在/dev目录下。通过查看找到gpiochip0~gpiochip9共10个设备文件。每一个设备文件对应着GPIOs端口。也就是gpiochip0对应着GPIOA口。详细的信息可以使用<br />
cat /sys/kernel/debug/gpio<br />
查看得到。通过资料知道LED5是与GPIOA的14脚相连。使用gpioset工具操作gpiochip0的14脚应该可以操作led5的开断。<br />
gpioset gpiochip0 14=0<br />
可一看到rest按键旁边的led5发光。资料上说好的是Green怎么变成Yellow啦。Yellow也挺好!只要亮就行。</p>

<p><strong>2、使用文件操作GPIO</strong></p>

<p>使用C代码写一个led5程序。开始我想使用libgpiod库来操作gpio。调试了很长时间,也没有成功。没办法找到了一个直接操作设备文件的代码</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-preprocessor">#include &lt;errno.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;fcntl.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;stdio.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;stdlib.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;string.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;sys/ioctl.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;unistd.h&gt;</span>

<span class="hljs-preprocessor">#include &lt;linux/gpio.h&gt;</span>

<span class="hljs-keyword">int</span> main(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span> **argv)
{
        <span class="hljs-keyword">struct</span> gpiohandle_request req;
        <span class="hljs-keyword">struct</span> gpiohandle_data data;
        <span class="hljs-keyword">char</span> chrdev_name[<span class="hljs-number">20</span>];
        <span class="hljs-keyword">int</span> fd, ret;

        <span class="hljs-built_in">strcpy</span>(chrdev_name, <span class="hljs-string">&quot;/dev/gpiochip0&quot;</span>);

        <span class="hljs-comment">/*Open device: gpiochip0 for GPIO bank A */</span>
        fd = open(chrdev_name, <span class="hljs-number">0</span>);
        <span class="hljs-keyword">if</span> (fd == -<span class="hljs-number">1</span>) {
                ret = -errno;
                <span class="hljs-built_in">fprintf</span>(stderr, <span class="hljs-string">&quot;Failed to open %s\n&quot;</span>, chrdev_name);

                <span class="hljs-keyword">return</span> ret;
        }

        <span class="hljs-comment">/* request GPIO line: GPIO_A_14 */</span>
        req.lineoffsets[<span class="hljs-number">0</span>] = <span class="hljs-number">14</span>;
        req.flags = GPIOHANDLE_REQUEST_OUTPUT;
        <span class="hljs-built_in">memcpy</span>(req.default_values, &amp;data, <span class="hljs-keyword">sizeof</span>(req.default_values));
        <span class="hljs-built_in">strcpy</span>(req.consumer_label, <span class="hljs-string">&quot;led_gpio_a_14&quot;</span>);
        req.lines= <span class="hljs-number">1</span>;

        ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &amp;req);
        <span class="hljs-keyword">if</span> (ret == -<span class="hljs-number">1</span>) {
                ret = -errno;
                <span class="hljs-built_in">fprintf</span>(stderr, <span class="hljs-string">&quot;Failed to issue GET LINEHANDLE IOCTL (%d)\n&quot;</span>,
                        ret);
        }
        <span class="hljs-keyword">if</span> (close(fd) == -<span class="hljs-number">1</span>)
                perror(<span class="hljs-string">&quot;Failed to close GPIO character device file&quot;</span>);

        <span class="hljs-comment">/*Start led blinking */</span>
        <span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>) {

                data.values[<span class="hljs-number">0</span>] = !data.values[<span class="hljs-number">0</span>];
                ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &amp;data);
                <span class="hljs-keyword">if</span> (ret == -<span class="hljs-number">1</span>) {
                        ret = -errno;
                        <span class="hljs-built_in">fprintf</span>(stderr, <span class="hljs-string">&quot;Failed to issue %s (%d)\n&quot;</span>,
                                        <span class="hljs-string">&quot;GPIOHANDLE_SET_LINE_VALUES_IOCTL&quot;</span>, ret);
                }
                sleep(<span class="hljs-number">1</span>);
        }

        <span class="hljs-comment">/*release line */</span>
        ret = close(req.fd);
        <span class="hljs-keyword">if</span> (ret == -<span class="hljs-number">1</span>) {
                perror(<span class="hljs-string">&quot;Failed to close GPIO LINEHANDLE device file&quot;</span>);
                ret = -errno;
        }
        <span class="hljs-keyword">return</span> ret;
}

</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); left: 0px; top: -15px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>经过编译,可以成功的控制led5</p>

<p></p>

<p>至此Hello world完成!</p>

<p>对于新手建议参考一下</p>

<p><a href="https://wiki.st.com/stm32mpu/wiki/How_to_cross-compile_with_the_Developer_Package" target="_blank">How to cross-compile with the Developer Package</a></p>

<p>&nbsp;</p>

<p><b><font color="#5e7384">此内容由EEWORLD论坛网友<font size="3">bigbat</font>原创,如需转载或用于商业用途需征得作者同意并注明出处</font></b></p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

兰博 发表于 2020-3-26 15:51

<p><img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/onion/Onion--12.gif" width="50" />楼主的评测做的真好!!</p>

littleshrimp 发表于 2020-3-26 17:07

<p>不错,速度够快。</p>

chenzhufly 发表于 2020-3-26 23:11

<p>不错 不错 期待你们的大作</p>

我爱下载 发表于 2020-3-27 07:43

<p>学习了,学习了</p>

xinshuwei 发表于 2020-4-9 20:53

<p>&nbsp;编译不通过呀</p>

bigbat 发表于 2020-4-10 08:43

xinshuwei 发表于 2020-4-9 20:53
&nbsp;编译不通过呀

<p>这个程序是肯定能编译的,需要注意的是你机器的编译环境一定要正确!!!</p>

<p><span style="background-color:#ffffff; color:#333333">source /opt/st/stm32mp1/2.6-openstlinux-20-02-19/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi</span></p>

<p><span style="background-color:#ffffff; color:#333333">执行后按照操作步骤检查环境。还有就是:你如果不懂makefile文件编写请学习一下。</span></p>

<p><span style="background-color:#ffffff; color:#333333">以上还是不行,那就是人品问题了...</span></p>

xinshuwei 发表于 2020-5-12 22:38

bigbat 发表于 2020-4-10 08:43
这个程序是肯定能编译的,需要注意的是你机器的编译环境一定要正确!!!

source /opt/st/stm32mp1/2. ...

<p>搞定了,原来是编译器搞错了</p>
页: [1]
查看完整版本: STM32MP157A-DK1测评+HelloWorld与GPIO(2)