MiniFly微型四轴学习与开发日志(四)

2023-05-16

文章目录

    • 任务创建和删除 API 函数
    • 任务调度器开启函数分析
    • 临界区
    • atkp.c

任务创建和删除 API 函数

FreeRTOS 最基本的功能就是任务管理,而任务管理最基本的操作就是创建和删除任务,FreeRTOS 的任务创建和删除 API 函数如表所示:
在这里插入图片描述
遥控器固件程序基本是使用xTaskCreate()动态创建一个任务,使用vTaskDelete()来删除一个任务。
在这里插入图片描述
1、函数 xTaxkCreate()

此函数用来创建一个任务,任务需要 RAM 来保存与任务有关的状态信息(任务控制块),任务也需要一定的 RAM 来作为任务堆栈。如果使用函数 xTaskCreate()来创建任务的话那么这些所需的 RAM 就会自动的从 FreeRTOS 的堆中分配,因此必须提供内存管理文件,默认我们使用heap_4.c 这个内存管理文件,而且宏 configSUPPORT_DYNAMIC_ALLOCATION 必须为 1。新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行,不管在任务调度器启动前还是启动后,都可以创建任务。函数原型如下:

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
						const char * const pcName,
						const uint16_t usStackDepth,
						void * const pvParameters,
						UBaseType_t uxPriority,
						TaskHandle_t * const pxCreatedTask )

参数:
pxTaskCode: 任务函数。
pcName: 任务名字,一般用于追踪和调试,任务名字长度不能超过configMAX_TASK_NAME_LEN。
usStackDepth: 任务堆栈大小,注意实际申请到的堆栈是 usStackDepth 的 4 倍。其中空闲任务的任务堆栈大小为 configMINIMAL_STACK_SIZE。
pvParameters: 传递给任务函数的参数。
uxPriotiry: 任务优先级,范围 0~ configMAX_PRIORITIES-1。
pxCreatedTask: 任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他 API 函数可能会使用到这个句柄。

返回值:
pdPASS: 任务创建成功。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY: 任务创建失败,因为堆内存不足!

2、函数vTaskDelete()

删除一个用函数 xTaskCreate()或者 xTaskCreateStatic()创建的任务,被删除了的任务不再存在,也就是说再也不会进入运行态。任务被删除以后就不能再使用此任务的句柄!如果此任务是使用动态方法创建的,也就是使用函数 xTaskCreate()创建的,那么在此任务被删除以后此任务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当调用函数 vTaskDelete()删除任务以后必须给空闲任务一定的运行时间。
此函数原型如下:

vTaskDelete( TaskHandle_t xTaskToDelete )

参数:
xTaskToDelete: 要删除的任务的任务句柄

返回值: 无

在固件程序创建任务函数startTask()中,动态创建完任务后,任务删除开始:

vTaskDelete(startTaskHandle);									/*删除开始任务*/

任务调度器开启函数分析

xTaskCreate(startTask, "START_TASK", 100, NULL, 2, &startTaskHandle);/*创建起始任务*/
vTaskStartScheduler();/*开启任务调度*/

例程中是在 main()函数中先创建一个开始任务 startTask,后面紧接着调用函数 vTaskStartScheduler()。这个函数的功能就是开启任务调度器的,这个函数在文件 tasks.c
中有定义,缩减后的函数代码如下:

	void vTaskStartScheduler( void )
	{
		BaseType_t xReturn;
		xReturn = xTaskCreate( prvIdleTask, (1)
								"IDLE", configMINIMAL_STACK_SIZE,
								( void * ) NULL,
								( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
	&xIdleTaskHandle );
		#if ( configUSE_TIMERS == 1 ) //使用软件定时器使能
		{
			if( xReturn == pdPASS )
			{
				xReturn = xTimerCreateTimerTask(); (2)
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		#endif /* configUSE_TIMERS */
		if( xReturn == pdPASS ) //空闲任务和定时器任务创建成功。
		{
			portDISABLE_INTERRUPTS(); (3)
			#if ( configUSE_NEWLIB_REENTRANT == 1 ) //使能 NEWLIB
			{
				_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
			}
		#endif /* configUSE_NEWLIB_REENTRANT */
		xNextTaskUnblockTime = portMAX_DELAY;
		xSchedulerRunning = pdTRUE; (4)
		xTickCount = ( TickType_t ) 0U;
		portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); (5)
		if( xPortStartScheduler() != pdFALSE ) (6)
		{
	//如果调度器启动成功的话就不会运行到这里,函数不会有返回值的
		}
		else
		{
	//不会运行到这里,除非调用函数 xTaskEndScheduler()。 
		} 
		}
	else
	{
	//程序运行到这里只能说明一点,那就是系统内核没有启动成功,导致的原因是在创建
	//空闲任务或者定时器任务的时候没有足够的内存。
	configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY );
	}
	//防止编译器报错,比如宏 INCLUDE_xTaskGetIdleTaskHandle 定义为 0 的话编译器就会提
	//示 xIdleTaskHandle 未使用。
	( void ) xIdleTaskHandle;
	}

(1) 创建空闲任务,如果使用静态内存的话使用函数 xTaskCreateStatic()来创建空闲任务,优先级为 tskIDLE_PRIORITY,宏 tskIDLE_PRIORITY 为 0,也就是说空闲任务的优先级为最低。
(2) 如果使用软件定时器的话还需要通过函数 xTimerCreateTimerTask()来创建定时器服务任务。定时器服务任务的具体创建过程是在函数 xTimerCreateTimerTask()中完成的。
(3) 关闭中断,在 SVC 中断服务函数 vPortSVCHandler()中会打开中断。
(4) 变量 xSchedulerRunning 设置为 pdTRUE,表示调度器开始运行。
(5) 当宏 configGENERATE_RUN_TIME_STATS 为 1 的时候说明使能时间统计功能,此时需要用户实现宏 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS,此宏用来配置一个定时器/计数器。
(6) 调用函数 xPortStartScheduler()来初始化跟调度器启动有关的硬件,比如滴答定时器、FPU 单元和 PendSV 中断等等。

临界区

/*创建任务*/
void startTask(void *param)
{
	taskENTER_CRITICAL();	/*进入临界区*/
	
	xTaskCreate(radiolinkTask, "RADIOLINK", 100, NULL, 6, &radiolinkTaskHandle);/*创建无线连接任务*/
	
	xTaskCreate(usblinkTxTask, "USBLINK_TX", 100, NULL, 5, NULL);	/*创建usb发送任务*/
	xTaskCreate(usblinkRxTask, "USBLINK_RX", 100, NULL, 5, NULL);	/*创建usb接收任务*/
	
	xTaskCreate(commanderTask, "COMMANDER", 100, NULL, 4, NULL);	/*创建飞控指令发送任务*/
	
	xTaskCreate(keyTask, "BUTTON_SCAN", 100, NULL, 3, NULL);		/*创建按键扫描任务*/
	
	xTaskCreate(displayTask, "DISPLAY", 200, NULL, 1, NULL);		/*创建显示任务*/
	
	xTaskCreate(configParamTask, "CONFIG_TASK", 100, NULL, 1, NULL);/*创建参数配置任务*/
	
	xTaskCreate(radiolinkDataProcessTask, "DATA_PROCESS", 100, NULL, 6, NULL);	/*创建无线通信数据处理任务*/
	xTaskCreate(usblinkDataProcessTask, "DATA_PROCESS", 100, NULL, 6, NULL);	/*创建USB通信数据处理任务*/
	
	vTaskDelete(startTaskHandle);									/*删除开始任务*/
	
	taskEXIT_CRITICAL();	/*退出临界区*/
}

临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。FreeRTOS 在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断。FreeRTOS 系统本身就有很多的临界段代码,这些代码都加了临界段代码保护,在写自己的用户程序的时候有些地方也需要添加临界段代码保护
FreeRTOS 与临界段代码保护有关的函数有 4 个 : taskENTER_CRITICAL() 、taskEXIT_CRITICAL() 、 taskENTER_CRITICAL_FROM_ISR() 和
taskEXIT_CRITICAL_FROM_ISR(),这四个函数其实是宏定义,在 task.h 文件中有定义。这四个函数的区别是前两个是任务级的临界段代码保护,后两个是中断级的临界段代码保护。
taskENTER_CRITICAL()和 taskEXIT_CRITICAL()是任务级的临界代码保护,一个是进入临
界段,一个是退出临界段,这两个函数是成对使用的,这函数的定义如下:

#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()

而 portENTER_CRITICAL()和 portEXIT_CRITICAL()也是宏定义,在文件 portmacro.h 中有定义,如下:

#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()

函数 vPortEnterCritical()和 vPortExitCritical()在文件 port.c 中,函数如下:

void vPortEnterCritical( void )
{
	portDISABLE_INTERRUPTS();
	uxCriticalNesting++;
	if( uxCriticalNesting == 1 )
	{
		configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
	} 
}

void vPortExitCritical( void )
{
	configASSERT( uxCriticalNesting );
	uxCriticalNesting--;
	if( uxCriticalNesting == 0 )
	{
		portENABLE_INTERRUPTS();
	} 
}

可以看出在进入函数 vPortEnterCritical()以后会首先关闭中断,然后给变量 uxCriticalNesting加一,uxCriticalNesting 是个全局变量,用来记录临界段嵌套次数的。函数 vPortExitCritical()是退出临界段调用的,函数每次将 uxCriticalNesting 减一,只有当 uxCriticalNesting 为 0 的时候才会调用函数 portENABLE_INTERRUPTS()使能中断。这样保证了在有多个临界段代码的时候不会因为某一个临界段代码的退出而打乱其他临界段的保护,只有所有的临界段代码都退出以后才会使能中断

atkp.c

aktp.c 主要实现解析四轴通过 radiolink.c 返回的应答包并通过 usblink.c 转发给上位机,上位机通过 usblink.c 发下来的数据包 将 通 过 radiolink 转发给四轴,即的 radiolinkDataProcessTask 和 usblinkDataProcessTask。
在这里插入图片描述

float plane_yaw,plane_roll,plane_pitch;
float plane_bat;
u8 rssi;

/*atkp解析*/
static void atkpAnalyze(atkp_t *p)
{
	if(p->msgID == UP_STATUS)
	{
		plane_roll = (s16)(*(p->data+0)<<8)|*(p->data+1);
		plane_roll = plane_roll/100;
		plane_pitch = (s16)(*(p->data+2)<<8)|*(p->data+3);
		plane_pitch = plane_pitch/100;
		plane_yaw = (s16)(*(p->data+4)<<8)|*(p->data+5);
		plane_yaw = plane_yaw/100;
	}
	else if(p->msgID == UP_POWER)
	{
		plane_bat = (s16)(*(p->data+0)<<8)|*(p->data+1);
		plane_bat = plane_bat/100;
	}
	else if(p->msgID == UP_REMOTOR)	
	{
		switch(p->data[0])
		{
			case ACK_MSG:
				miniFlyMsgACKProcess(p);
				break;
		}
	}
	else if(p->msgID == UP_RADIO)
	{
		radioConfig_t radio;
		switch(p->data[0])
		{
			case U_RADIO_RSSI:
				rssi = p->data[1];
				break;
			
			case U_RADIO_CONFIG:
				memcpy(&radio, p->data+1, sizeof(radio));
				setMatchRadioConfig(&radio);
				break;
		}
	}
}

/*无线连接数据处理任务*/
void radiolinkDataProcessTask(void *param) 
{
	atkp_t p;
	while(1)
	{
		radiolinkReceivePacketBlocking(&p); /*接收四轴上传的数据,包括四轴数据和遥控器数据*/
		atkpAnalyze(&p);
		usblinkSendPacket(&p);	/*把接收到的四轴数据发送到上位机*/
		vTaskDelay(1);
	}
}

/*USB连接数据处理任务*/
void usblinkDataProcessTask(void *param)
{
	atkp_t p;
	while(1)
	{
		usblinkReceivePacketBlocking(&p);	/*接收上位机发送的数据*/
		atkpAnalyze(&p);
		radiolinkSendPacket(&p);
	}
}

在这里插入图片描述
遥控器与四轴 NRF51822 无线通信,无线通信本身自带了 CRC16 校验,传输是可靠的,因此直接可以传输 ATKP 数据包。Usblink 链路通信是串口方式,为了区分一帧数据和保证传输可靠性,所以需要加上帧头和校验。
当遥控器与四轴 NRF51822 通信成功后,遥控器会不断发送数据包给 NRF51822,NRF51822 接收并解析,然后再转发给 STM32F11,STM32F411 接收到后会立即向 NRF51822返回一条数据包,一应一答模式。NRF51822 与 STM32F411 通信使用的串口方式,数据格式跟 usblink 链路数据格式一样。如果遥控器连接了上位机,遥控器会将接收到的应答数据包先解析,解析完成后转发给上位机。同样,上位机发下来的数据遥控器也会先解析再转发给四轴。Radiolink 链路中,遥控器定周期发送控制命令,四轴定周期返回姿态和其他数据。
Usblink 链路中,如果四轴连接了上位机,四轴会定周期返回姿态和其他数据给上位机;如果遥控器连接了上位机,遥控器将四轴返回的数据转发给上位机。上位机同一时刻只能连接一个 Usblink 链路。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MiniFly微型四轴学习与开发日志(四) 的相关文章

  • 彻底掌握FreeRTOS中的任务

    FreeRTOS是个操作系统 xff0c FreeRTOS的任务 task 其实就是像我们电脑中的一个独立程序 xff0c 表现在源码中 xff0c 其实就是一个函数 本文从学会使用任务 task 到理解逐步深入 参考资料 xff1a Ma
  • FreeRTOS任务之调度器中的三种调度算法

    本文主要讲解FreeRTOS调度器中的三种调度算法 xff1a 基于时间片的抢占式调度 不带时间片的抢占式调度和协同调度 前导文章 xff1a FreeRTOS全解析 3 任务 xff08 task xff09 参考资料 xff1a Mas
  • 彻底理解FreeRTOS中的队列(Queue)

    队列 xff08 Queue xff09 提供了任务与任务之间通信的机制 在这样的场景 xff1a 一个或多个其他的任务产生数据 xff0c 主任务要依次处理数据 xff0c 队列就显得非常有用了 参考资料 xff1a Mastering
  • 简单路由器DIY

    一 关于路由器 路由器 xff08 Route xff09 是一种负责寻径的系统 xff0c 在互连网络中从多条路径中寻找通讯量最少的一条网络路径提供给用户通信 它使用寻径协议来获得网络信息 xff0c 采用基于 34 寻径矩阵 34 的寻
  • DOS那一代的程序员现在都干嘛呢?

    亿友论坛 DOS那一代的程序员现在都干嘛呢 xff1f xff08 几年前的老帖子 xff09 作者 xff1a 包子夹蛋 发布时间 xff1a 2005 5 10 14 01 00 DOS那一代的程序员现在都干嘛呢 xff1f xff08
  • switch case的用法

    switch case的用法如下 1 Switch用在编程中 xff0c 如C语言中它经常跟Case一起使用 xff0c 是一个判断选择代码 其功能就是控制流程流转的 直线翻译 xff1a switch语句 xff0c 即 切换 语句 xf
  • Rust嵌入式:只使用寄存器为STM32点灯;从查手册开始

    为什么是 只使用寄存器 网上很多教程都是直接调用对应芯片的HAL库 xff0c 让初学者认为操作都被Rust嵌入式开源组封装好了 xff0c 直接调就好 这在目前Rust嵌入式生态还不成熟的情况下可能是个误解 实际上Rust嵌入式有自己独特
  • epoll_wait 中timeout参数的损耗和如何避免

    ccd 100qps xff0c dcc 4wqps
  • ubuntu和windows双系统默认启动顺序

    在安装了双系统后 xff0c 一般的默认启动ubuntu xff0c 但我实际可能使用windows会比较多 xff0c 为解决这个问题 xff0c 必须要更改默认顺序 xff0c 以达到方便我们使用的效果 方法 xff1a 开机界面会有显
  • 深度学习优化算法

    深度学习各类优化器 借用古代炼丹的一些名词 xff0c 我们可以把训练模型中的数据比做炼丹药材 xff0c 模型比做炼丹炉 xff0c 火候比做优化器 那么我们知道 xff0c 同样的药材同样的炼丹炉 xff0c 但是火候不一样的话 xff
  • yolov3

    YOLOv3 YOLOv3的总体网络架构图 可根据官方代码中的yolov3 cfg进行一一对应 xff0c 标号 0 0 0 是第一个 convolutional Darknet 53 和DarkNet 19一样 xff0c 同样下采样32
  • SSH远程连接报错:kex_exchange_identification: Connection closed by remote host

    突然出现问题 xff1a kex exchange identification Connection closed by remote host 解决方法 删除known hosts xff0c 重启终端即可
  • Dronekit——Introduction

    Dronekit Introduction 参考 xff1a http python dronekit io about overview html 关于Dronekit DroneKit Python允许开发人员创建 在板载协同计算机上运
  • Run dronekit scripts by SITL on Linux 执行dronekit 脚本在Linux系统下模拟飞行

    参考 xff1a http ardupilot org dev docs setting up sitl on linux html Overview The SITL simulator allows you to run Plane C
  • SLAM从入门到放肆——SLAM简述

    SLAM 同时定位与建图 xff08 simultaneous localization and mapping xff0c SLAM xff09 是自动驾驶与增强现实领域中常用的技术 主要研究装置通过各种传感器在未知环境中的感知与定位问题
  • 关于NoDriveTypeAutoRun的键值

    最近在写一个修改注册表的驱动 xff0c 只是为了好玩 xff0c 也算是一个恶搞驱动吧 xff01 遇到一个问题 xff0c 花了我差不多两天的时间的 xff0c 详情往下看 写这篇文章 xff0c 为了记住这个教训 xff0c 一个提供
  • 闭包的实现原理和作用、以及内存泄露

    一 闭包的实现原理和作用 xff0c 可以列举几个开发中闭包的实际应用 1 闭包的概念 xff1a 指有权访问另一个函数作用域中的变量的函数 xff0c 一般情况就是在一个函数中包含另一个函数 2 闭包的作用 xff1a 访问函数内部变量
  • PX4 SITL Gazebo 仿真时 libgazebo_multirotor_base_plugin 插件运行时出错

    PX4 SITL Gazebo 仿真时 libgazebo multirotor base plugin 插件运行时出错 问题描述原因分析解决办法总结 问题描述 在 Gazebo 中进行 PX4 的软件在环仿真时 xff0c 执 make
  • Jetson AGX Xavier 正确上手教程

    概览 1 开机1 1 配件1 2 需要准备的器材1 3 连接设备 2 刷机2 1 更换主机的 apt get 源2 2 在主机上安装 SDK ManagerStep 1Step xff12 Step xff13 烧录 OS 镜像安装 SDK
  • Matplotlib绘图显示缺少中文字体-RuntimeWarning: Glyph 8722 missing from current font.

    pyplot 并不默认支持中文显示 xff0c 也没有自带中文字体 xff0c 因此需要自行下载所需字体 xff0c 并修改 rcParams 参数来显示中文 下面以 SimHei xff08 黑体 xff09 字体为例进行说明 说明 xf

随机推荐

  • Win10 系统安装 Linux 子系统教程(WSL2 + Ubuntu 20.04 + Gnome 桌面 )

    Win10 系统安装 Linux 子系统教程 WSL2 43 Ubuntu 20 04 43 Gnome 桌面 xff09 1 WSL 简介1 1 什么是 WSL xff1f 1 2 WSL1 与 WSL2 2 安装 WSL2 1 安装 W
  • Ubuntu 桌面美化教程

    将 Ubuntu 桌面美化成 Mac 风格 xff0c 效果如下 1 美化任务栏 Ubuntu 20 04 默认的任务栏在桌面左侧 xff0c 不使用时会自动隐藏 安装 plank dock 工具可以在桌面底部设置一个常驻任务栏 xff08
  • Git 图解教程

    Git 图解教程 基础篇 git 简介 安装与配置 安装 git 配置 git 创建版本库 跟踪修改 提交修改 比较文件 辅助命令 创建分支 合并分支 git merge git rebase 高级篇 移动提交记录 分离的 HEAD 相对引
  • Doxygen + Graphviz 代码自动化分析

    Doxygen 43 Graphviz 代码自动化分析 目录 1 实际需求2 工具简介3 使用说明4 代码注释规范5 参考 1 实际需求 在开发程序时 xff0c 需要编写对应的说明文档 在阅读现有的项目源代码时 xff0c 需要梳理函数间
  • Microsoft Learn: Docker入门教程

    Microsoft Learn Docker入门教程 1 Introduction2 What is Docker3 How Docker images work4 How Docker containers work5 When to u
  • 将kitti数据集中的velodyne points转换为ROS bag文件

    kitti数据集中包含了相机图像 激光扫描得到的点云信息 高精度GPS测量信息和IMU加速度信息 xff0c 用于移动机器人与自动驾驶方面的研究 如下为数据采集平台示意图 kitti数据集中的激光扫描数据是以二进制文件形式存储的 xff0c
  • 使用 Dockerfile 创建一个简单的容器

    Dockerfile Dockerfile 是用于指导 docker 创建自定义 image 的一系列指令 xff0c 是用于创建 image 的蓝图 现在有一个简单的 node 项目 其中Dockerfile 是后面加的 xff0c 初始
  • 导航英语专业词汇——不停更新

    惯性导航 inertia 惯性INS 惯性导航系统GINS 平台惯性导航系统SINS 捷联惯性导航系统IMU 惯性导航元件gyroscope 陀螺仪accelerometer 加速度计 SLAM 词汇词性意思 导航中用 SLAM词组同步定位
  • 不止于linux SSH 基本用法-正反向代理-内外网穿透

    最近小伙伴们纷纷进了实验室 xff0c 就冒出了一系列关于控制远程机器的问题 xff0c 我觉得我还是有必要科普一下的 约定 本文不讲解 Linux 使用方法 xff0c 只讲解机器之间的通信方法 下文中行首的 local 以及 remot
  • 传感器数据滤波算法

    嵌入式应用中 xff0c 系统获取的传感器数据通常不能够直接供应用使用 xff08 存在噪声干扰 xff1a 低频噪声或高频噪声 xff09 xff0c 一般通过一种或者多种滤波算法结合 xff0c 对原始数据进行滤波处理 xff0c 在保
  • 写了一个生成reStructuredText表格的vim插件

    vim官网上有一个rst table xff0c 不过不太好用 xff0c 最大的问题是对中文的支持有欠缺在 f后 xff0c 中文所在的cell的长度会计算错误 扫了一眼它的源码使用了python写的插件 xff0c 所以我就心血来潮也想
  • Ubuntu 16.04 一系列软件安装命令,包括QQ、搜狗、Chrome、vlc、网易云音乐安装方法

    1 简介 Ubuntu 16 04安装完后 还需要做一些配置才能愉快的使用 包括添加软件源 安装搜狗输入法 Chrome浏览器 网易云音乐 配置快捷键 安装git等等 下面就跟着我来配置吧 just do it 2 版本选择 如果你是小白
  • 从入门到放弃之生产环境基于Kubernetes V1.21.10搭建高可用集群

    1 资源规划 名称系统配置IP组件k8s master01CentOS 7 94核8G 500G存储172 16 97 27kube apiserver lt br gt kube controller manager lt br gt k
  • ros c++ 开发错误“集锦”

    集锦 xff0c 才能经常回放 1 error s getMD5Sum is not a member2 ROS datatype md5sum错误 持续更新 1 error s getMD5Sum is not a member 目前观测
  • 嵌入式ARM算法移植与优化

    目录 一 算法优化指导思想 1 算法优化基本原则 2 算法优化方法 二 编译器优化 1 xff0c 函数内联 2 xff0c 消除公共子表达式 3 xff0c 循环展开 4 xff0c GCC优化选项 5 xff0c ARMCC优化选项 三
  • OV2640摄像头驱动与应用代码

    目录 一 摄像头基础 1 1 OV2640参数 1 2 视场角与镜头 二 OV2640驱动 三 OV2640视频接入
  • ubuntu16.04常用软件安装

    目录 1 办公软件 xff1a WPS 2 文本比较工具 Meld 3 版本管理 xff1a git 4 安装wine 5 安装常用库 6 配置阿里源 7 vim 8 OpenCV 9 QT 10 VSCode 11 gparted 1 办
  • RK1109 NPU算法测试demo

    目录 一 矩阵乘法测试 二 测试结果 一 矩阵乘法测试 通过一个简单的矩阵乘法 xff0c 和L2距离计算来测试NPU计算性能与启动NPU的一般方法 具体代码如下 xff1a Example Calculate x y 2 using Ma
  • VS2015远程连接虚拟机

    目录 一 安装VC Linux exe 二 打开VS 选择新建项目 三 配置VS 四 创建项目 一 安装VC Linux exe 下载地址 xff1a 二 打开VS 选择新建项目 三 配置VS 打开VS xff0c 菜单栏点击工具 gt 选
  • MiniFly微型四轴学习与开发日志(四)

    文章目录 任务创建和删除 API 函数任务调度器开启函数分析临界区atkp c 任务创建和删除 API 函数 FreeRTOS 最基本的功能就是任务管理 xff0c 而任务管理最基本的操作就是创建和删除任务 xff0c FreeRTOS 的