如何编写含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
相关产品推荐
相关产品推荐

