完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F429移植FreeRTOS
一、环境 Win10、Keil uVision5、STM32CubeMX、STM32F429IGT6 二、准备工作 2.1创建基于HAL库的STM32F429基础工程 创建新项目,MCU型号选择STM32F429IGTx,然后开始项目。 选择使用外部高速时钟,时钟源为外部晶振,然后配置系统时钟,根据晶振频率将系统时钟配置到180MHz。 配置USART1为异步收发串口模式,设定为115200波特率,8位数据位,1位停止位,无奇偶校验,配置USART1相关外设IO引脚,启用USART1 DMA收发传输,启用USART1中断和其DMA收发关联通道中断并设定优先级。 在项目管理子页面对项目相关配置项以及代码生成项进行相关配置。 建议对HAL时基源选择为SysTick以外的时钟源。 以上步骤完成后点击生成代码,代码生成完以后用Keil uVision5打开项目并进行编译,此时编译应该是能正常编译的。 经过以上步骤,我们创建了不含有FreeRTOS的基础工程(如果想使用CMSIS接口的也可以在配置时直接勾选使用FreeRTOS中间件)。 2.2获取FreeRTOS源码 FreeRTOS作为开源RTOS,允许开源商用,可以在其官方网站找到源码获取入口(官方网址为:www.freertos.org)。进入官网后,在首页点击下载FreeRTOS,进入下载页面点击下载。这里我获取的是FreeRTOS V10.3.1的源码。 三、FreeRTOS移植 在STM32CubeMX生成的项目目录中添加子目录FreeRTOS。将官方源码中Source目录中的所有内容全部复制到我们创建的FreeRTOS目录下。保留FreeRTOSportable目录下的Keil、MemMang、RVDS,其他的可以删除(其实Keil也可以删除)。 在Keil uVision5中创建分组FreeRTOS_CORE、FreeRTOS_PORTABLE。将FreeRTOS目录下的croutine.c、event_groups.c、list.c、queue.c、stream_buffer.c、tasks.c、timers.c全部添加到分组FreeRTOS_CORE。将FreeRTOSportableMemMangheap_4.c和FreeRTOSportableRVDSARM_CM4Fport.c添加到分组FreeRTOS_PORTABLE。 然后将FreeRTOS的相关头文件路径添加到项目中。 将官方Demo中的FreeRTOS复制到我们的工程目录FreeRTOSinclude中去。 将FreeRTOSConfig.h中第45行左右的 #ifdef __ICCARM__ 修改为 #ifdef __CC_ARM以便和我们使用的编译器匹配。 将FreeRTOSConfig.h中目前没有实现的没有使用的钩子函数开启宏关闭(官方Demo中开启了这些宏):configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configCHECK_FOR_STACK_OVERFLOW、configUSE_MALLOC_FAILED_HOOK。 打开文件stm32f4xx_it.c,找到SVC_Handler、PendSV_Handler、SysTick_Handler的函数定义将其屏蔽,因为这三个函数和FreeRTOS内核息息相关,在FreeRTOS内核源码中有具体实现,屏蔽掉是为了祛除重定义。 这时候编译,会正常通过。 四、添加基础功能 经过以上步骤实际上已经基本完成了FreeRTOS V10.3.1在STM32F429IGT6的移植,但是为了方便测试,我们还将添加一些基础功能。 4.1串口DMA发送 添加USART1_Tx DMA传输N字节相关代码段: #define USART1_TX_DMA_BUFFER_MAX_SIZE 1024 uint8_t Usart1_Tx_DMA_Buffer[USART1_TX_DMA_BUFFER_MAX_SIZE+1]; uint16_t Usart1_DMASend_NBytes(uint8_t* buffer, uint16_t size) { uint16_t size_t=0; if(!size) return 0; size_t = (size 》 USART1_TX_DMA_BUFFER_MAX_SIZE ? USART1_TX_DMA_BUFFER_MAX_SIZE : size); while(0 != __HAL_DMA_GET_COUNTER(&hdma_usart1_tx)){;} if(buffer!=NULL) { memcpy(&Usart1_Tx_DMA_Buffer[0], buffer,size_t); } HAL_UART_Transmit_DMA(&huart1, Usart1_Tx_DMA_Buffer, size_t); return size; } 创建几个简单的FreeRTOS任务: #define START_TASK_PRIO 1 #define START_STK_SIZE 128 TaskHandle_t StartTask_Handler; void start_task(void *pvParameters); #define USART1_SEND_TASK_PRIO 2 #define USART1_SEND_STK_SIZE 256 TaskHandle_t USART1_SendTask_Handler; void USART1_Send_task(void *pvParameters); #define APP_TASK_PRIO 3 #define APP_STK_SIZE 256 TaskHandle_t APP_Task_Handler; void APP_task(void *pvParameters); #define SENSOR_TASK_PRIO 4 #define SENSOR_STK_SIZE 256 TaskHandle_t Sensor_Task_Handler; void Sensor_task(void *pvParameters); #define USART1_TX_Q_NUM 5 QueueHandle_t Queue_Usart1_tx; #define MAX_FRAME_COMM_BUFFER_SIZE USART1_TX_DMA_BUFFER_MAX_SIZE typedef struct { uint8_t* start_addr; uint16_t len; }Usart1_Tx_Buffer_Typedef; int main(void) { BaseType_t TaskCreateStatus; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); TaskCreateStatus= 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); if(pdPASS == TaskCreateStatus) { //printf(“ start_task create successrn”); } vTaskStartScheduler(); while (1) { } } void start_task(void *pvParameters) { BaseType_t TaskCreateStatus; taskENTER_CRITICAL(); Queue_Usart1_tx=xQueueCreate(USART1_TX_Q_NUM,sizeof(Usart1_Tx_Buffer_Typedef)); TaskCreateStatus= xTaskCreate((TaskFunction_t )USART1_Send_task, (const char* )“USART1_Send_task”, (uint16_t )USART1_SEND_STK_SIZE, (void* )NULL, (UBaseType_t )USART1_SEND_TASK_PRIO, (TaskHandle_t* )&USART1_SendTask_Handler); if(pdPASS == TaskCreateStatus) { //printf(“ LED0Task create successrn”); } TaskCreateStatus= xTaskCreate((TaskFunction_t )APP_task, (const char* )“APP_task”, (uint16_t )APP_STK_SIZE, (void* )NULL, (UBaseType_t )APP_TASK_PRIO, (TaskHandle_t* )&APP_Task_Handler); if(pdPASS == TaskCreateStatus) { //printf(“ LED0Task create successrn”); } TaskCreateStatus= xTaskCreate((TaskFunction_t )Sensor_task, (const char* )“Sensor_task”, (uint16_t )SENSOR_STK_SIZE, (void* )NULL, (UBaseType_t )SENSOR_TASK_PRIO, (TaskHandle_t* )&Sensor_Task_Handler); if(pdPASS == TaskCreateStatus) { //printf(“ LED0Task create successrn”); } vTaskDelete(StartTask_Handler); taskEXIT_CRITICAL(); } void USART1_SendData(uint8_t *pData,uint16_t len) { Usart1_Tx_Buffer_Typedef Tx_Buff; Tx_Buff.start_addr = pData; Tx_Buff.len = len; xQueueSendToBack(Queue_Usart1_tx,(void *)&Tx_Buff,portMAX_DELAY); } void USART1_Send_task(void *pvParameters) { Usart1_Tx_Buffer_Typedef Tx_Type; BaseType_t res = pdTRUE; while(1) { res = xQueueReceive(Queue_Usart1_tx,&Tx_Type,portMAX_DELAY); if(res == pdTRUE) Usart1_DMASend_NBytes(Tx_Type.start_addr,Tx_Type.len);//通过DMA发送 vTaskDelay(10); } } void APP_task(void *pvParameters) { uint8_t testOut[128]; uint32_t index=0; while(1) { sprintf((char*)testOut,“APP_task %u rn”,index++); USART1_SendData(testOut,strlen((const char*)testOut)); vTaskDelay(100); } } void Sensor_task(void *pvParameters) { uint8_t testOut2[128]; uint32_t index=0; while(1) { sprintf((char*)testOut2,“Sensor_task %u rn”,index++); USART1_SendData(testOut2,strlen((const char*)testOut2)); vTaskDelay(100); } } 4.2下载验证 将工程进行编译、下载验证,符合预期。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1683 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1582 浏览 1 评论
1013 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
703 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1627 浏览 2 评论
1892浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
675浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
538浏览 3评论
558浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
526浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 02:07 , Processed in 0.813155 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号