小编Arn*_*rne的帖子

删除未使用的模板实例化的静态成员

我目前在STM32平台上参与嵌入式C++开发.我们的团队正在评估模板的使用,以便为各种低级硬件设备参数化驱动程序.

所有有效的模板特化都是事先已知的,因此我们可以在实现文件中明确地给出所有有效的特化(实现和声明分离).事实上,对我们来说,显式专业化非常有用,因为它有助于记录可行的参数集.

// file i2c_dev.h

template<typename traits>
struct i2c_dev
{
public:
   static void init();
   static void send();
   static bool busy();
   ...
private:
   static i2c_transfer periodic_transfer; // class with used-defined constructor
};

// traits class for configuration A
struct i2c_dev_traitsA
{
   enum 
   { 
       I2Cx_BASE    = I2C1_BASE
     , PORTx_BASE   = GPIOB_BASE
     , PORTx_PIN_TX = PB08
     , PORTx_PIN_RX = PB09
   };
};

// traits class for configuration B, different I2C peripherial and pinout
struct i2c_dev_traitsB
{
   enum 
   { 
       I2Cx_BASE    = I2C2_BASE
     , PORTx_BASE …
Run Code Online (Sandbox Code Playgroud)

c++ embedded templates stm32

9
推荐指数
1
解决办法
590
查看次数

排序插入小(255元素)列表

我正在寻找一个合适的算法来构建一个相对较小(最多255个元素)排序的整数数组.目标平台是基于STM32的嵌入式系统.由于存储器是有限的,因此优选就地方法.

我知道显而易见的方法是实现和描述通常的嫌疑人(快速排序,插入sert,shell排序),但是想要问你的经历.更具体地说,我在构建阵列时发现很少有关于性能的信息- 也就是说,不同算法可以使用所有现有元素已经订购的事实.

编辑1: 虽然问题标记为C++,但STL不可用.此外,排序确实发生在内循环内.为了进一步说明,我正在寻找一种特别适合以有效方式构建排序列表的算法.我假设(可能是错误的)必须有专门适合这项任务的算法.这就是问题所在.

编辑2: 当说构建排序列表时,我的意思是列表开始为空,并由16位整数的有界数字(最多255)填充,这些数字没有特定的顺序.必须在存储所有元素后处理该列表.对于处理,必须对列表进行排序,优选地按降序排序.

谢谢,Arne

c c++ sorting algorithm

7
推荐指数
1
解决办法
1461
查看次数

Ada on STM32F4(Cortex-M4)

我只是偶然发现了这篇文章,说明Ada语言的端口存在于Cortex-M4微处理器中.这看起来令人兴奋,但不幸的是我在AdaCore上没有发现这样的迹象.

我们的目标是STM32F407或STMF417裸机.Ada的实时扩展对我们来说至关重要.

我们最好使用工具的GPL版本.但是,作为一所大学,我们可以访问相应大学版的开发套件.

任何人都可以在Cortex-M4甚至STM32上与Ada分享经验吗?

我最终找到了正确的下载,甚至包括STM32F4的示例项目.凉.

ada bare-metal stm32 cortex-m

7
推荐指数
1
解决办法
2975
查看次数

Ada中的任意长度整数

我目前正在教自己Ada,虽然我可以从解决一些更传统的问题开始.

更具体地说,我尝试计算阶乘n !,而n> 100.到目前为止,我的实施是:

with Ada.Text_IO;
with Ada.Integer_Text_IO;

use Ada.Text_IO;

procedure Factorial is 
    -- define a type covering the range beginning at 1 up to which faculty is to
    -- be computed.
    subtype Argument is Long_Long_Integer range 1..100;

    -- define a type that is large enough to hold the result
    subtype Result is Long_Long_Integer range 1..Long_Long_Integer'Last;
    package Result_IO is new Ada.Text_IO.Integer_IO(Result); use Result_IO;

    -- variable holding the faculty calculated.
    fac : Result := 1;

begin
    -- loop over whole range …
Run Code Online (Sandbox Code Playgroud)

ada

6
推荐指数
1
解决办法
2370
查看次数

libusb中断传输

我需要对定制 HID USB 设备(控制面板上的一些按钮和 LED)驱动程序进行逆向工程。该驱动程序仅在 Windows 上可用,我们需要 *nix 实现。

该设备显然是 HID 设备,尽管不属于特定类别。它提供两个接口,每个接口都有一个中断端点。

我的设置当前涉及在 Ubuntu 主机上运行 Windows 的 VirtualBox,以通过 Wireshark 捕获 USB 流量。该协议相当简单,我已经有了很好的理解。

我在一个简单的 C++ 控制台程序中使用 libusb-1.0 进行原型设计。我已经设法通过发出 SET_REPORT 控制传输来切换 LED,但在通过传输中断接收按钮按下时遇到了困难。

事实上,以下调用将永远阻塞:

unsigned char bytes[8] = { 0 };
int len = 0;
int ret = libusb_interrupt_transfer(handle, 0x81, bytes, 8, &len, 0); 
Run Code Online (Sandbox Code Playgroud)

在 Wireshark 中检查生成的 URB 时,它看起来与在 Windows 会话中捕获的等效内容完全相同。但我仍然没有收到设备的回复。

我觉得我缺少一些设置。请注意,设备已正确打开,并且设备提供的两个接口已成功声明。即使在我的 Linux 应用程序中,通过控制传输的输入报告也会出现。

感谢您的指点!阿内

附录一:我想知道在使用时我应该如何指定我想要接收的报告ID libusb_interrupt_transfer()

附录二:将 Windows 驱动程序发出的请求与 Wireshark 中上述代码生成的请求进行比较时,我没有看到任何差异(URB 中的值相同)。但是,只有当 Windows 驱动程序发出中断传输时才会返回。

在 Wireshark 中检查 Windows 驱动程序通信时,除了各种GET_DESCRIPTOR(...). …

c c++ linux usb libusb

6
推荐指数
1
解决办法
2万
查看次数

在菜单项中嵌入文本框

这是一个概念验证问题。我正在设计一个 GUI,用于在飞行模拟应用程序中编辑空中交通参与者的航路点。在当前的概念中,所选航路点的参数显示在一堆文本框中。该输入掩码既充当数据视图又充当编辑掩码。编辑字段后,用户可以:

  • 保存对路径点的更改
  • 根据输入创建新的路径点

如果仅需要为新路径点更改某些参数子集,则此设计可以避免重新输入数据。

只有一个问题:在哪里插入路径点?我的答案是“另存为新”按钮上的下拉菜单,其中包含以下菜单项:

  • 作为飞行计划的第一个航路点
  • 所选航路点之前的位置
  • 选定航路点后
  • 作为飞行计划的最后一个航点
  • 在索引位置

最后一项是棘手的。索引位置需要由用户输入,我想避免弹出窗口只要求单个值。

我的想法是:将文本框嵌入到菜单项中。

这种方法在 QT 或 wxWidgets 中可行吗?您对 GUI 设计有何看法?

问候,阿恩

PS:请注意,这一切都处于概念阶段。该小组甚至还没有决定使用哪种 GUI 框架:Qt 或 wxWidgets。

qt wxwidgets qt4

5
推荐指数
1
解决办法
2085
查看次数

从std:string派生以添加typedef和enums

对于客户端和服务器之间交换的UDP包,我想支持两种字符串字段:

  • 以null结尾的c-string命名 cstring
  • 前面写有uint8_tsize-field的字符串vstring

要自我记录我们的包的布局,我想使用简单的结构声明:

struct ABC {
  vstring a;
  cstring b;
}
Run Code Online (Sandbox Code Playgroud)

并调用重载函数get(char*, vstring& v)get(char*, cstring&)内部de /序列化函数,如下所示:

void deserialize(const char* bytes, ABC& msg) {
  get(msg.a);
  get(msg.b);
}

void serialize(char* bytes, const ABC& msg) {
  put(msg.a);
  put(msg.b);
}
Run Code Online (Sandbox Code Playgroud)

但是,对于用户而言vstring,cstring理想情况下应该像正常一样std::string.

我的第一个想法是简单地进行std::string的民意基础vstring,并cstring使得两个类可以超载解析期间,disriminated而是表现为用户相同.但由于std::string劝阻,我不确定该怎么办.

c++ inheritance stdstring c++11

5
推荐指数
1
解决办法
157
查看次数

使用const double作为中间结果

我正在编写一个模拟程序,并想知道在存储中间结果时是否使用const double是有用的.请考虑以下代码段:

double DoSomeCalculation(const AcModel &model) {
   (...)
   const double V = model.GetVelocity();
   const double m = model.GetMass();
   const double cos_gamma = cos(model.GetFlightPathAngleRad());
   (...)
   return m*V*cos_gamma*Chi_dot;
}
Run Code Online (Sandbox Code Playgroud)

请注意,样本仅用于说明 - 从工程方面来看,它可能没有多大意义.在变量中存储例如cos_gamma的动机是这个余弦在(...)覆盖的其他表达式中多次使用,我觉得代码在使用时更易读

cos_gamma 
Run Code Online (Sandbox Code Playgroud)

而不是

cos(model.GetFlightPathAngleRad())
Run Code Online (Sandbox Code Playgroud)

用各种表达方式.现在问题是这样的:因为我希望余弦在代码部分是相同的,我实际上只是作为占位符创建了东西,为了方便起见,我倾向于将它声明为const.是否有关于这是好还是坏的实际意见,或者它最终是否会咬我?编译器是否使用了这些附加信息,或者我是否真的阻碍了编译器执行有用的优化?

阿恩

c++ const

4
推荐指数
1
解决办法
257
查看次数

模板功能专业化问题

我正在使用模板来实现从int到enum的范围检查转换。看起来像这样:

template<typename E>
E enum_cast(const int &source);
Run Code Online (Sandbox Code Playgroud)

模板功能或多或少地位于项目的根目录中。当定义一个新的枚举时,可以像这样从配置文件中分配值:

enum ConfigEnum {
    ConfigEnumOption1 = 'A'
  , ConfigEnumOption2 = 'B'
  , ConfigEnumInvalid };

ConfigEnum option = XmlNode.iAttribute("option");
Run Code Online (Sandbox Code Playgroud)

我在使用此枚举的模块的.cpp文件中为此特定枚举类型定义了模板专用化。

template<>
ConfigEnum enum_cast(const int &source) {
   switch(source) {
   case ConfigEnumOption1 : return ConfigEnumOption1;
   case ConfigEnumOption2 : return ConfigEnumOption2;
   default return ConfigEnumInvalid;
}
Run Code Online (Sandbox Code Playgroud)

现在,将int分配给枚举变为:

ConfigEnum option = enum_cast<ConfigEnum>(XmlNode.iAttribute("option"));
Run Code Online (Sandbox Code Playgroud)

这样可以确保枚举始终在有效范围内。请注意,我没有始终控制这些枚举,因此这似乎是一个合理且易于配置的解决方案。

无论如何,这一切都很好(尽管我不能保证这里给出的所有代码都是正确的,因为我现在只是从内存中调用它)

问题源于这样一个事实,即在将in分配给枚举时可能不希望在代码库中使用此“ enum_cast”构造。毕竟,这可以通过简单的搜索和替换操作来实施。当然,我不想为所有枚举定义这些专业化知识,而只是为那些目前需要范围检查的人定义。我宁愿在需要时为枚举类型添加模板专业化,而在未定义专业化时使用赋值运算符。

从而:

InternalEnum internal = enum_cast<InternalEnum>(internal_integer);
Run Code Online (Sandbox Code Playgroud)

有效地调用internal = internal_integer。我认为我需要告诉编译器对所有没有专门化的枚举类型使用某种“默认”实现。

我的第一个选择是给原始模板函数一个这样的实现:

template<typename E>
E enum_cast(const int &source) {
  E copy = source;
  return copy;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ enums

3
推荐指数
1
解决办法
517
查看次数

删除大小为1的数组

这可能是单行答案的候选人.无论如何我想知道..

我正在编写一个简单的循环缓冲区,由于某些原因,这对于我需要使用双精度数组实现它的问题并不重要.事实上,我没有研究其他方法,但是因为无论如何都需要阵列,所以我没有花太多时间寻找替代方案.

template<typename T>
class CircularBuffer
{
public:
    CircularBuffer(unsigned int size);
    ~CircularBuffer();
    void Resize(unsigned int new_size);
    ...
private:
    T* buffer;
    unsigned int buffer_size;
};
Run Code Online (Sandbox Code Playgroud)

由于我需要动态调整缓冲区大小,因此buffer_size既不const是模板参数也不是模板参数.现在的问题是:

在构造和功能期间,Resize(int)我只要求大小至少为1,尽管大小为1的缓冲区实际上不再是缓冲区.当然,使用简单的双重替代会更合适,但无论如何.

现在当在析构函数中删除内部缓冲区时 - 或者在函数调整大小时 - 我需要删除分配的内存.问题是,怎么样?第一个候选者当然是delete[] buffer;然后再次,如果我已经分配了一个大小为1的缓冲区,即如果指针被获取buffer = new T[0],是否仍然适合调用delete[]指针或我是否需要调用delete buffer;(没有括号)?

谢谢,阿恩

c++ memory-management

3
推荐指数
3
解决办法
1644
查看次数

在STM32上编写Flash

我在执行上的闪存一个STM32微处理器仿真EEPROM,主要是由ST基础上,应用笔记(AN2594 - 在STM32F10x微控制器EEPROM仿真).

其中的基本概述以及相应的数据手册和编程手册(PM0075)非常清楚.但是,我不确定电源输出/系统复位对闪存编程和页面擦除操作的影响.AppNote也考虑了这种情况,但没有说明编程(写)操作中断时到底发生了什么:

  1. 地址是否具有任意(随机)值?要么
  2. 只写了一部分位?要么
  3. 它有默认的擦除值0xFF吗?

感谢您提供相关文档的提示或指示.

阿恩

c microcontroller stm32

3
推荐指数
1
解决办法
7161
查看次数