BLE RX 명령 큐 모듈 분리
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
/*******************************************************************************
|
||||
* @file ble_cmd_queue.c
|
||||
* @brief BLE RX command queue
|
||||
******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include "ble_cmd_queue.h"
|
||||
#include "debug_print.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define BLE_CMD_MAX_LEN 256
|
||||
#define BLE_CMD_QUEUE_DEPTH 8 // RX command ring buffer depth
|
||||
#define BLE_CMD_WORKQ_STACK_SZ 8192
|
||||
#define BLE_CMD_WORKQ_PRIORITY 10
|
||||
|
||||
static struct k_work_q ble_cmd_work_q;
|
||||
K_THREAD_STACK_DEFINE(ble_cmd_workq_stack, BLE_CMD_WORKQ_STACK_SZ);
|
||||
static struct k_work ble_cmd_work; // BLE command worker
|
||||
static struct k_spinlock ble_cmd_lock; // RX queue lock
|
||||
|
||||
static uint8_t ble_cmd_q_buf[BLE_CMD_QUEUE_DEPTH][BLE_CMD_MAX_LEN]; // command data
|
||||
static uint16_t ble_cmd_q_len[BLE_CMD_QUEUE_DEPTH]; // command length
|
||||
static uint8_t ble_cmd_q_head; // next pop slot
|
||||
static uint8_t ble_cmd_q_tail; // next push slot
|
||||
static uint8_t ble_cmd_q_count; // queued command count
|
||||
|
||||
/* Queue에 쌓인 BLE 명령을 parser로 전달 */
|
||||
static void ble_cmd_work_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
|
||||
uint8_t local_buf[BLE_CMD_MAX_LEN];
|
||||
uint16_t local_len;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
k_spinlock_key_t key = k_spin_lock(&ble_cmd_lock);
|
||||
if (ble_cmd_q_count == 0U)
|
||||
{
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
break;
|
||||
}
|
||||
|
||||
local_len = ble_cmd_q_len[ble_cmd_q_head];
|
||||
memcpy(local_buf, ble_cmd_q_buf[ble_cmd_q_head], local_len);
|
||||
ble_cmd_q_head = (uint8_t)((ble_cmd_q_head + 1U) % BLE_CMD_QUEUE_DEPTH);
|
||||
ble_cmd_q_count--;
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
|
||||
if (local_len == 0U)
|
||||
{
|
||||
DBG_ERR("[BLE RX] worker: empty\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ble_cmd_dispatch(local_buf, local_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* BLE RX 명령 처리 queue 초기화 */
|
||||
void ble_cmd_queue_init(void)
|
||||
{
|
||||
k_work_init(&ble_cmd_work, ble_cmd_work_handler);
|
||||
k_work_queue_start(&ble_cmd_work_q, ble_cmd_workq_stack, K_THREAD_STACK_SIZEOF(ble_cmd_workq_stack), BLE_CMD_WORKQ_PRIORITY, NULL);
|
||||
}
|
||||
|
||||
/* BLE RX 콜백에서 호출되는 명령 enqueue 함수 */
|
||||
void ble_cmd_queue_rx_handler(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
if (len > BLE_CMD_MAX_LEN)
|
||||
{
|
||||
DBG_ERR("[BLE RX] drop: len=%u exceeds %d\r\n", len, BLE_CMD_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&ble_cmd_lock);
|
||||
if (ble_cmd_q_count >= BLE_CMD_QUEUE_DEPTH)
|
||||
{
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
DBG_ERR("[BLE RX] drop: queue full\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ble_cmd_q_buf[ble_cmd_q_tail], data, len);
|
||||
ble_cmd_q_len[ble_cmd_q_tail] = len;
|
||||
ble_cmd_q_tail = (uint8_t)((ble_cmd_q_tail + 1U) % BLE_CMD_QUEUE_DEPTH);
|
||||
ble_cmd_q_count++;
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
|
||||
int err = k_work_submit_to_queue(&ble_cmd_work_q, &ble_cmd_work);
|
||||
if (err < 0)
|
||||
{
|
||||
DBG_ERR("[BLE RX] queue submit fail err=%d\r\n", err);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*******************************************************************************
|
||||
* @file ble_cmd_queue.h
|
||||
* @brief BLE RX command queue
|
||||
******************************************************************************/
|
||||
#ifndef BLE_CMD_QUEUE_H__
|
||||
#define BLE_CMD_QUEUE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void ble_cmd_queue_init(void);
|
||||
void ble_cmd_queue_rx_handler(const uint8_t *data, uint16_t len);
|
||||
|
||||
#endif /* BLE_CMD_QUEUE_H__ */
|
||||
+3
-107
@@ -14,24 +14,12 @@
|
||||
#include "led_control.h"
|
||||
#include "ble_service.h"
|
||||
#include "battery_adc.h"
|
||||
#include "parser.h"
|
||||
#include "ble_cmd_queue.h"
|
||||
#include "imu_i2c.h"
|
||||
#include "piezo_measure.h"
|
||||
|
||||
LOG_MODULE_REGISTER(vesiscan, LOG_LEVEL_INF);
|
||||
|
||||
#define BLE_CMD_MAX_LEN 256
|
||||
#define BLE_CMD_QUEUE_DEPTH 8 // RX 명령 링버퍼 깊이(버스트 흡수)
|
||||
#define BLE_CMD_WORKQ_STACK_SZ 8192
|
||||
/*
|
||||
* BLE 명령 처리 스택
|
||||
* - piezo sweep
|
||||
* - ADC capture
|
||||
* - BLE 응답 패킷 조립
|
||||
* - 디버깅 여유분 포함
|
||||
*/
|
||||
#define BLE_CMD_WORKQ_PRIORITY 10
|
||||
|
||||
volatile bool ble_connection_st = false; // BLE 연결 상태
|
||||
volatile bool processing = false; // 센서 데이터 처리 중 플래그
|
||||
bool bond_data_delete = true; // 본딩 데이터 삭제 요청
|
||||
@@ -46,87 +34,6 @@ static bool resume_without_power_button; // 리셋 후 버튼 없이 복귀
|
||||
static bool dfu_confirm_pending_boot; // DFU test 이미지 확인 전 자동 복귀
|
||||
static bool dfu_reset_resume_request; // DFU 완료 리셋 후 자동 복귀
|
||||
static uint32_t boot_reset_reason; // RESETREAS 원본 값
|
||||
static struct k_work_q ble_cmd_work_q;
|
||||
K_THREAD_STACK_DEFINE(ble_cmd_workq_stack, BLE_CMD_WORKQ_STACK_SZ);
|
||||
static struct k_work ble_cmd_work; // BLE 명령 처리 work
|
||||
static struct k_spinlock ble_cmd_lock; // RX 큐 보호
|
||||
|
||||
// RX 명령 링버퍼: 들어온 순서대로 쌓고 워커가 순차 처리 (head=꺼낼 위치, tail=넣을 위치)
|
||||
static uint8_t ble_cmd_q_buf[BLE_CMD_QUEUE_DEPTH][BLE_CMD_MAX_LEN]; // 명령 데이터
|
||||
static uint16_t ble_cmd_q_len[BLE_CMD_QUEUE_DEPTH]; // 각 명령 길이
|
||||
static uint8_t ble_cmd_q_head; // 다음에 꺼낼 슬롯
|
||||
static uint8_t ble_cmd_q_tail; // 다음에 넣을 슬롯
|
||||
static uint8_t ble_cmd_q_count; // 큐에 쌓인 명령 수
|
||||
|
||||
static void ble_cmd_work_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
|
||||
// work queue 로컬 복사본
|
||||
uint8_t local_buf[BLE_CMD_MAX_LEN];
|
||||
uint16_t local_len;
|
||||
|
||||
// 큐가 빌 때까지 head에서 하나씩 꺼내 순차 처리 (dispatch는 락 밖에서)
|
||||
for (;;)
|
||||
{
|
||||
k_spinlock_key_t key = k_spin_lock(&ble_cmd_lock);
|
||||
if (ble_cmd_q_count == 0U)
|
||||
{
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
break;
|
||||
}
|
||||
local_len = ble_cmd_q_len[ble_cmd_q_head];
|
||||
memcpy(local_buf, ble_cmd_q_buf[ble_cmd_q_head], local_len);
|
||||
ble_cmd_q_head = (uint8_t)((ble_cmd_q_head + 1U) % BLE_CMD_QUEUE_DEPTH);
|
||||
ble_cmd_q_count--;
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
|
||||
if (local_len == 0U)
|
||||
{
|
||||
DBG_ERR("[BLE RX] worker: empty\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 일반 스레드 문맥 명령 처리
|
||||
//DBG_CORE("[BLE RX] worker dispatch len=%u\r\n", local_len);
|
||||
ble_cmd_dispatch(local_buf, local_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* BLE RX 콜백 */
|
||||
static void ble_rx_handler(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
if (len > BLE_CMD_MAX_LEN)
|
||||
{
|
||||
DBG_ERR("[BLE RX] drop: len=%u exceeds %d\r\n", len, BLE_CMD_MAX_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// 공유 RX 큐 보호: tail 슬롯에 명령 적재 (FIFO)
|
||||
k_spinlock_key_t key = k_spin_lock(&ble_cmd_lock);
|
||||
if (ble_cmd_q_count >= BLE_CMD_QUEUE_DEPTH)
|
||||
{
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
DBG_ERR("[BLE RX] drop: queue full\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 명령 버퍼 복사
|
||||
memcpy(ble_cmd_q_buf[ble_cmd_q_tail], data, len);
|
||||
ble_cmd_q_len[ble_cmd_q_tail] = len;
|
||||
ble_cmd_q_tail = (uint8_t)((ble_cmd_q_tail + 1U) % BLE_CMD_QUEUE_DEPTH);
|
||||
ble_cmd_q_count++;
|
||||
k_spin_unlock(&ble_cmd_lock, key);
|
||||
|
||||
// 명령 처리 work 예약 (워커는 큐가 빌 때까지 처리하므로 중복 예약은 무해)
|
||||
// 실패해도 항목은 큐에 유효하게 남아 있고, 다음 RX의 submit이 함께 처리하므로 롤백하지 않음
|
||||
int err = k_work_submit_to_queue(&ble_cmd_work_q, &ble_cmd_work);
|
||||
if (err < 0)
|
||||
{
|
||||
DBG_ERR("[BLE RX] queue submit fail err=%d\r\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* 전원 유지 (POWER_HOLD) 제어 */
|
||||
static void boot_context_detect(void)
|
||||
{
|
||||
@@ -197,17 +104,6 @@ static void load_default_config(void)
|
||||
DBG_CORE("[INIT] Default (S/N=%s)\r\n", SERIAL_NO);
|
||||
}
|
||||
|
||||
/* 타이머 초기화 */
|
||||
static void timers_init(void)
|
||||
{
|
||||
|
||||
// BLE 명령 처리 work queue
|
||||
k_work_init(&ble_cmd_work, ble_cmd_work_handler);
|
||||
k_work_queue_start(&ble_cmd_work_q, ble_cmd_workq_stack, K_THREAD_STACK_SIZEOF(ble_cmd_workq_stack), BLE_CMD_WORKQ_PRIORITY, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* 메인 함수 */
|
||||
int main(void)
|
||||
{
|
||||
@@ -232,7 +128,7 @@ int main(void)
|
||||
DBG_CORE("[INIT] HW Init\r\n");
|
||||
// 기본 하드웨어/센서 초기화
|
||||
power_control_init();
|
||||
timers_init();
|
||||
ble_cmd_queue_init();
|
||||
dfu_manager_init();
|
||||
dfu_log_mcuboot_state();
|
||||
load_default_config();
|
||||
@@ -245,7 +141,7 @@ int main(void)
|
||||
|
||||
// BLE 스택 + NUS
|
||||
DBG_CORE("[INIT] BLE Init\r\n");
|
||||
if (ble_service_init(ble_rx_handler) == 0)
|
||||
if (ble_service_init(ble_cmd_queue_rx_handler) == 0)
|
||||
{
|
||||
DBG_CORE("[INIT] BLE - ble/nus OK\r\n");
|
||||
// 소프트 리셋 후 서비스 복구
|
||||
|
||||
Reference in New Issue
Block a user