嵌入式工程师必须掌握的几种系统架构

嵌入式工程师只使用C语言来编写代码,不用考虑面向对象语言那么多的设计模式。但是在实际编程中还是有一些固定的模式要掌握。掌握这些固定的软件架构,不仅可以看懂资深工程师写的代码,还可以用在自己的项目中。

下面就来演示下这些非常重要模式。

第一,分层构架

// 操作系统层
#include 

void operating_system_layer(void) {
    printf("Operating System Layer\n");
    // 操作系统层的处理
}

// 硬件抽象层
void hardware_abstraction_layer(void) {
    printf("Hardware Abstraction Layer\n");
    // 硬件抽象层的处理
    operating_system_layer();  // 硬件抽象层调用操作系统接口
}

// 应用层
void application_layer(void) {
    printf("Application Layer\n");
    // 应用层的处理
    hardware_abstraction_layer();  // 应用层调用硬件抽象层
}

// 主函数
int main(void) {
    // 应用层的调用
    application_layer();

    return 0;
}

这样的设计体现了分层架构的核心思想,使得不同层次的功能清晰划分,提高了代码的可维护性和可扩展性。在实际应用中,每个层次的功能会更加复杂,可能涉及更多的模块和接口设计。通常在阅读操作系统源代码时候,要知道这种分层思想就可以很容易读懂系统代码。

第二,事件驱动架构

#include 

// 事件定义
typedef enum {
    BUTTON_PRESSED,
    TIMER_TIMEOUT,
    SENSOR_DATA_UPDATE,
    NUM_EVENT_TYPES // 用于计数事件类型的总数
} EventType;

// 事件结构体
typedef struct {
    EventType type;
    // 其他事件相关的数据
} Event;

// 事件处理函数
void handle_button_pressed(Event event) {
    printf("Button Pressed Event Handled\n");
    // 处理按钮按下事件的逻辑
}

void handle_timer_timeout(Event event) {
    printf("Timer Timeout Event Handled\n");
    // 处理定时器超时事件的逻辑
}

void handle_sensor_data_update(Event event) {
    printf("Sensor Data Update Event Handled\n");
    // 处理传感器数据更新事件的逻辑
}

// 主循环 - 不断处理事件
int main(void) {
    while (1) {
        // 模拟检查是否有新事件发生
        Event currentEvent = { .type = SENSOR_DATA_UPDATE }; // 模拟传感器数据更新事件

        // 处理事件的选择分支
        switch (currentEvent.type) {
            case BUTTON_PRESSED:
                handle_button_pressed(currentEvent);
                break;
            case TIMER_TIMEOUT:
                handle_timer_timeout(currentEvent);
                break;
            case SENSOR_DATA_UPDATE:
                handle_sensor_data_update(currentEvent);
                break;
            default:
                // 处理未知事件类型或其他逻辑
                break;
        }
    }

    return 0;
}

在这个例子中,主循环会不断迭代,模拟检查是否有新事件发生。根据当前事件的类型,使用 switch 语句选择相应的事件处理函数。实际上,这个过程可能会涉及到中断、事件队列、定时器等硬件或系统的机制,具体实现会因应用的需求而有所不同。

第三,消息传递构架

#include 
#include 
#include 

// 消息结构体
typedef struct {
    int messageType;
    // 其他消息相关的数据
} Message;

// 定义消息队列
#define MAX_QUEUE_SIZE 10

typedef struct {
    Message queue[MAX_QUEUE_SIZE];
    int front;
    int rear;
} MessageQueue;

// 初始化消息队列
void initMessageQueue(MessageQueue* q) {
    q->front = -1;
    q->rear = -1;
}

// 发送消息到队列
void sendMessage(MessageQueue* q, Message message) {
    if ((q->rear + 1) % MAX_QUEUE_SIZE == q->front) {
        printf("Error: Message queue is full.\n");
        return;
    }

    if (q->front == -1) {
        q->front = 0;
        q->rear = 0;
    } else {
        q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
    }

    q->queue[q->rear] = message;
}

// 从队列接收消息
Message receiveMessage(MessageQueue* q) {
    Message emptyMessage = { -1 }; // 空消息,表示队列为空

    if (q->front == -1) {
        printf("Error: Message queue is empty.\n");
        return emptyMessage;
    }

    Message message = q->queue[q->front];

    if (q->front == q->rear) {
        q->front = -1;
        q->rear = -1;
    } else {
        q->front = (q->front + 1) % MAX_QUEUE_SIZE;
    }

    return message;
}

// 任务1:发送消息
void* task1(void* arg) {
    MessageQueue* messageQueue = (MessageQueue*)arg;

    for (int i = 0; i < 5; ++i) {
        Message message = { i };
        sendMessage(messageQueue, message);
        printf("Task 1 sent message: %d\n", i);
        sleep(1);
    }

    pthread_exit(NULL);
}

// 任务2:接收并处理消息
void* task2(void* arg) {
    MessageQueue* messageQueue = (MessageQueue*)arg;

    for (int i = 0; i < 5; ++i) {
        Message receivedMessage = receiveMessage(messageQueue);
        if (receivedMessage.messageType != -1) {
            printf("Task 2 received and processed message: %d\n", receivedMessage.messageType);
        }
        sleep(1);
    }

    pthread_exit(NULL);
}

int main() {
    MessageQueue messageQueue;
    initMessageQueue(&messageQueue);

    pthread_t thread1, thread2;

    // 创建两个线程,分别执行任务1和任务2
    if (pthread_create(&thread1, NULL, task1, (void*)&messageQueue) != 0 ||
        pthread_create(&thread2, NULL, task2, (void*)&messageQueue) != 0) {
        fprintf(stderr, "Error creating threads.\n");
        return 1;
    }

    // 等待两个线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    return 0;
}

消息传递通常涉及到多任务或多线程的场景,其中任务或线程之间通过消息进行通信。上面是一个简单的C语言示例,演示了一个简单的消息队列,一个任务发送消息,另一个任务接收并处理消息。

第四,有限状态机

#include 

// 定义状态
typedef enum {
    STATE_A,
    STATE_B,
    STATE_C,
    NUM_STATES
} State;

// 定义事件
typedef enum {
    EVENT_X,
    EVENT_Y,
    EVENT_Z,
    NUM_EVENTS
} Event;

// 定义状态机结构体
typedef struct {
    State currentState;
} StateMachine;

// 初始化状态机
void initStateMachine(StateMachine* fsm) {
    fsm->currentState = STATE_A; // 初始状态为 STATE_A
}

// 处理事件并执行状态转移
void processEvent(StateMachine* fsm, Event event) {
    switch (fsm->currentState) {
        case STATE_A:
            if (event == EVENT_X) {
                printf("Transition from STATE_A to STATE_B\n");
                fsm->currentState = STATE_B;
            } else {
                printf("Invalid event in STATE_A\n");
            }
            break;
        case STATE_B:
            if (event == EVENT_Y) {
                printf("Transition from STATE_B to STATE_C\n");
                fsm->currentState = STATE_C;
            } else {
                printf("Invalid event in STATE_B\n");
            }
            break;
        case STATE_C:
            if (event == EVENT_Z) {
                printf("Transition from STATE_C to STATE_A\n");
                fsm->currentState = STATE_A;
            } else {
                printf("Invalid event in STATE_C\n");
            }
            break;
        default:
            printf("Unknown state\n");
            break;
    }
}

int main() {
    StateMachine fsm;
    initStateMachine(&fsm);

    // 模拟事件序列
    Event events[] = { EVENT_X, EVENT_Y, EVENT_Z, EVENT_X };
    int numEvents = sizeof(events) / sizeof(events[0]);

    // 处理事件序列
    for (int i = 0; i < numEvents; ++i) {
        processEvent(&fsm, events[i]);
    }

    return 0;
}

有限状态机(Finite State Machine,FSM)是一种形式化的计算模型,对于描述系统的状态和状态之间的转移非常有用。上面是一个简单的C语言示例,演示了一个有限状态机的基本结构和转移过程。

第五,回调函数

#include 

// 定义回调函数类型
typedef void (*CallbackFunction)(void);

// 回调函数1
void callbackFunction1(void) {
    printf("Callback Function 1: Button Pressed\n");
}

// 回调函数2
void callbackFunction2(void) {
    printf("Callback Function 2: Button Released\n");
}

// 模拟外部触发的事件
void simulateExternalEvent(CallbackFunction callback) {
    // 模拟事件触发
    printf("Simulating External Event...\n");
    // 调用回调函数
    callback();
}

int main() {
    // 模拟外部事件触发回调函数1
    simulateExternalEvent(&callbackFunction1);

    // 模拟外部事件触发回调函数2
    simulateExternalEvent(&callbackFunction2);

    return 0;
}

在这个简单的例子中:

  • 我们定义了两个回调函数 callbackFunction1callbackFunction2,分别模拟了按钮按下和按钮释放的事件处理。
  • 使用 simulateExternalEvent 函数来模拟外部触发的事件,这个函数接受一个回调函数作为参数,并在模拟的事件发生时调用该回调函数。
  • main 函数中,我们模拟了两次外部事件触发,分别触发了不同的回调函数。

以上就是非常重要的几种嵌入式架构和模式,实际代码可能会复杂点,但是基本原理都是相同的。这些架构会在工作经常用到,希望对大家有帮助。

你可能感兴趣的:(系统架构,linux,运维)