You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写含switch case的C程序,选择编译运行两个指定Contiki C程序

实现Contiki应用切换方案

要实现通过switch case逻辑选择运行MQTT-SN或CoAP应用,需要结合Contiki的进程模型和编译机制改造原有代码,具体步骤如下:

1. 改造原有应用,封装启动接口

两个原有程序都是独立的Contiki应用,需将核心逻辑封装为可外部调用的启动函数,同时移除自动启动进程的配置。

处理main_core.c(MQTT-SN应用)

  • 在contiki/mqtt-sn-contiki_examples目录下创建main_core.h头文件:
#ifndef MAIN_CORE_H
#define MAIN_CORE_H

#include "contiki.h"

// 声明MQTT-SN应用的启动函数
void main_core_start(void);

#endif /* MAIN_CORE_H */
  • 修改main_core.c,将核心逻辑封装进进程,并通过启动函数触发:
#include "contiki.h"
#include "main_core.h"

// 保留原有进程定义
PROCESS(mqtt_sn_core_process, "MQTT-SN Core Process");

// 启动函数:启动MQTT-SN核心进程
void main_core_start(void) {
  process_start(&mqtt_sn_core_process, NULL);
}

// 原有进程逻辑保持不变
PROCESS_THREAD(mqtt_sn_core_process, ev, data) {
  PROCESS_BEGIN();
  
  // 此处保留原main_core.c中的进程处理代码
  
  PROCESS_END();
}

// 注释或删除原有自动启动宏(否则会自动启动)
// AUTOSTART_PROCESSES(&mqtt_sn_core_process);

处理coap_server.c(CoAP应用)

  • 在contiki/examples/cc26xx/cc26xx-web-demo目录下创建coap_server.h头文件:
#ifndef COAP_SERVER_H
#define COAP_SERVER_H

#include "contiki.h"

// 声明CoAP服务器的启动函数
void coap_server_start(void);

#endif /* COAP_SERVER_H */
  • 修改coap_server.c,封装启动函数并移除自动启动:
#include "contiki.h"
#include "coap_server.h"

// 保留原有进程定义
PROCESS(coap_server_process, "CoAP Server Process");

// 启动函数:启动CoAP服务器进程
void coap_server_start(void) {
  process_start(&coap_server_process, NULL);
}

// 原有进程逻辑保持不变
PROCESS_THREAD(coap_server_process, ev, data) {
  PROCESS_BEGIN();
  
  // 此处保留原coap_server.c中的进程处理代码
  
  PROCESS_END();
}

// 注释或删除原有自动启动宏
// AUTOSTART_PROCESSES(&coap_server_process);

2. 创建应用选择程序

在contiki/examples/ipv6/rpl-border-router目录下创建app_selector.c,实现switch case选择逻辑,分两种场景:

场景1:编译时选择应用(通过Makefile宏控制)

适合固定场景部署,编译时指定要运行的应用:

#include "contiki.h"
#include "main_core.h"
#include "coap_server.h"
#include <stdio.h>

PROCESS(app_selector_process, "App Selector Process");

// 自动启动选择器进程
AUTOSTART_PROCESSES(&app_selector_process);

PROCESS_THREAD(app_selector_process, ev, data) {
  PROCESS_BEGIN();

  // 根据编译宏选择启动对应应用
  #ifdef RUN_MQTT_APP
    printf("Starting MQTT-SN Core Application...\n");
    main_core_start();
  #elif RUN_COAP_APP
    printf("Starting CoAP Server Application...\n");
    coap_server_start();
  #else
    printf("Error: No application selected! Use RUN_MQTT_APP or RUN_COAP_APP macro.\n");
  #endif

  PROCESS_END();
}

int main(void) {
  process_run();
  return 0;
}

场景2:运行时选择应用(通过串口输入切换)

适合调试或动态切换场景,通过串口输入1/2选择应用:

#include "contiki.h"
#include "uart0.h"
#include "main_core.h"
#include "coap_server.h"
#include <stdio.h>

PROCESS(app_selector_process, "App Selector Process");
PROCESS(serial_input_process, "Serial Input Handler");

AUTOSTART_PROCESSES(&app_selector_process);

static uint8_t selected_app = 0;

PROCESS_THREAD(app_selector_process, ev, data) {
  PROCESS_BEGIN();

  // 提示用户选择应用
  printf("\n=== Application Selector ===\n");
  printf("1. Start MQTT-SN Core\n");
  printf("2. Start CoAP Server\n");
  printf("Enter your choice: ");

  // 启动串口输入处理进程
  process_start(&serial_input_process, NULL);

  // 等待选择信号
  while(1) {
    PROCESS_WAIT_EVENT();
    if(ev == PROCESS_EVENT_POLL && selected_app != 0) {
      switch(selected_app) {
        case 1:
          printf("\nStarting MQTT-SN Core...\n");
          main_core_start();
          break;
        case 2:
          printf("\nStarting CoAP Server...\n");
          coap_server_start();
          break;
        default:
          printf("\nInvalid choice! Enter 1 or 2: ");
          selected_app = 0;
          continue;
      }
      break; // 选择完成后退出循环
    }
  }

  PROCESS_END();
}

// 串口输入处理进程
PROCESS_THREAD(serial_input_process, ev, data) {
  PROCESS_BEGIN();

  uart0_init(); // 初始化串口(根据硬件调整,比如uart1)

  while(1) {
    char input_char;
    // 读取串口输入
    if(uart0_read_byte(&input_char)) {
      if(input_char >= '1' && input_char <= '2') {
        selected_app = input_char - '0';
        process_poll(&app_selector_process); // 通知选择器进程
      } else {
        printf("\nInvalid input! Enter 1 or 2: ");
      }
    }
    PROCESS_YIELD();
  }

  PROCESS_END();
}

int main(void) {
  process_run();
  return 0;
}

3. 修改Makefile配置

在contiki/examples/ipv6/rpl-border-router/Makefile中添加以下配置,确保编译器能找到头文件和源文件:

# 添加头文件搜索路径
INCLUDE_DIRS += -I$(CONTIKI)/mqtt-sn-contiki_examples
INCLUDE_DIRS += -I$(CONTIKI)/examples/cc26xx/cc26xx-web-demo

# 添加两个应用的源文件
CONTIKI_SOURCEFILES += $(CONTIKI)/mqtt-sn-contiki_examples/main_core.c
CONTIKI_SOURCEFILES += $(CONTIKI)/examples/cc26xx/cc26xx-web-demo/coap_server.c

# 链接依赖库(根据应用需求添加)
# MQTT-SN依赖
MODULES += os/net/app-layer/mqtt-sn
# CoAP依赖
MODULES += os/net/app-layer/coap

# 编译时选择应用的宏定义(场景1用)
# 编译MQTT应用:make RUN_MQTT_APP=1 TARGET=xxx
# 编译CoAP应用:make RUN_COAP_APP=1 TARGET=xxx
ifeq ($(RUN_MQTT_APP),1)
  CFLAGS += -DRUN_MQTT_APP
endif
ifeq ($(RUN_COAP_APP),1)
  CFLAGS += -DRUN_COAP_APP
endif

注意事项

  • 若两个应用存在资源冲突(如占用同一网络端口、硬件外设),运行时切换可能导致异常,建议优先使用编译时选择方案。
  • 不同硬件平台的串口初始化可能不同,比如CC2650可能用uart_init()而非uart0_init(),需根据目标平台调整。
  • 原有应用中的全局变量、定时器等资源需确保不会在切换时产生冲突,必要时添加资源清理逻辑。

内容的提问来源于stack exchange,提问作者Tufail Gulzar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:10:32