当前位置:   article > 正文

【运行在freertos上的microros 任何stm32平台】_microros stm32

microros stm32

文章目录

  • 前言
  • 一、工程下载
  • 二、使用步骤
    • 1.了解每个文件夹的作用
    • 2.移植到自己的工程
    • 3.运行!


前言

`本文主要分享一下如何快速在stm32f103或stm32系列的任意板子上运行microros的具体步骤。(所需要的文件已经生成好了)。
生成的步骤极其踩坑,是一段令人痛苦的回忆。
生成静态链接库的踩坑主要内容就是 所有资源都是外网,需要代理,如果网络不通畅所有的步骤都得重新来,尤其是在docker 容器运行时的代理配置,直接给我干吐血了…
好的废话不多说,此篇文章的只需要下载工程后,即可使用(对于stm32f103rct6),其他芯片的可通过cubemx软件选择对应芯片即可。
对于microros如何从源码开始编译可点击以下链接

microros部署教程
microros github源码
microros 官网

一、工程下载

链接:https://pan.baidu.com/s/1QUw-3e9ZpeAaA7Khyjd_Dg?pwd=iebe
提取码:iebe
–来自百度网盘超级会员V4的分享

二、使用步骤

1.了解每个文件夹的作用

microros2pc_test 用于开发板与linux端ros2通信测试功能包
microros_ws 构建静态链接库,agent等功能包的setup功能包 具体使用可参考microros官网
microros_agent_ws linux端运行microros的agent功能包
freertos_rosnode stm32工程文件,包含了静态链接 .a文件
在freertos_rosnode下的micro_ros_stm32cubemx_utils文件夹是极其重要的文件夹,一般不做修改,移植所需文件夹 。同时可参考其中的main.c文件如何编程microros

2.移植到自己的工程

打开stm32 cubemx,创建一个新的工程 (我以stm32f103rct6为例)

1.正常配置时钟树即可

2.rcc配置 HSE选择crystal

选择中间件 middleware,选择freertos。如下配置 选择v2版本 选择tasks and queues双击已存在的tasks
配置 stack size 3000 allocation static
在这里插入图片描述
3.配置usart:
mode 选择asynchronous
dma settings 点击add
rx mode选择circular
tx默认即可
两者优先级都为非常高
nvic settings 打开中断

配置图如下
在这里插入图片描述
4.sys配置
打开debug
timebase source 选择tim1

在这里插入图片描述
5.工程管理:
toolchan/ide 选择makefile
在这里插入图片描述
6.代码生成:
在这里插入图片描述
生成代码 打开工程所在位置,将百度网盘下载的工程中的micro_ros_stm32cubemx_utils文件夹复制到新生成的工程文件夹目录下
如图所示
在这里插入图片描述

使用你最常用的ide或者编辑器打开工程(我以clion为例,配置文件可复制.idea文件夹到新工程目录下):需要配置好工具链,如果没有配置,可参考稚晖君配置教程(clion)
编辑makefile文件:
将以下内容复制到 build the application之前

#######################################
# micro-ROS addons
#######################################
LDFLAGS += micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a
C_INCLUDES += -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include

# Add micro-ROS utils
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/custom_memory_manager.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_allocators.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_time.c

# Set here the custom transport implementation
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c

print_cflags:
   @echo $(CFLAGS)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述
最好按照cubemx语法规则放入注释之间,这样在cubemx软件新添配置后代码不会被覆盖

/* USER CODE BEGIN PM */

/* USER CODE END PM */
  • 1
  • 2
  • 3

将以下头文件复制到freertos.c文件中

#include "usart.h"
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include <rmw_microros/rmw_microros.h>
#include <std_msgs/msg/int32.h>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

再将StartDefaultTask()函数中的内容替换为以下内容

void StartDefaultTask(void *argument)
{
    /* USER CODE BEGIN StartDefaultTask */
    /* Infinite loop */
    // micro-ROS configuration

    rmw_uros_set_custom_transport(
      true,
      (void *) &huart1,
      cubemx_transport_open,
      cubemx_transport_close,
      cubemx_transport_write,
      cubemx_transport_read);

    rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
    freeRTOS_allocator.allocate = microros_allocate;
    freeRTOS_allocator.deallocate = microros_deallocate;
    freeRTOS_allocator.reallocate = microros_reallocate;
    freeRTOS_allocator.zero_allocate =  microros_zero_allocate;

    if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {
        printf("Error on default allocators (line %d)\n", __LINE__);
    }

    // micro-ROS app

    rcl_publisher_t publisher;
    std_msgs__msg__Int32 msg;
    rclc_support_t support;
    rcl_allocator_t allocator;
    rcl_node_t node;

    allocator = rcl_get_default_allocator();

    //create init_options
    rclc_support_init(&support, 0, NULL, &allocator);

    // create node
    rclc_node_init_default(&node, "cubemx_node", "", &support);

    // create publisher
    rclc_publisher_init_default(
      &publisher,
      &node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
      "cubemx_publisher");

    msg.data = 0;

    for(;;)
    {
      rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);
      if (ret != RCL_RET_OK)
      {
        printf("Error publishing (line %d)\n", __LINE__);
      }

      msg.data++;
      osDelay(10);
    }
    /* USER CODE END StartDefaultTask */
}
  • 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
  • 60
  • 61
  • 62

添加syscalls.c:
在工程目录的core/src目录下新建syscalls.c文件,并复制以下内容到新建文件中

/**
*****************************************************************************
**
**  File        : syscalls.c
**
**  Author        : Auto-generated by System workbench for STM32
**
**  Abstract    : System Workbench Minimal System calls file
**
**                   For more information about which c-functions
**                need which of these lowlevel functions
**                please consult the Newlib libc-manual
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed “as is,” without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**   1. Redistributions of source code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**   2. Redistributions in binary form must reproduce the above copyright notice,
**      this list of conditions and the following disclaimer in the documentation
**      and/or other materials provided with the distribution.
**   3. Neither the name of STMicroelectronics nor the names of its contributors
**      may be used to endorse or promote products derived from this software
**      without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

// the code was modified by Fynn Boyer

/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>


/* Variables */
//#undef errno
extern int errno;
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));

register char * stack_ptr asm("sp");

char *__env[1] = { 0 };
char **environ = __env;

extern char _estack;  // see ld file
extern char _Min_Stack_Size;  // see ld file

/* Functions */
void initialise_monitor_handles()
{
}

int _getpid(void)
{
    return 1;
}

int _kill(int pid, int sig)
{
    errno = EINVAL;
    return -1;
}

void _exit (int status)
{
    _kill(status, -1);
    while (1) {}        /* Make sure we hang here */
}

__attribute__((weak)) int _read(int file, char *ptr, int len)
{
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        *ptr++ = __io_getchar();
    }

    return len;
}

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        __io_putchar(*ptr++);
    }
    return len;
}

caddr_t _sbrk(int incr) {
    extern char __heap_start__ asm("end");  // Defined by the linker.
    static char *heap_end;
    char *prev_heap_end;

    if (heap_end == NULL) heap_end = &__heap_start__;

    prev_heap_end = heap_end;

    if (heap_end + incr > &_estack - _Min_Stack_Size) {
        __asm("BKPT #0\n");
        errno = ENOMEM;
        return (caddr_t)-1;

    }

    heap_end += incr;
    return (caddr_t)prev_heap_end;

}

int _close(int file)
{
    return -1;
}


int _fstat(int file, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}

int _isatty(int file)
{
    return 1;
}

int _lseek(int file, int ptr, int dir)
{
    return 0;
}

int _open(char *path, int flags, ...)
{
    /* Pretend like we always fail */
    return -1;
}

int _wait(int *status)
{
    errno = ECHILD;
    return -1;
}

int _unlink(char *name)
{
    errno = ENOENT;
    return -1;
}

int _times(struct tms *buf)
{
    return -1;
}

int _stat(char *file, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}

int _link(char *old, char *new)
{
    errno = EMLINK;
    return -1;
}

int _fork(void)
{
    errno = EAGAIN;
    return -1;
}

int _execve(char *name, char **argv, char **env)
{
    errno = ENOMEM;
    return -1;
}
  • 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
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209

再编辑makefile文件,加入syscalls.c文件路径

######################################
source
######################################
C sources
下加入

Core/Src/syscalls.c \
  • 1

最后编译即可
在这里插入图片描述
最后下载固件到开发板上即可。

3.运行!

1.将agent功能包上传到linux中(linux需安装ros2系统,版本为foxy)
2.最好编译一下,source功能包后运行以下命令

ros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyUSB0
  • 1

其中ttyUSB0要根据开发板连接的代号来修改
注意 一定要先运行上述命令后再连接开发板
效果如下
在这里插入图片描述
出现以下情况后连接开发板,会出现以下情况
在这里插入图片描述
说明开发板与ros2连接成功
再运行`

ros2 topic echo /cubemx_publisher
  • 1

可查看microros发布的信息
如图
在这里插入图片描述
运行以下命令 可查看节点信息

rqt_graph
  • 1

在这里插入图片描述
说明stm32f103的节点已启动!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/661248
推荐阅读
相关标签
  

闽ICP备14008679号