KEIL / MDK C++支持方法:基于TencentOS-Tiny 工程修改,STM32芯片

采用STM32CubeMX生成的keil工程,默认是采用V5编译的,V5版本编译器只支持C。

就目前来说,使用C++开发嵌入式的程序员还是比较少,就我个人认为原因是一方面KEIL / MDK对C++程序的支持还不够全面,另一方面则是C++程序的体量相较于C程序过于庞大,对于小型的应用来说没有必要。

作为一个嵌入式和智能终端都有一点接触的程序员来说,我当然是更希望我的代码能够更容易地移植,最重要的一点则是C++兼容了C,我们要在原始的C工程上面,进行修改,使得我们的工程变得可以支持C++。

一、KEIL / MDK 配置修改

KEIL / MDK是支持C++编程方式的,我们先打开原先的keil工程,当然这个工程原本是可以编译通过的。

如下图,打开Project -- Options for Target,打开Target选项卡:

1、选择Version 6

因为KEIL / MDK V5版本只支持C编译,V6版本才支持C++编译。

2、去掉Use MicorLIB的勾选

microlib 是缺省 C 库的备选库;

它用于必须在极少量内存环境下运行的深层嵌入式应用程序;

microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。

microlib支持printf,

但是不支持C++编译,所以这里要去掉,后面我们会采用其他方式来支持printf。

如下图,选择C/C++(AC6)选项卡

OK,配置完成

二、std标准库 重定向

因为microlib已经去掉,需要对部分标准库方法进行重定向编写,既将输入输出流重定向至STM32的串口端。而Retarget.c里面就实现了相关的方法。

我们从keil的安装路径里找到Retarget.c文件,复制到我们的工程目录下,然后进行修改如下:

/******************************************************************************/
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions      */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools.                    */
/* Copyright (c) 2005 Keil Software. All rights reserved.                     */
/* This software may only be used under the terms of a valid, current,        */
/* end user licence from KEIL for a compatible version of KEIL software       */
/* development tools. Nothing else gives you the right to use this software.  */
/******************************************************************************/

#include <rt_sys.h>
#include "usart.h"
#ifdef __cplusplus
extern "C" {
#endif

extern int  sendchar(int ch);  
extern int  getkey(void);      

int fputc(int ch, FILEHANDLE *f) {
  return (sendchar(ch));
}

int fgetc(FILEHANDLE *f) {
  return (sendchar(getkey()));
}

FILEHANDLE _sys_open(const char * name, int openmode)
{
    return 1;  
}
int _sys_close(FILEHANDLE fh)
{
    return 0; //return success
}
int _sys_write(FILEHANDLE fh, const unsigned char * buf,
               unsigned len, int mode)
{
    return 0;   
}
int _sys_read(FILEHANDLE fh, unsigned char * buf,
              unsigned len, int mode)
{
    return 0;       
}
void _ttywrch(int ch)
{ 
}
int _sys_istty(FILEHANDLE fh)
{
    return 1; // no interactive device present
}
int _sys_seek(FILEHANDLE fh, long pos)
{
    return -1; // error
}
int _sys_ensure(FILEHANDLE fh)
{
    return 0; // success
}
long _sys_flen(FILEHANDLE fh)
{
    return 0;
}
int _sys_tmpnam(char * name, int sig, unsigned maxlen)
{
    return 0; // fail, not supported
}
void _sys_exit(int returncode)
{
    while(1) {};
}
#ifdef __cplusplus
}
#endif

然后在其他文件里,比如你的串口读写的C文件里实现

sendchar函数和getkey函数

例如:

int  sendchar(int ch)
{
	if (ch == '\n') {
    HAL_UART_Transmit(&huart1, (void *)"\r", 1,30000);
  }
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
}

int  getkey(void){
	/* Place your implementation of fgetc here */
  /* e.g. readwrite a character to the USART2 and Loop until the end of transmission */
  uint8_t ch = 0;
  //uint32_t recv_size;
  HAL_UART_Receive(&huart1, &ch, 1,30000);
  return ch;
}

三、从C调用C++

建立一个C++文件,加入到我们工程中,或者将我们之前的一个c文件直接修改为cpp文件

要调用c++里的函数, 需要将被调用的函数声明为``extern "C"''

extern "C" void application_entry(void *arg);

可以添加

std::cout << "hello world" << std::endl;

进行测试了。

串口已能正常打印输出。

至此,我们就可以任意

随心所欲地进行C++程序编写了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爬呀爬的水滴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值