RTOS系统 -- 原子操作之taskENTER_CRITICAL与无锁队列实现

M4架构RTOS中的原子变量递增和无锁队列

原子变量递增

对于原子变量递增,许多RTOS都会提供相应的API。例如:

FreeRTOS

FreeRTOS 提供了任务同步和互斥的机制,比如二进制信号量、计数信号量和互斥锁。同时,它也提供了原子操作的支持。可以通过taskENTER_CRITICAL()taskEXIT_CRITICAL()宏来实现原子的变量操作。

uint32_t atomicIncrement(volatile uint32_t *ptr) {
    taskENTER_CRITICAL();
    uint32_t newValue = ++(*ptr);
    taskEXIT_CRITICAL();
    return newValue;
}

CMSIS-RTOS

CMSIS-RTOS 提供了osKernelLockosKernelUnlock函数来实现原子操作。

uint32_t atomicIncrement(volatile uint32_t *ptr) {
    osKernelLock();
    uint32_t newValue = ++(*ptr);
    osKernelUnlock();
    return newValue;
}

无锁队列

无锁队列通常通过CAS(Compare And Swap)操作来实现。如果底层硬件支持,这种方法会非常高效。以下是一些典型的实现:

FreeRTOS

FreeRTOS 提供了无锁队列的支持,通过队列(Queue)和流缓冲区(Stream Buffer)。

QueueHandle_t xQueue;
xQueue = xQueueCreate(10, sizeof(int));

// 发送
int valueToSend = 42;
xQueueSend(xQueue, &valueToSend, portMAX_DELAY);

// 接收
int receivedValue;
xQueueReceive(xQueue, &receivedValue, portMAX_DELAY);

CMSIS-RTOS

CMSIS-RTOS 提供了消息队列(Message Queue)和邮件队列(Mail Queue)的支持。

osMessageQueueId_t mid;
mid = osMessageQueueNew(10, sizeof(int), NULL);

// 发送
int valueToSend = 42;
osMessageQueuePut(mid, &valueToSend, 0, 0);

// 接收
int receivedValue;
osMessageQueueGet(mid, &receivedValue, 0, 0);

无锁队列的通用实现

也可以使用CAS操作来实现一个简单的无锁队列。

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct {
    Node* head;
    Node* tail;
} LockFreeQueue;

void enqueue(LockFreeQueue* queue, int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;

    Node* oldTail;
    do {
        oldTail = queue->tail;
    } while (!__sync_bool_compare_and_swap(&(queue->tail->next), NULL, newNode));

    __sync_bool_compare_and_swap(&(queue->tail), oldTail, newNode);
}

int dequeue(LockFreeQueue* queue) {
    Node* oldHead;
    do {
        oldHead = queue->head;
        if (oldHead->next == NULL) return -1;  // Queue is empty
    } while (!__sync_bool_compare_and_swap(&(queue->head), oldHead, oldHead->next));

    int value = oldHead->next->data;
    free(oldHead);
    return value;
}

这些解决方案可以根据具体需求和所使用的RTOS进行选择和调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值