在MDK上建立一个C++的STM32开发工程

简介:

 最近,我惊讶地发现居然可以用C++进行嵌入式程序开发,甚至是裸系统程序。之前,做单片机开发、STM32上程序开发,想到的都是C语言、汇编语言,根 本就没有考虑过还可以用C++语言做开发。近日,在学习公司的项目之后,发现C++有其独道之处。开发起来比C语言更方便架构搭建与程序管理。

     我之前对C++有曲解,总认为C++只适合做上层应用软件开发,不适用于单片机开发。一方面是因为C++喜欢来不不就new一个对象。对于内存空间非常紧 张的单片机,只能望海兴叹。二是C++生成的代码量较C庞大,效率上可能没有C高。对于主频较低的单片机,也用一点勉强。但是,这并不能掩盖C++的优 势。C++是面向对象的程序语言,能非常灵活地进行继承与派生,还能实现多态。对于较大一点的程序而言,用C作开发,不异于用砖头砌坐20层的大厦。这样 的大厦既不稳定,也不好维护。相反,C++则可以很好地完成这样大的任务。但是,你就盖个两层楼的小平房,需得着什么房屋框架吗?也没必要呀。
    总而言之,C与C++各有各的优势,就看你怎么用。

    我手头一有块STM32的开发板。于是,我尝试在MDK上建一个基于C++的Demo工程。板子上有64KB的SRAM,主频可达72MHz,也差不多了。

    想到C++,我就想到了new 这个关键字。这个new 就是从堆里取一块内存空间,并执行类的构造函数。
    那么这里就要涉及到堆的问题,你必须得告诉程序一个问题:(1)堆在哪里?(2)堆有多大?

    以下是我在main()中对堆的实现:


#include <rt_heap.h>  //_init_alloc
 
#define HEAP_SIZE   (0x3000)
INT32U  heap_zone[HEAP_SIZE] = {0};
 
int main()
{
    NVIC_Configuration();
 
    OSInit();
 
    _init_alloc((INT32U)heap_zone, (INT32U)&heap_zone[HEAP_SIZE-1]);
 
    CStartTask start;
    start.Create();
     
    OSStart();
 
    return 0;
}

  首先声明,这个main()所在的文件必须是以.cpp文件,不然编译当成C语言进行编译。C++可以调用C,C不能调用C++,这点要记住。以上对堆的实现分两步:
    (1)要在SRAM中留一块空间来做堆。上代就用定义数组的方式实现。 INT32U heap_zone[HEAP_SIZE] = 0;
    (2)告诉程序堆的起止地址。通过调用 _init_alloc( startAddr, endAddr  );

    也不一定非要用这做笨绌的方法定义一块堆空间。我这块开发板上还用FSMC扩展了一个512KB的SRAM。那么我可以用这块空间来做堆空间。如下:


#include <rt_heap.h>  //_init_alloc
 
#define HEAP_BASE  Bank1_SRAM3_ADDR
#define HEAP_TOP   (Bank1_SRAM3_ADDR+0x100000)
int main()
{
    NVIC_Configuration();
    FSMC_SRAM_Init();  //初始化对SRAM的访问
 
    OSInit();
 
    _init_alloc(HEAP_BASE, HEAP_TOP);    // 设置堆空间
 
    CStartTask start;
    start.Create();
     
    OSStart();
 
    return 0;
}

  SRAM 的首地址就是 HEAP_BASE = Bank1_SRAM3_ADDR , 止地址就是 HEAP_TOP =  Bank1_SRAM3_ADDR+0x100000 。
    如上调用完 _init_alloc() 函数后,你就可以使用 new 进行申请空间与创建对象了。

    在工程中凡是 .c 文件都是C源文件,凡是 .cpp 文件都是C++源文件。在将原来部分C语言代码移植到C++的时候,要在头文件的开始与终止处添加以下内容:


#ifdef __cplusplus
       extern "C" {
#endif
        ……    // 正文
#ifdef __cplusplus
        }
#endif


  extern "C" { } 用于告诉编译器,大括号以内的东西以C的方式进行编译。因为原来.C的头文件被.CPP文件包含了,那么编译器便按C++的方式进行编译,导致与原来.C文件中定义的不一致,编译报错。  

目录
相关文章
|
21天前
|
开发框架 Linux C语言
C、C++、boost、Qt在嵌入式系统开发中的使用
C、C++、boost、Qt在嵌入式系统开发中的使用
30 1
|
28天前
|
程序员 API 数据库
【Cmake工程 库相关教程 】深入理解CMake工程C/C++ 库管理技巧
【Cmake工程 库相关教程 】深入理解CMake工程C/C++ 库管理技巧
60 0
|
1月前
|
网络协议 C++
C++ Qt开发:QTcpSocket网络通信组件
`QTcpSocket`和`QTcpServer`是Qt中用于实现基于TCP(Transmission Control Protocol)通信的两个关键类。TCP是一种面向连接的协议,它提供可靠的、双向的、面向字节流的通信。这两个类允许Qt应用程序在网络上建立客户端和服务器之间的连接。Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QTcpSocket`组件实现基于TCP的网络通信功能。
37 8
C++ Qt开发:QTcpSocket网络通信组件
|
20天前
|
人工智能 机器人 编译器
【C++】Windows端VS code中运行CMake工程(手把手教学)
【C++】Windows端VS code中运行CMake工程(手把手教学)
|
1月前
|
IDE 编译器 开发工具
C/C++ IDE环境 (Qt Creator visual studio等) Cmake工程不显示头文件的解决方案
C/C++ IDE环境 (Qt Creator visual studio等) Cmake工程不显示头文件的解决方案
22 0
|
1月前
|
监控 C++
C++ Qt开发:QProcess进程管理模块
Qt是一个跨平台的C++图形库,简化了窗体应用开发,支持通过拖放组件提升效率。本章节关注`QProcess`组件,它用于控制和管理进程,例如执行命令、运行可执行文件及与外部进程通信。`QProcess`提供多种方法如`start`、`waitForStarted`和`waitForFinished`等,实现启动、监控和交互。示例展示了如何使用`QProcess`获取系统进程和信息,通过`tasklist`和`systeminfo`命令,并将结果展示在`QTreeWidget`中。
28 0
C++ Qt开发:QProcess进程管理模块
|
1月前
|
编译器 测试技术 API
C++库开发之道:实践和原则(三)
C++库开发之道:实践和原则
72 0
|
1月前
|
存储 缓存 安全
C++库开发之道:实践和原则(二)
C++库开发之道:实践和原则
46 0
|
1月前
|
安全 API C++
C++库开发之道:实践和原则(一)
C++库开发之道:实践和原则
46 0
|
1月前
|
数据可视化 算法 C++
C++ cmake工程引入qt6和Quick 教程
C++ cmake工程引入qt6和Quick 教程
36 0