如何避免使用“extern”在C中的多个文件之间共享实例?

时间:2017-02-22 23:54:55

标签: c embedded avr

我在c中创建了一个计时器库来启动一个计时器,停止它......等等。我使用这个lib为不同的事件制作许多计时器。对于每个事件,我应该创建一个新的计时器实例。我使用一个带有串行通信库,一个用于键盘库。现在重点是必须通过微控制器的timer1中断程序为每个实例调用一个函数timer_interrupt_handler(New_timer* timer),该程序保留在主文件中。为此,计时器的实例必须是外部类型。有没有办法避免在这种情况下使用extern。

timer_tick.h文件

typedef enum state{STOPPED=0, RUNNING, TIMEOUT} Timer_state;

typedef struct {
        unsigned char volatile state;
        unsigned int volatile ticks;
        unsigned int volatile timeout_ticks;
    }New_timer;

timer_tick.c文件

#include "timer_tick.h"

void start_a_timer(New_timer* timer)
{
    timer->state = RUNNING;
    timer->ticks = 0;
}

void stop_a_timer(New_timer* timer)
{
    timer->state = STOPPED;
}

void timer_interrupt_handler(New_timer* timer)
{
    if(timer->state==RUNNING)
    {
        if(timer->ticks < timer->timeout_ticks)
            timer->ticks++;
        else
            timer->state = TIMEOUT;
    }
}

的main.c

// timer1 interrupt routine
void timerIsr()
{
    timer_interrupt_handler(&timer1);
    timer_interrupt_handler(&timer2);
    timer_interrupt_handler(&timer3);
    timer_interrupt_handler(&timer4);
    timer_interrupt_handler(&timer5);
}

2 个答案:

答案 0 :(得分:5)

为什么不使用链接列表在计时器模块中注册实例?

在客户代码

static New_timer a_timer;
void foo () {
    timer_register (&a_timer);
};

在timer.c:

void timer_register (New_timer * timer) {
    timer_add_to_a_linked_list (timer);
}

void timer_interrupt_handler () {
    for_each_timer_in_list_do_something ();
}

答案 1 :(得分:0)

在许多情况下,您可以通过使用 getter 函数来避免使用extern

在client.h中:

#include "timer_tick.h"

New_timer* client_get_timer(void);

在client.c中:

#include "client.h"

New_timer local_timer;

New_timer* client_get_timer()
{
    return &local_timer;
}

在main.c中:

#include "client.h"

void timerIsr()
{
    timer_interrupt_handler(client_get_timer());
}