STM32 趟坑一览


CubeMX 添加RTX



前言:

STM32CubeMX是意法推出的基于STM32的一款强大的可视化开发软件,在常规的产品开发中,可以结合可视化的硬件配置来完成系统平台的初始化配置,选用一些中间软件包,如OS,FS等。

RTX5是Keil公司打造的一款轻量型,实时,低延迟,高可靠,安全的操作系统,MDK开发环境本身集成了RTX5软件包。但STM32CubeMX中不包含RTX5组件包,并不支持RTX5组件包,这需要在STM32CubeMXb生成的工程文件中手动添加RTX5软件包,下面详细阐述该过程,并对其中的编译错误的更正过程进行了的说明。

开发环境:

  • MDK 5.25

  • STM32CubeMX 4.25

  • STM32CubeMX STM32F4 组件包版本为1.21.0

  • RTX5 5.3.0

一. 在STM32CubeMX生成的工程中添加RTX5源码

1. 打开STM32CubeMX工程

如果中间件FreeRTOS被勾选,要勾选掉,防止两个操作系统同时存在:

upload_downloader_1610940249286_45807139.png

2. 生成MDK工程代码

在STM32CubeMX,生成并打开MDK工程代码。

在MDK的工程Options for target ...的Output选显卡中,勾选掉默认的选项"Browse Iniormation",这样可以加快编译速度,否则编译会非常耗时。


3. 增加RTX5软件组件:

upload_downloader_1610940249483_53685877.png

添加RTOS2-->Keil RTX5,这里为5.3.0版本(单击图片可放大):

upload_downloader_1610940279186_24133307.png

如提示出现“Validation Output",点击信息框下面的"Resolve"。

有两种添加RTX5的方式:库和源代码。这里重点说明如何对添加的RTX5源码进行工程编译,所以这里选择"Source"。

上图 “Keil RTX5”对应的右侧栏目选择"Source",然后点击"Resolve"。

二. 工程编译错误的解决

1. "Unknown Arm Architecture!"错误

尝试工程编译,会提示如下的编译错误:

error:  #35: #error directive: "Unknown Arm Architecture!"

删除工程目录Drivers\CMSIS\Include\下的cmsis_armcc.h

这样工程会使用C:\Keil_v5\ARM\PACK\ARM\CMSIS\5.3.0\CMSIS\Include\cmsis_armcc.h

后一个文件的文件头代码如下:

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)

  #error "Please use Arm Compiler Toolchain V4.0.677 or later!"

#endif

/* CMSIS compiler control architecture macros */

#if ((defined (__TARGET_ARCH_6_M  ) && (__TARGET_ARCH_6_M   == 1)) || \

     (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M  == 1))   )

  #define __ARM_ARCH_6M__           1

#endif

#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M  == 1))

  #define __ARM_ARCH_7M__           1

#endif

#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))

  #define __ARM_ARCH_7EM__          1

#endif

  /* __ARM_ARCH_8M_BASE__  not applicable */

  /* __ARM_ARCH_8M_MAIN__  not applicable */

/* CMSIS compiler specific defines */

#ifndef   __ASM

  #define __ASM                                  __asm

#endif

#ifndef   __INLINE

  #define __INLINE                               __inline

#endif

#ifndef   __STATIC_INLINE

  #define __STATIC_INLINE                        static __inline

#endif

#ifndef   __STATIC_FORCEINLINE                

  #define __STATIC_FORCEINLINE                   static __forceinline

#endif          

#ifndef   __NO_RETURN

  #define __NO_RETURN                            __declspec(noreturn)

#endif

#ifndef   __USED

  #define __USED                                 __attribute__((used))

#endif

#ifndef   __WEAK

  #define __WEAK                                 __attribute__((weak))

#endif

...

而在STM32CubeMX生成的Drivers\CMSIS\Include\下的cmsis_armcc.h的文件中并无这些宏定义。

特别,如下宏定义分支有效:

#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M  == 1))

  #define __ARM_ARCH_7M__           1

#endif

2. 代码重复冲突错误

再次编译,会出现如下错误:

error: L6235E: More than one section matches selector - cannot all be FIRST/LAST.

这是由于STM32CubeMX生成的工程所包含的启动文件"startup_stm32f439xx.s"(Application/MDK-ARM工程文件夹下,见下图)中,已经存在RESET段。这和RTX5的启动文件"startup_stm32f439xx.s"(Deviece工程文件夹下,见下图)中的代码相冲突:

upload_downloader_1610940249302_42179088.png

将Application/MDK-ARM工程文件夹下的"startup_stm32f439xx.s"文件排除在编译之外:

右键点击Application/MDK-ARM工程文件夹下的文件"startup_stm32f439xx.s",

选中“Options for startup_stm32f439xx.s”菜单,弹出(单击图片可放大):

upload_downloader_1610940249302_25027256.png

勾选掉“include in Target Build",如上图(“include in Target Build"未勾选掉之前)。


编译工程,会出现如下错误:

Error: L6200E: Symbol SystemCoreClock multiply defined (by system_stm32f4xx_1.o and system_stm32f4xx.o).

Error: L6200E: Symbol AHBPrescTable multiply defined (by system_stm32f4xx_1.o and system_stm32f4xx.o).

Error: L6200E: Symbol APBPrescTable multiply defined (by system_stm32f4xx_1.o and system_stm32f4xx.o).

rror: L6200E: Symbol SVC_Handler multiply defined (by stm32f4xx_it.o and irq_cm4f.o).

(单击图片可放大)

upload_downloader_1610940249303_45105712.png

同样的,这是由于STM32CubeMX生成的工程所包含的文件"system_stm32f4xx.c"(Drivers/CMSIS工程文件夹下,见下图)中,已经存在上面编译错误中的段。这和RTX5的文件"system_stm32f4xx.c"(Deviece工程文件夹下,见下图)中的代码相冲突:

upload_downloader_1610940250218_80576118.png

将Drivers/CMSIS工程文件夹中的"system_stm32f4xx.c"排除在编译之外。

工程编译,会提示:

Error: L6200E: Symbol SVC_Handler multiply defined (by stm32f4xx_it.o and irq_cm4f.o).

Error: L6200E: Symbol PendSV_Handler multiply defined (by stm32f4xx_it.o and irq_cm4f.o).

Error: L6200E: Symbol SysTick_Handler multiply defined (by stm32f4xx_it.o and irq_cm4f.o).

同样的,将文件"stm32f4xx_it.c"排除在编译之外。

3.  RTX5示例演示

增加RTX5示例代码:

在"Application/MDK-ARM"列表上点击右键,在弹出的菜单中选中"Add New Item to Group 'Application/User'":

upload_downloader_1610940251158_15975779.png

弹出对话框:

upload_downloader_1610940251479_67736049.png

注意要防止这里的man.c文件存放路径和STM32CubeMX生成的main.c文件的路径相冲突。

在工程中排除掉"Application/User"下的main.c文件的编译。

最后的工程文件列表如下(红色框处的标注为排除在工程编译之外的文件):

upload_downloader_1610940251869_34153400.png

编译工程,提示:

STM32F429_176\STM32F429_176.axf: Error: L6218E: Undefined symbol _Error_Handler (referred from tim.o).

复制"Application/User"下的main.c中的_Error_Handler函数到新增的"Application/MDK-ARM"下的main.c文件中。

在main.c中新增任务,最后的代码如下:

/*----------------------------------------------------------------------------

 * Application main thread

  *---------------------------------------------------------------------------*/

void task1 ( void * argument )

{

 

    // ...

    for (;;){

        osDelay ( 30 );

    }

   

}

 

void task2 ( void * argument )

{

 

    // ...

    for (;;){

        osDelay ( 20 );

    }

   

}

 

int main ( void ) {

 

    // System Initialization

    SystemCoreClockUpdate ();

    #ifdef RTE_Compiler_EventRecorder

        // Initialize and start Event Recorder

        EventRecorderInitialize ( EventRecordError , 1U );

    #endif

    // ...

    osKernelInitialize ();               // Initialize CMSIS-RTOS

    osThreadNew ( task1 , NULL , NULL );     // Create application main thread

    osThreadNew ( task2 , NULL , NULL );     // Create application main thread

    osKernelStart ();                    // Start thread execution

    for (;;) {}

   

}

最后,在MDK的"Project"中,Clean Targets,再次全部编译。

注意,Clean Targets这一步是必须的,否则,调试启动时,无法跳转到最终所使用的main.c文件的main函数中。







来自:计算机科学 / 软件综合
5
张静茹 作者
1个月14天前 修改于 1个月14天前
1楼

例如串口同时在DMA发送和DMA接收,DMA接收到一半我要终止DMA的话,只能调用HAL_UART_DMAStop把接收DMA和串口DMA都停止。
换言之,不能单独停止DMA接收。
我理解的接收DMA和发送DMA是两个独立的操作,为什么不能单独停止? 


HAL_UART_DMAStop()函数的确是uart接收和发送同时关闭,找了好久终于找到只关闭接收的函数了。
只关闭接收的函数。HAL_UART_AbortReceive()


https://www.stmcu.org.cn/module/forum/thread-606385-1-1.html

回复
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
1个月14天前
2楼

Demo\Demo.sct(7): error: L6235E: More than one section matches selector - cannot all be FIRST/LAST.

工程中包含了不只一个启动文件

回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
1个月14天前
3楼

image.png

回头试试

回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
1个月14天前 修改于 1个月14天前
4楼

RTX + HAL 

HAL Tick选择其他定时器提供 SYS->Timebase Source

NVIC->取消SystemTickTimer 取消System service call via swl instruction 取消Pendable request for system service

Keil 中选择RTX 但不要选择启动代码,不然启动代码有两份,内存不足检查RTX默认分配内存太大


回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
1个月13天前
5楼


void Task1(void* args)
{
	osDelay(1000);
	char TxBf[] = "HelloDMA0";
	//HAL_UART_Transmit_DMA(&huart1, (uint8_t*)TxBf, sizeof(TxBf));
	while (1) {

		//HAL_DMA_RegisterCallback(&hdma_usart1_tx, HAL_DMA_XFER_CPLT_CB_ID, Uart1_DMA_TxComplete);
		HAL_UART_Transmit_DMA(&huart1, (uint8_t*)TxBf, sizeof(TxBf)-1);
		//osEventFlagsWait(Uart1_Recv_Event, 01, osFlagsWaitAny, osWaitForever);
		/*__HAL_DMA_CLEAR_FLAG(&hdma_usart1_tx, DMA_FLAG_TC4);
		while (__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC4) == 0);*/
		while(huart1.gState != HAL_UART_STATE_READY)
		{}	
		
		osDelay(1);
	}
}

DMA发送字符串 串口助手显示数据错乱,原因是C语言字符最后有个\0  串口助手显示错乱

回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
warmonkey
1个月13天前
6楼
引用张静茹发表于5楼的内容
DMA发送字符串 串口助手显示数据错乱,原因是C语言字符最后有个\0  串口助手显示错乱

取字符串长度是strlen(str)

回复
评论(1)
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
1个月12天前
7楼
#pragma SAVE           // save current optimization level
#pragma OPTIMIZE(7)    // disable function block optimization
void func (void)  {

}
#pragma RESTORE        // restore original optimization level

keil设置某段程序的优化等级,V6编译器仅支持按文件设置编译等级

回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
Mxxy
1个月9天前
8楼

    STM32现在这个芯片涨价厉害的很啊

回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
张静茹
学者 机友 笔友
文章
131
回复
1797
学术分
1
2010/12/30注册,13 小时前活动
暂无简介
%7B%22isDisplay%22%3Atrue%7D

仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传
空空如也~
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
{{forum.displayName}}
{{forum.countThreads}}
篇文章,
{{forum.countPosts}}
条回复
{{forum.description || "暂无简介"}}
ID: {{user.uid}}
学术分隐藏
{{submitted?"":"投诉或举报"}}
请选择违规类型:
{{reason.description}}
支持的图片格式:jpg, jpeg, png
插入公式
分享回复:{{shareId}}
加载中...
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
加入关注取消关注
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
建议修改
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
下载资料
{{fileName}}
大小:{{size}}
下载当前附件将花费 {{costMessage}}
你当前剩余 {{holdMessage}}
{{fileName}}
大小:{{size}}
当前附件免费。
你已购买过此附件,下载当前附件不需要花费积分。
加载中...
{{errorInfo}}
附件已丢失
当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}