• arduino - 用 arduino zero 开发板来学习理解arduino软件编程细节


    arduino - 用 arduino zero 开发板来学习理解arduino软件编程细节

    概述

    手头有个固件, 使用了arduino Mega2560 开发板来做控制.
    但是我是arduino新手, Mega2560并不能做单步调试. 光看代码不管用啊, 要单步调试才能深入理解代码实现逻辑.
    整了一块arduino zero开发板, 可以在 Arduino IDE 单步调试, 这就好多了.
    单步调试后, 通过实验, 就可以理解很多arduino编程的细节问题了.

    笔记

    实验环境

    Arduino IDE 2.0.3 + arduino zero

    不是所有的arduino工程都能在同一块开发板上编译过

    每块开发板都包含了特定的库, 可能这个库由于MCU的原因(e.g. AVR MCU vs ARM M0 MCU), 并没有包含进开发板的库, 导致编译不过.
    e.g. _delay_loop_2 声明在 util/delay_basic.h 中, 头文件路径为 C:\Users\me\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\util

    在mega2560开发板的工程上, 可以看到为了延时, 调用_delay_loop_2()
    但是arduino zero是ARM M0的MCU, 所以就没有这个函数. 需要看官方例子, 找到延时函数, 进行替代.
    打开官方例子工程, 将板子选为arduino zero, 打开有延时操作的例子, e.g. Blink工程, 单步delay()函数, 在实验里面, 可以看到微妙延时的函数. delayMicroseconds(), 替换掉就好.

    还有些寄存器定义, 是和MCU相关的. e.g. SREG 这个在avr MCU中才有, 在ARM MCU中是没有的, 这就移植不了, 只能在mega2560或arduino nano every上运行. 因为这2款开发板不能单步, 只能用arduino zero模拟运行(将编译不过的实现注释掉), 将实现逻辑理清楚. 然后在avr mcu 的板子上实际测试.

    为啥arduino编程都是在setup()和loop()函数中实现代码?

    这个单步一下就知道, 先在setup()和loop()入口下断点, 跑起来, 单步出了这2个函数就看到了.

    /*
      Copyright (c) 2015 Arduino LLC.  All right reserved.
    
      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
      License as published by the Free Software Foundation; either
      version 2.1 of the License, or (at your option) any later version.
    
      This library is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      See the GNU Lesser General Public License for more details.
    
      You should have received a copy of the GNU Lesser General Public
      License along with this library; if not, write to the Free Software
      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    */
    
    #define ARDUINO_MAIN
    #include "Arduino.h"
    
    // Weak empty variant initialization function.
    // May be redefined by variant files.
    void initVariant() __attribute__((weak));
    void initVariant() { }
    
    extern USBDeviceClass USBDevice;
    
    // Initialize C library
    extern "C" void __libc_init_array(void);
    
    /*
     * \brief Main entry point of Arduino application
     */
    int main( void )
    {
      init();
    
      __libc_init_array();
    
      initVariant();
    
      delay(1);
    #if defined(USBCON)
      USBDevice.init();
      USBDevice.attach();
    #endif
    
      setup();
    
      for (;;)
      {
        loop();
        if (arduino::serialEventRun) arduino::serialEventRun();
      }
    
      return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    可以看到arduino IDE自己实现的main(), 系统初始化init()之后, 调用用户自己的初始化函数setup(), 然后在一个循环中调用用户自己的循环处理函数loop().

    arduino这么搞, 对于用户来说, 方便倒是方便, 但是不灵活. 只能处理一些实时性不强, 没有并行处理, 只有顺序处理的任务.
    对于产品来说, 还是不能用arduino IDE的这种编程方式, 还是要用没有封装的, 传统的MCU编程流程.

    END

  • 相关阅读:
    SEO优化:提升网站排名和流量的终极指南
    iOS 关于UIWebView常见使用方法
    南卡A2降噪耳机和vivo TWS2蓝牙耳机哪个好?vivo TWS2和南卡降噪蓝牙耳机测评
    洛谷P3369 【模板】普通平衡树 红黑树实现
    进程间通信之共享内存
    Linux 内存管理 页回收和swap机制
    深入浅出:Objective-C中使用MWFeedParser下载豆瓣RSS
    算法设计与分析基础-重要的问题类型
    一文剖析 PolarDB HTAP 的列存数据压缩
    go语言基础 -- 面向对象编程
  • 原文地址:https://blog.csdn.net/LostSpeed/article/details/128520030