【问题标题】:Stopping watchdog timer from global object constructor从全局对象构造函数停止看门狗定时器
【发布时间】:2019-06-09 17:09:45
【问题描述】:

我正在将许多 C 驱动程序集成到一个 C++ 集成嵌入式项目中。 转向 OOP 方法,我将函数和变量组织到类中,每个类代表一个系统模块。

声明全局对象,包含编译器 RTS 库启动代码,以便在程序执行到达 main() 之前使用它们的构造函数构建它们。 这会延迟 watchdog_timer 禁用,这是从 main() 调用的,因此系统不会启动。

我有一个全局对象,其中包含其他对象作为成员,每个对象都有其重要的构造函数;在全局对象构造函数开始时停止看门狗定时器并不能解决问题。

如何解决这个问题?

【问题讨论】:

  • 我建议重新设计以尽量减少全局变量的使用。全局对象引入了一大堆问题,例如未指定的构造顺序。在禁用看门狗计时器后,我将在main() 中创建所有对象。这也使您可以更轻松地显式控制对象的构造顺序。这确实意味着您需要找到一种方法将对象(或指向它们的指针/引用)传递给需要它们的代码,但这在实践中相对简单。

标签: c++ initialization watchdog


【解决方案1】:

创建一个WatchDog 类来处理启动、停止和踢它。如果你必须使用一个大的全局然后实例化WatchDog 作为第一个成员。它的构造函数应该关闭看门狗。在main 中,您可以在一切准备好运行时启动它。

同意这样的评论,即拥有一个巨大的全局类是一种糟糕的代码气味。我已经完成了一堆大大小小的嵌入式系统,而无需使用全局变量。

【讨论】:

  • 您是如何管理中断处理程序以访问对象成员的?避免单个巨型类对我来说听起来很明智,但我需要使用全局/全局指针来制作如下函数: extern void TA0_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler")));访问成员。
  • 这是一个很难回答的问题,因为有多种因素。你的系统有多大?该处理器的编译器如何处理中断? (您已经展示了。)有 RTOS 吗?在有限的评论空间中,无法充分解决它,因此 SO 不希望长评论线程来解决它。一种基本方法是记录数据并设置标志的全局杠杆中断功能。当您需要数据时,您检查标志以查看是否有新数据,读取它并重置标志。编译器可能允许您使用静态类成员函数来封装数据。
【解决方案2】:

如果在第一个成员对象构造函数的开头执行相同的指令,则问题似乎解决了,该构造函数在容器类之前调用​​。

我们来上课:

class A
{
    object B;
    object C;
    object D;
    // ...

public:
    A(void);
    // ...
};

A::A()
{
    Stop_WatchDog();
    // ...
}

类似下面的代码会重现该问题:

A myContainerObject;

int main()
{
   Stop_WatchDog();
}

除非B 更改为:

class B
{
    // ...
public:
    B(void);
    // ...
}

B::B()
{
    Stop_WatchDog();
    // ...
}

因此,一般来说,看门狗定时器应该在程序首次初始化的全局对象的第一个成员构造函数开始时停止。

【讨论】:

  • 您看到的原因是所有成员的构造函数(BCD 等)在包含 A 的构造函数之前被调用。如果您需要停止看门狗定时器以构造对象,那么您需要保证在看门狗定时器停止之前没有构造任何对象。 A 的构造函数中不会发生这种情况,因为它在其他构造函数之后。
猜你喜欢
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多