FreeRTOS系列|任务创建和删除

2023-05-16

1. 任务创建和删除API函数

  • xTaskCreate()函数:动态创建一个新的任务,每个任务都需要RAM来保存任务状态(任务控制块+任务栈),此接口采用动态分配内存资源
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,	//任务函数(函数名)
                       const char *const pcName,	//任务名称(字符串)
                       unsigned short usStackDepth,	//任务堆栈大小
                       void *pvParameters,			//传递给任务函数的参数
                       UBaseType_t uxPriority,		//任务优先级
                       TaskHandle_t *pxCreatedTask);//任务句柄
返回值:pdPASS:创建成功
	   errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:堆空间不足,失败
/*注意:configSUPPORT_DYNAMIC_ALLOCATION 必须置为1*/

  • xTaskCreateStatic()函数:静态创建一个新的任务,每个任务都需要RAM来保存任务状态(任务控制块+任务栈),此接口采用静态分配内存资源
TaskHandle_t xTaskCreateStatic(TaskFunction_t pvTaskCode,//任务函数(函数名)
                               const char *const pcName, //任务名称(字符串)
                               uint32_t ulStackDepth,	 //任务堆栈大小
                               void *pvParameters,		 //传递给任务函数的参数
                               UBaseType_t uxPriority,	 //任务优先级
                               StackType_t *const puxStackBuffer, //任务堆栈
                               StaticTask_t *const pxTaskBuffer);//任务控制块
返回值:NULL:任务创建失败
	   其他值:任务句柄
/*注意:configSUPPORT_STATIC_ALLOCATION 必须置为1*/

  • 任务删除函数
函数原型:void vTaskDelete(TaskHandle_t xTaskToDelete)
参    数:xTaskToDelete 要删除的任务的任务句柄
返 回 值:无

2. 任务创建和删除函数源码分析

2.1 FreeRTOS任务创建函数源码分析
BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
						const char * const pcName,
						const uint16_t usStackDepth,
						void * const pvParameters,
						UBaseType_t uxPriority,
						TaskHandle_t * const pxCreatedTask )
{
	TCB_t *pxNewTCB;
	BaseType_t xReturn;
			
	#define portSTACK_GROWTH	//(-1)表示满减栈
	#if( portSTACK_GROWTH > 0 ){
	}
	#else{ /* portSTACK_GROWTH */
		StackType_t *pxStack;
		/* 任务栈内存分配*/
		pxStack = ( StackType_t *) pvPortMalloc(((( size_t) usStackDepth ) * sizeof( StackType_t))); 
		if( pxStack != NULL ){
			/* 任务控制块内存分配 */
			pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); 
			if( pxNewTCB != NULL ){
				/* 赋值栈地址 */
				pxNewTCB->pxStack = pxStack;
			}
			else{
				/* 释放栈空间 */
				vPortFree( pxStack );
			}
		}
		else{
			/* 没有分配成功 */
			pxNewTCB = NULL;
		}
	}
	#endif /* portSTACK_GROWTH */

	if( pxNewTCB != NULL )
	{
		/* 新建任务初始化 */
		prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
		/* 把任务添加到就绪列表中 */
		prvAddNewTaskToReadyList( pxNewTCB );
		xReturn = pdPASS;
	}
	else{
		xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
	}

	return xReturn;
}

2.2 任务初始化函数源码分析
static void prvInitialiseNewTask(TaskFunction_t			pxTaskCode,
								 const char * const 	pcName,
								 const uint32_t 		ulStackDepth,
								 void * const 			pvParameters,
								 UBaseType_t 			uxPriority,
								 TaskHandle_t * const 	pxCreatedTask,
								 TCB_t *				pxNewTCB,
								 const MemoryRegion_t * const xRegions ){
	StackType_t *pxTopOfStack;
	UBaseType_t x;

	/* 计算栈顶的地址 */
	#if( portSTACK_GROWTH < 0 ){
		/* 把栈空间的高地址分配给栈顶 */
		pxTopOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 );
		/* 栈对齐----栈要8字节对齐 */
		pxTopOfStack = (StackType_t *)(((portPOINTER_SIZE_TYPE) pxTopOfStack) & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK))); 
		/* 检查是否有错误 */
		configASSERT((((portPOINTER_SIZE_TYPE) pxTopOfStack & (portPOINTER_SIZE_TYPE) portBYTE_ALIGNMENT_MASK) == 0UL));
	}
	#else /* portSTACK_GROWTH */
	{
	}
	#endif /* portSTACK_GROWTH */

	/* 存储任务名称 */
	for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ){
		pxNewTCB->pcTaskName[ x ] = pcName[ x ];

		if( pcName[ x ] == 0x00 ){
			break;
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
	}

	/* \0补齐字符串 */
	pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';
	/* 判断任务分配的优先级,是否大于最大值  如果超过最大值,赋值最大值 */
	if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ){
		uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
	}
	else{
		mtCOVERAGE_TEST_MARKER();
	}
	/* 赋值任务优先级到任务控制块 */
	pxNewTCB->uxPriority = uxPriority;
	/* 任务状态表 事件表初始化 */
	vListInitialiseItem( &( pxNewTCB->xStateListItem ) );
	vListInitialiseItem( &( pxNewTCB->xEventListItem ) );
	/* 任务控制块链接到任务状态表中 */
	listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );
	/* 任务控制块连接到事件表中 */
	listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); 
	listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );

	#if( portUSING_MPU_WRAPPERS == 1 ){
	
	}
	#else{ /* portUSING_MPU_WRAPPERS */
		/* 任务堆栈初始化,之后返回任务栈顶 */
		pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
	}
	#endif /* portUSING_MPU_WRAPPERS */

	if( ( void * ) pxCreatedTask != NULL ){
		/* 赋值任务句柄 */
		*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
	}
	else{
		mtCOVERAGE_TEST_MARKER();
	}
}

2.3 任务堆栈初始化函数源码分析
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters){
	pxTopOfStack--;		/* 入栈程序状态寄存器 */
	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */
	
	pxTopOfStack--;		/* 入栈PC指针 */
	*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK;	/* PC */
	
	pxTopOfStack--;		/* 入栈LR链接寄存器 */
	*pxTopOfStack = ( StackType_t ) prvTaskExitError;	/* LR */
	
	pxTopOfStack -= 5;	/* 跳过R12, R3, R2 and R1这四个寄存器,不初始化 */
	*pxTopOfStack = ( StackType_t ) pvParameters;	/* R0作为传参入栈 */
	
	pxTopOfStack--;		/* 异常返回值入栈   返回值是确定程序使用的栈地址是哪一个 MSP PSP*/
	*pxTopOfStack = portINITIAL_EXEC_RETURN;
	
	pxTopOfStack -= 8;	/* 跳过R11, R10, R9, R8, R7, R6, R5 and R4这8个寄存器,不初始化 */
	return pxTopOfStack;	/*最终返回栈顶*/
}

以STM32(堆栈为向下增长模式)为例,经过上面的初始化后,此时的堆栈结果如下图所示
在这里插入图片描述

2.4 任务删除函数源码分析
void vTaskDelete( TaskHandle_t xTaskToDelete ){
	TCB_t *pxTCB;
	/* 进入临界段 */
	taskENTER_CRITICAL();
	{
		/* 如果传入的参数为NULL,说明调用vTaskDelete的任务要删除自身 */
		pxTCB = prvGetTCBFromHandle( xTaskToDelete );
		/* 将任务从就绪列表中移除 */
		if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ){
			taskRESET_READY_PRIORITY( pxTCB->uxPriority );
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
		/* 查看任务是否在等待某个事件,并将其从相应的列中删除 */
		if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ){
			( void ) uxListRemove( &( pxTCB->xEventListItem ) );
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
			
		uxTaskNumber++;
		/* 要删除的是当前正在运行的任务 */
		if( pxTCB == pxCurrentTCB ){
			/* 把任务添加到等待删除的任务列表中,并在空闲任务中删除 */
			vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );
			/* 记录有多少个任务需要释放内存 */
			++uxDeletedTasksWaitingCleanUp;
			/* 任务删除钩子函数---需要用户自己实现*/
			portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
		}
		else{
			/* 要删除的是别的任务 */
			--uxCurrentNumberOfTasks;
			prvDeleteTCB( pxTCB );
			/* 重新计算还要多长时间执行下一个任务 */
			prvResetNextTaskUnblockTime();
		}
		traceTASK_DELETE( pxTCB );
	}
	/* 退出临界段 */
	taskEXIT_CRITICAL();

	/* 判断调度器是否开启 */
	if( xSchedulerRunning != pdFALSE ){
		/* 如果是删除任务本身,马上进行任务调度(释放CPU的使用权)*/
		if( pxTCB == pxCurrentTCB ){
			configASSERT( uxSchedulerSuspended == 0 );
			portYIELD_WITHIN_API();
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
	}
}

3. 任务创建和删除函数实例

本实验设计三个任务:

start_task:用来创建其他两个任务
task1_task:此任务运行5次后调用vTaskDelete函数删除任务task2_task,同时控制LED0的闪烁
task2_task:此任务控制控制LED1的闪烁

  • 任务设置
#define START_TASK_PRIO 1 //任务优先级 
#define START_STK_SIZE 128 //任务堆栈大小 
TaskHandle_t StartTask_Handler; //任务句柄 
void start_task(void *pvParameters); //任务函数 

#define TASK1_TASK_PRIO 2 //任务优先级
#define TASK1_STK_SIZE 128 //任务堆栈大小
TaskHandle_t Task1Task_Handler; //任务句柄
void task1_task(void *pvParameters); //任务函数

#define TASK2_TASK_PRIO 3 //任务优先级
#define TASK2_STK_SIZE 128 //任务堆栈大小
TaskHandle_t Task2Task_Handler; //任务句柄
void task2_task(void *pvParameters); //任务函数

  • main()函数
int main(void){
	......
	//创建开始任务
	xTaskCreate((TaskFunction_t )start_task, 	//任务函数 
				(const char* )"start_task", 	//任务名称
				(uint16_t )START_STK_SIZE, 		//任务堆栈大小
				(void* )NULL, 					//传递给任务函数的参数
				(UBaseType_t )START_TASK_PRIO, 	//任务优先级
				(TaskHandle_t* )&StartTask_Handler); //任务句柄
	vTaskStartScheduler(); 						//开启任务调度
}

  • 任务函数
/* 开始任务任务函数 */
void start_task(void *pvParameters){
	taskENTER_CRITICAL(); //进入临界区
	//创建 TASK1 任务
	xTaskCreate((TaskFunction_t )task1_task,
				(const char* )"task1_task",
				(uint16_t )TASK1_STK_SIZE,
				(void* )NULL,
				(UBaseType_t )TASK1_TASK_PRIO,
				(TaskHandle_t* )&Task1Task_Handler);
	//创建 TASK2 任务
	xTaskCreate((TaskFunction_t )task2_task,
				(const char* )"task2_task",
				(uint16_t )TASK2_STK_SIZE,
				(void* )NULL,
				(UBaseType_t )TASK2_TASK_PRIO,
				(TaskHandle_t* )&Task2Task_Handler);
	vTaskDelete(StartTask_Handler); //删除开始任务
	taskEXIT_CRITICAL(); //退出临界区
}
//task1 任务函数
void task1_task(void *pvParameters){
	uint8_t task1_num=0;
	while(1){
		task1_num++; //任务1执行次数加1
		LED0=!LED0;
		printf("任务1已经执行: %d 次\r\n",task1_num);
		if(task1_num==5){
			vTaskDelete(Task2Task_Handler);//任务 1 执行 5 次删除任务 2 (4)
			printf("任务 1 删除了任务 2!\r\n");
		}
	vTaskDelay(1000); //延时 1s,也就是 1000 个时钟节拍
	}
}
//task2 任务函数
void task2_task(void *pvParameters){
	uint8_t task2_num=0;
	while(1){
		task2_num++; //任务2执行次数加1
		LED1=!LED1;
		printf("任务 2 已经执行: %d 次\r\n",task2_num);
		vTaskDelay(1000); //延时 1s,也就是 1000 个时钟节拍
	}
}

编译程序并下载到开发板中,打开串口助手,显示如下图示:一开始任务1和任务2是同时运行的,由于任务2的优先级比任务1高,所以任务2先输出信息;任务1运行了5次以后任务1就删除了任务2,最后只剩下任务1在运行

在这里插入图片描述

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

FreeRTOS系列|任务创建和删除 的相关文章

  • 【FreeRtos学习笔记】STM32 CubeMx——Timers(定时器)

    目录 1 软件定时器 2 示例程序 2 1 例程功能 2 2 步骤 2 3 实验结果 2 4 函数讲解 1 软件定时器 定时器是MCU常用的外设 我们在学习各种单片机时必然会学习它的硬件定时器 但是 MCU自带的硬件定时器资源是有限的 而且
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • STM32F103移植FreeRTOS必须搞明白的系列知识---3(堆栈)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • FreeRTOS学习笔记<中断>

    中断概念 Cortex M的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽中断 NMI 1个Systick 滴答定时器 定时器中断和多个系统异常 Cortex M处理器有多个用于管中断和异常的可编程寄存器 这些寄存器大多数都在 NV
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free

随机推荐

  • 2018-8-30华为机试第三题

    一个很明显的递归问题 package cn csu ksh import java util ArrayList import java util List import java util Scanner public class Mai
  • 海康威视web3.2开发包开发使用说明

    首言 xff1a 通过海康威视的最新web开发包工具进行js调用引入至vue项目中 xff0c 实现监控设备的对接 xff0c 监控功能的实现 3 2无插件js库同时支持插件安装的模式 目录 首言 xff1a 一 海康威视开发平台 xff1
  • 游戏的navmesh 与rvo动态避障算法(1)

    目前很多手游中如果需要寻路 xff0c 很多时候复杂地形都是需要用到navmesh xff0c 而比较常用的navmesh 系统 xff1a 1 astarpathfinding xff1a 一个老外开发的寻路插件 xff0c 内置有很多寻
  • Python3 指数函数 | numpy.power() math.pow() numpy.exp2() a**b

    对数函数用法 单纯求一个数的指数函数 xff0c 直接用a b比较好 xff1f 2 3 2的三次方 使用pow x y pow 有两种 xff0c 一种是python内置函数 xff0c 一种是math pow 使用python内置函数调
  • SVO2.0

    rpg svo pro open即svo2 0版本在上一年开源了 xff0c 对svo2 0接触了有一小段时间了 xff0c 感觉代码功能和一些函数实现等相比svo1 0版本有区别 xff0c 所以准备把这块好好总结下 xff0c 争取白话
  • ROS CMakeLists.txt中catkin_package和INCLUDE_DIRS的区别

    CMakeLists txt中 catkin package INCLUDE DIRS include 这里代表的是catkin的构建选项 xff0c INCLUDE DIRS表示将使用INCLUDE DIRS后面的内部目录include
  • 利用ROS框架搭建云平台提供机器人服务

    我们要怎么做呢 我们在云平台我们识别物体之后输出的是全局的二维码坐标 x y z 我们接下来要做两件事情 一种是使用云端的服务 xff08 在ROS中的表现形式是云平台提供的action xff09 第二种是请求云端的数据 xff08 可以
  • 虚拟现实技术vr可以用来干什么?虚拟现实技术vr有什么特征

    科技行业的不断蓬勃发展 xff0c 每天会出现一些新的科技产品 xff0c 例如现在很火的虚拟现实技术vr xff0c 虚拟现实技术用的领域很多 xff0c 就拿游戏行业来说 xff0c 玩家可以通过vr眼镜 vr手柄等体验vr游戏 xff
  • vr直播是如何实现的?vr直播都有哪些优势

    科技改变了我们的生活方式 xff0c 提起科技相信大家对这个直播行业恐怕都不陌生 xff0c 最近直播行业也玩出来新的花样 xff0c 引进了vr技术 xff0c 摇身一变 xff0c 变成了vr直播 xff0c 很多朋友不太理解vr直播是
  • Python归并排序

    归并排序 数据科学家每天都在处理算法 然而 xff0c 数据科学学科作为一个整体已经发展成为一个不涉及复杂算法实现的角色 尽管如此 xff0c 从业者仍然可以从建立对算法的理解和知识库中受益 在本文中 xff0c 对排序算法归并排序进行了介
  • 平衡车PID调节总结

    https blog csdn net a568713197 article details 82845959
  • FreeRTOS详解三

  • Invalid bound statement (not found)出现的原因和解决方法

    解决错误的步骤 出现了什么错误可能导致的原因解决办法 出现了什么错误 错误截图 xff1a BindingException 数据绑定异常 not found 找不到 org apache ibatis binding BindingExc
  • TI Processor SDK 如何生成例程

    TI现在新的SDK都叫Process SDK了 例程要自己生成 这样好多人都说自己找不到例程在哪里 其实就是生成这一步搞不定 我以AM5728为例子说 先打开到pdk的目录 编辑箭头所示文件 安装在默认路径Cpan的可以忽略这一步 否则要改
  • PCIE BAR空间理解

    PCIE应用程序编程 xff0c 首先就要理清PCIE BAR空间到底说的是什么 在PCIE配置空间里 xff0c 0x10开始后面有6个32位的BAR寄存器 xff0c BAR寄存器中存储的数据是表示PCIE设备在PCIE地址空间中的基地
  • 老男孩读PCIe之五:TLP结构

    来源 xff1a http www ssdfans com p 61 3683 无论Request TLP xff0c 还是作为回应的Completion TLP xff0c 它们模样都差不多 xff1a 图5 1 TLP主要由三部分组成
  • vxWorks6.9及workBench3.3常见配置

    1 双斜杠注释 在workBench集成开发环境当中 xff0c 默认的注释方式为 xxxxxx 如果想要使用 注释的方法必须修改workBench 的编译选项 xff0c 为编译选项添加c99支持或者gnu89 在编译选项中添加 std
  • 可能是最全的FreeRTOS源码分析及应用开发系列

    可能是最全的FreeRTOS源码分析及应用开发系列 FreeRTOS 是一个可裁剪的小型且免费的 RTOS 系统 xff0c 尺寸非常小 xff0c 可运行于微控制器上 其特点包括 xff1a 内核支持抢占式 xff0c 合作式和时间片调度
  • FreeRTOS系列|FreeRTOS简介

    1 RTOS简介 RTOS全称为 Real Time Operation System xff0c 即实时操作系统 RTOS强调的是实时性 xff0c 又分为硬实时和软实时 硬实时要求在规定的时间内必须完成操作 xff0c 不允许超时 xf
  • FreeRTOS系列|任务创建和删除

    1 任务创建和删除API函数 xTaskCreate 函数 xff1a 动态创建一个新的任务 xff0c 每个任务都需要RAM来保存任务状态 任务控制块 43 任务栈 xff0c 此接口采用动态分配内存资源 BaseType t span