Alarm

android的alarm机制可以让你在app的生命周期之外做一些基于时间的操作,例如周期性的更新mail,天气信息等等。

实作的时候一般是通过alarm manager在具体的时间点或者某一个时间间隔发出intent或者broadcast,另一侧在receiver中执行相关的操作。

创建alarm

在创建alarm的时候需要确定alarm的类型,alarm的时间或者时间间隔(如果你指定的时间已经过去,那么alarm会立刻被触发),到达某个时间时发出什么样的Pending Intent。


alarm有两大类,一是elapsed real time,这个是相对于系统启动时间的时间,二是real time clock(RTC),这是绝对时间。前者适用于隔一段时间执行某个任务,后者适用于在一天中的某个时间执行一个任务。

然后每一类alarm还有一个wake版本,意思是即便当时屏幕是熄灭状态也会唤醒CPU,如果你使用非wake版本就不会唤醒CPU,相应的操作在下次点亮屏幕时才会执行。所以如果对时间要求比较严格需要使用wake版本。

所以总计四种类型:

ELAPSED_REALTIME—Fires the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.
ELAPSED_REALTIME_WAKEUP—Wakes up the device and fires the pending intent after the specified length of time has elapsed since device boot.
RTC—Fires the pending intent at the specified time but does not wake up the device.
RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time.

30分钟后启动隔30分钟再启动

alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        AlarmManager.INTERVAL_HALF_HOUR,    //30mins后执行
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);  //间隔30mins执行

一分钟后,只启动一次

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,    //启动一次使用set而不是setRepeat
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);



alarm的精度:

使用setInexactRepeating会把近似时间的alarm一起触发,这样节省电量;使用setRepeating比较精确。


Cancel alarm

呼叫alarm manager的cancel方法,入参是之前的pending intent。

if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}




在设备启动时创建一个alarm

设备关机时会自动cancel alarm,你可以在设备重启后自动开启alarm。

1,首先要声明权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
2,实现receiver,重新设置alarm

3,在manifest中声明receiver

<receiver android:name=".SampleBootReceiver"
        android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"></action>
    </intent-filter>
</receiver>

enable属性设置为false,意思是必须在程序中手动enable这个receiver它才会收到broadcast,

在程序中enable/disable可以overridemanifest中的值。

ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();


pm.setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);



这是slp_model.h中部分代码: #define ALARM_PLAN_STR_MAX_LEN 16 typedef struct _MSG_ALARM_CHN1_PLAN { SWITCH enabled; char alarm_plan_1[5][ALARM_PLAN_STR_MAX_LEN + 1]; /* 0000-0000,000格式 */ S32 alarm_plan_num; }MSG_ALARM_CHN1_PLAN, *PTR_MSG_ALARM_PLAN; 这是msg_alarm.c中部分代码: LOCAL void msg_alarm_plan_data_model() { /*************************************************************************************/ /********* Desc of /msg_alarm_plan/chn1_msg_alarm_plan *******************************/ /*************************************************************************************/ DS_ARR_DESC(alarm_plan, OPT_TYPE_STRING, MSG_ALARM_CHN1_PLAN, alarm_plan_1); DS_OPT_DESC chn1_msg_alarm_plan_options[] = { DS_SWITCH_OPT(MSG_ALARM_CHN1_PLAN, enabled, OPT_FLAG_NORM), DS_ARR_OPT(MSG_ALARM_CHN1_PLAN, alarm_plan_1, OPT_FLAG_NORM, &alarm_plan), DS_S32_OPT(MSG_ALARM_CHN1_PLAN, alarm_plan_num, OPT_FLAG_NORM), }; DS_SEG_DESC chn1_msg_alarm_plan_segments[] = { DS_STRUCT_SEG("chn1_msg_alarm_plan", SEG_LIM_RW, SEG_GROUP_ROOT, MSG_ALARM_CHN1_PLAN, chn1_msg_alarm_plan_options), }; DS_SECT_DESC chn1_msg_alarm_plan_sections[] = { DS_STRUCT_SECT("chn1_msg_alarm_plan", chn1_msg_alarm_plan_segments), }; /*************************************************************************************/ /********* Desc of /msg_alarm_plan/arming_schedule_sound***************************************/ /*************************************************************************************/ DS_OPT_DESC arming_schedule_info_options[] = { DS_STR_OPT(ARMING_SCHEDULE, monday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, tuesday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, wednesday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, thursday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, friday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, saturday, OPT_FLAG_NORM), DS_STR_OPT(ARMING_SCHEDULE, sunday, OPT_FLAG_NORM), }; DS_SEG_DESC sound_arming_schedule_info_segments[] = { DS_STRUCT_SEG("arming_schedule_sound", SEG_LIM_RW, SEG_GROUP_ROOT, ARMING_SCHEDULE, arming_schedule_info_options), }; DS_SECT_DESC sound_arming_schedule_sections[] = { DS_STRUCT_SECT("arming_schedule_sound", sound_arming_schedule_info_segments), }; /*************************************************************************************/ /********* Desc of /msg_alarm_plan/arming_schedule_light***************************************/ /*************************************************************************************/ DS_SEG_DESC light_arming_schedule_info_segments[] = { DS_STRUCT_SEG("arming_schedule_light", SEG_LIM_RW, SEG_GROUP_ROOT, ARMING_SCHEDULE, arming_schedule_info_options), }; DS_SECT_DESC light_arming_schedule_sections[] = { DS_STRUCT_SECT("arming_schedule_light", light_arming_schedule_info_segments), }; DS_TBL_DESC msg_alarm_plan_tables[] = { DS_STRUCT_TBL("plan", TBL_ATTR_CFG, chn1_msg_alarm_plan_sections), DS_STRUCT_TBL("plan", TBL_ATTR_CFG, sound_arming_schedule_sections), DS_STRUCT_TBL("plan", TBL_ATTR_CFG, light_arming_schedule_sections), }; DS_DAT_MON_DESC msg_alarm_plan_data_monitor[] = { DS_DAT_MON(MSG_ALARM_CHN1_PLAN_PATH, DATA_ATTRI_CHECK), DS_DAT_MON(MSG_ALARM_PLAN_ARMING_SCHEDULE_SOUND_PATH, DATA_ATTRI_CHECK), DS_DAT_MON(MSG_ALARM_PLAN_ARMING_SCHEDULE_LIGHT_PATH, DATA_ATTRI_CHECK), }; DS_MOD_DESC msg_alarm_plan_module = DS_STRUCT_MOD("msg_alarm_plan", msg_alarm_plan_init, msg_alarm_plan_check, NULL, msg_alarm_plan_start, NULL, msg_alarm_plan_tables, msg_alarm_plan_data_monitor); MODULE *module_node = ds_register_module("msg_alarm_plan", &msg_alarm_plan_module); CAP_ASSERT(NULL != module_node); } CAP_INIT(msg_alarm_plan_data_model); 这是alarm_plan_ds.c中的代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <unistd.h> #include "slp_model.h" #include "libds.h" #include "msg_alarm.h" #include "detection_utils.h" #define MSG_ALARM_PLAN_MODULE_NAME "msg_alarm_plan" #define MSG_ALARM_PLAN_TABLE_NAME "plan" #define MSG_ALARM_PLAN_SECTION_NAME "chn1_msg_alarm_plan" /* 存放从ds中读取的数据 */ LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; /* ds get回调函数 */ /* 从ds共享内存中读取,然后填入json字符串 */ S32 ds_cb_get_alarm_plan(struct _DS_HANDLE_CONTEXT *context, JSON_OBJPTR reply_obj) { S32 i = 0; if (NULL == context || NULL == reply_obj) { MSG_ALARM_ERROR("ds_cb_get_alarm_plan: ptr is null"); return ERROR; } /* 从内存中读取并存入g_msg_alarm_plan结构体中 */ if (0 == ds_read(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("read from ds shm fail."); return ERROR; } /* 将enabled配置写入json */ jso_add_string(reply_obj, "enabled", g_msg_alarm_plan.enabled ? "on" : "off"); /* 将alarm_plan_num配置写入json */ jso_add_int(reply_obj, "alarm_plan_num", g_msg_alarm_plan.alarm_plan_num); JSON_OBJPTR alarm_plan_array = jso_new_array(); if(NULL == alarm_plan_array) { MSG_ALARM_ERROR("create new array object fail."); return ERROR; } /* 将alarm_plan_1数组配置写入json */ for (i = 0; i < g_msg_alarm_plan.alarm_plan_num; i++) { jso_array_add(alarm_plan_array, jso_new_string(g_msg_alarm_plan.alarm_plan_1[i])); } jso_obj_add(reply_obj, "alarm_plan_1", alarm_plan_array); /* 调试:打印json字符串 */ MSG_ALARM_DEBUG(" JSON %s",json_object_to_json_string(reply_obj)); return OK; } /* ds set回调函数 */ /* 解析json字符串,然后填入ds共享内存 */ S32 ds_cb_set_alarm_plan(struct _DS_HANDLE_CONTEXT *context, U8 method, const char* section_name, JSON_OBJPTR req_obj, BOOL is_table) { S32 i = 0; S32 ret = OK; const char *json_value_str = NULL; if (NULL == context || NULL == section_name || NULL == req_obj) { MSG_ALARM_ERROR("ptr is null"); return ERROR; } /* 从json中获取enable配置值 */ json_value_str = jso_obj_get_string_origin(req_obj, "enabled"); if (NULL == json_value_str) { MSG_ALARM_ERROR("jso_obj_get_string_origin key-enable return NULL"); return ERROR; } g_msg_alarm_plan.enabled = 0; if (0 == strcmp(json_value_str, "on")) { g_msg_alarm_plan.enabled = 1; } /* 从json中获取alarm_plan_num配置值 */ if (!jso_obj_get_int(req_obj, "alarm_plan_num", &g_msg_alarm_plan.alarm_plan_num)) { MSG_ALARM_ERROR("jso_obj_get_int key-alarm_plan_num return -1"); return ERROR; } /* 如果传入太多,只取前最大plan个数 */ if (g_msg_alarm_plan.alarm_plan_num > ALARM_PLAN_SIZE) { MSG_ALARM_ERROR("set too many plans!"); g_msg_alarm_plan.alarm_plan_num = ALARM_PLAN_SIZE; } JSON_OBJPTR alarm_plan_array = jso_obj_get(req_obj, "alarm_plan_1"); JSON_OBJPTR alarm_plan_term = jso_new_string(""); if (!jso_is_array(alarm_plan_array)) { MSG_ALARM_ERROR("key-alarm_plan_1 get non-array"); return ERROR; } /* 从json中获取alarm_plan_ch1配置值 */ for (i = 0; i < g_msg_alarm_plan.alarm_plan_num; i++) { alarm_plan_term = jso_array_get_idx(req_obj, i); if (!jso_is_string(alarm_plan_term)) { MSG_ALARM_ERROR("key-alarm_plan_1[] get non-string"); return ERROR; } jso_to_string(alarm_plan_term, g_msg_alarm_plan.alarm_plan_1[i], ALARM_PLAN_STR_MAX_LEN); } if (0 == ds_write(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("ds_write %s error", MSG_ALARM_CHN1_PLAN_PATH); return ERROR; } ret = ds_save_usr_cfg(); MSG_ALARM_DEBUG("ds_save_usr_cfg() ret[%d]", ret); /* 由于ds暂不支持listConfig的reload,所以这里手动调用 */ if (OK == ret) { alarm_plan_reload(); } return OK; } /* ds del回调函数 */ /* 解析json字符串,然后删除ds共享内存结构体中对应的plan */ S32 ds_cb_del_alarm_plan(struct _DS_HANDLE_CONTEXT *context, U8 method, const char* section_name, JSON_OBJPTR req_obj, BOOL is_table) { S32 i = 0; S32 ret = OK; const char *json_value_str = NULL; if (NULL == context || NULL == section_name || NULL == req_obj) { MSG_ALARM_ERROR("ptr is null"); return ERROR; } /* 从内存中读取并存入g_msg_alarm_plan结构体中 */ if (0 == ds_read(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("read from ds shm fail."); return ERROR; } JSON_OBJPTR alarm_plan_array = jso_obj_get(req_obj, "alarm_plan_1"); JSON_OBJPTR alarm_plan_term = jso_new_string(""); if (!jso_is_array(alarm_plan_array)) { MSG_ALARM_ERROR("key-alarm_plan_1 get non-array"); return ERROR; } /* 删的数量过多,清空plan数组 */ if (0 > (g_msg_alarm_plan.alarm_plan_num - jso_array_length(alarm_plan_array))) { for (i = 0; i < g_msg_alarm_plan.alarm_plan_num; i++ ) { memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); } MSG_ALARM_ERROR("delete too many plans."); return ERROR; } /* 从json中获取enable配置值 */ json_value_str = jso_obj_get_string_origin(req_obj, "enabled"); if (NULL == json_value_str) { MSG_ALARM_ERROR("jso_obj_get_string_origin key-enable return NULL"); return ERROR; } if (!strcmp(json_value_str, "on")) { g_msg_alarm_plan.enabled = 1; } else if (!strcmp(json_value_str, "off")) { g_msg_alarm_plan.enabled = 0; } else { MSG_ALARM_ERROR("set wrong key-enable param"); return ERROR; } /* 从json中获取要删除的plan项并删除,并更新alarm_plan_num的值 */ for (i = 0; i < jso_array_length(alarm_plan_array); i++) { alarm_plan_term = jso_array_get_idx(req_obj, i); if (!jso_is_string(alarm_plan_term)) { MSG_ALARM_ERROR("key-alarm_plan_1[] get non-string"); return ERROR; } jso_to_string(alarm_plan_term, json_value_str, ALARM_PLAN_STR_MAX_LEN); for (int j = 0; j < g_msg_alarm_plan.alarm_plan_num; j++) { if (!strncmp(json_value_str, g_msg_alarm_plan.alarm_plan_1[j], strlen(json_value_str))) { strncpy(g_msg_alarm_plan.alarm_plan_1[j], g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], strlen(g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1])); memset(g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], 0, ALARM_PLAN_STR_MAX_LEN); g_msg_alarm_plan.alarm_plan_num--; break; } } } if (0 == ds_write(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("ds_write %s error", MSG_ALARM_CHN1_PLAN_PATH); return ERROR; } ret = ds_save_usr_cfg(); MSG_ALARM_DEBUG("ds_save_usr_cfg() ret[%d]", ret); /* 由于ds暂不支持listConfig的reload,所以这里手动调用 */ if (OK == ret) { msg_alarm_plan_reload(); } return OK; } /* 注册ds get/set 回调函数 */ S32 registe_ds_cb() { S32 ret = OK; if (ERROR == ds_register_get_json(MSG_ALARM_PLAN_MODULE_NAME, MSG_ALARM_PLAN_TABLE_NAME, MSG_ALARM_PLAN_SECTION_NAME, ds_cb_get_alarm_plan)) { MSG_ALARM_ERROR("ds_register_get_json return error"); ret = ERROR; } if (ERROR == ds_register_set_json(MSG_ALARM_PLAN_MODULE_NAME, MSG_ALARM_PLAN_TABLE_NAME, MSG_ALARM_PLAN_SECTION_NAME, ds_cb_set_alarm_plan)) { MSG_ALARM_ERROR("ds_register_set_json return error"); ret = ERROR; } if (ERROR == ds_register_del_json(MSG_ALARM_PLAN_MODULE_NAME, MSG_ALARM_PLAN_TABLE_NAME, ds_cb_del_alarm_plan)) { MSG_ALARM_ERROR("ds_register_del_json return error"); ret = ERROR; } return ret; } /* 获取报警排程 */ PTR_MSG_ALARM_PLAN get_alarm_plan_cfg() { return &g_msg_alarm_plan; } /* 初始化 */ S32 alarm_plan_init() { S32 ret = OK; /* 注册ds set/get/del回调函数 */ ret = registe_ds_cb(); if (ERROR == ret) { MSG_ALARM_ERROR("registe_ds_cb error"); return ret; } /* 初始化ds侦测报警排程结构体 */ g_msg_alarm_plan.enabled = FALSE; g_msg_alarm_plan.alarm_plan_num = 0; for(int i = 0; i < ALARM_PLAN_SIZE; i++) { memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); } return ret; } 发生以下错误:make "make -C modules/msg_alarm MODULE_NAME=msg_alarm" make[5]: Entering directory '/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap/modules/msg_alarm' arm-AX620E-linux-uclibcgnueabihf-gcc -Os -pipe -D__LINUX_ARM_ARCH__=7 -march=armv7-a -mfloat-abi=hard -Wformat=0 -g -Wno-stringop-truncation -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-sizeof-pointer-div -Wno-restrict -Wno-stringop-overflow -Wno-format-truncation -Wno-format-overflow -Wno-error -g -DMCU_DIGITAL_LIGHT_SENSOR -DMCU_DIGITAL_PIR_SENSOR -DCLOUD_IOT_SUPPORT -DTAPO_USR_DEF_AUDIO_ALARM -DAUDIO_SAMPLE_RATE=16000 -DTAPO_AUDIO_ALARM_SETTINGS -DOPTIONAL_ALARM_AUDIO -DTELEMETRY_SUPPORT -DIR_LED_USE_MCU_ADC -DTP_TAPO_BATTERY_CAM -DTAPO_CARE_SUPPORT -DCONFIG_TARGET_AX620Q -DCONFIG_OPT300X_I2C_ALIAS=\"/dev/i2c-0\" -DSET_FRAME_SUPPORT -DBATTERY_OPERATING_MODE_SUPPORT -DBATTERY_STATISTIC_SUPPORT -DFREQ_WAKE_ABNORMAL_POWER_SUPPORT -DHUB_MANAGE_SUPPORT -DAUDIO_G711_16K_SUPPORT -DNET_STATUS_CHANGE_BITRATE -DNET_STATUS_CHANGE_BITRATE_REALTIME -DBAT_CAPACITY_CURVE_OPTIMIZATION -DPIR_SENSITIVITY_DEF_TABLE=100,91,80,69,48,36,30,28,24,20 -DMCU_CONTROL_MOTOR -DIRCUT_SWITCH_BY_MCU_MSG -DMCU_UART_ALIAS=\"/dev/ttyS3\" -DMCU_UPGRADE_CLEAN_UART -DMAX_BAT_MODEL=2 -DLOWER_IR_BEFORE_POWER_OFF -DJPEG_STREAM_ENABLE -DPTZ_SUPPORT -DGET_SNAPSHOT_ACCURATE -DSNAPSHOT_JPEG_HEIGHT=360 -DWLAN_SUPPORT -DLINUX_VERSION=4.19.125 -DTP_TAPO_RESET_WIFI_SUPPORT -I/home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include -I/home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/include -I/home/xyc/NVMP/nvmp/../sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/libc/usr/include -Wall -Werror -ffunction-sections -fdata-sections -DMODULE_LIST="\"general_plan mcu_proxy osd image dn_switch cover video battery_manage msg_alarm hsr md_alarm ptd_alarm vd_alarm speaker sd_card record_plan alarm_clock audio_library detection_region ptz light_control\"" -DTSS_MODULE_LIST="\"\"" -I/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap -c -o alarm_plan_ds.o alarm_plan_ds.c alarm_plan_ds.c:17:54: error: initialization of 'char' from 'void *' makes integer from pointer without a cast [-Werror=int-conversion] LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; ^~~~ alarm_plan_ds.c:17:54: note: (near initialization for 'g_msg_alarm_plan.alarm_plan_1[0]') alarm_plan_ds.c:17:46: error: missing braces around initializer [-Werror=missing-braces] LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; ^ In file included from alarm_plan_ds.c:9: alarm_plan_ds.c: In function 'ds_cb_get_alarm_plan': msg_alarm.h:59:36: error: implicit declaration of function 'CAP_ERROR'; did you mean 'MC_ERROR'? [-Werror=implicit-function-declaration] #define MSG_ALARM_ERROR(fmt, ...) CAP_ERROR("[MSG_ALARM]" fmt , ##__VA_ARGS__) ^~~~~~~~~ alarm_plan_ds.c:27:3: note: in expansion of macro 'MSG_ALARM_ERROR' MSG_ALARM_ERROR("ds_cb_get_alarm_plan: ptr is null"); ^~~~~~~~~~~~~~~ alarm_plan_ds.c:54:85: error: passing argument 1 of 'jso_new_string' makes pointer from integer without a cast [-Werror=int-conversion] jso_array_add(alarm_plan_array, jso_new_string(g_msg_alarm_plan.alarm_plan_1[i])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json.h:26, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/libds.h:7, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/slp_model.h:7, from alarm_plan_ds.c:7: /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json_api.h:35:41: note: expected 'char *' but argument is of type 'char' extern JSON_OBJPTR jso_new_string(char *str); ~~~~~~^~~ In file included from alarm_plan_ds.c:9: msg_alarm.h:57:36: error: implicit declaration of function 'CAP_DEBUG'; did you mean 'MC_DEBUG'? [-Werror=implicit-function-declaration] #define MSG_ALARM_DEBUG(fmt, ...) CAP_DEBUG("[MSG_ALARM]" fmt, ##__VA_ARGS__) ^~~~~~~~~ alarm_plan_ds.c:59:2: note: in expansion of macro 'MSG_ALARM_DEBUG' MSG_ALARM_DEBUG(" JSON %s",json_object_to_json_string(reply_obj)); ^~~~~~~~~~~~~~~ alarm_plan_ds.c: In function 'ds_cb_set_alarm_plan': alarm_plan_ds.c:100:43: error: 'ALARM_PLAN_SIZE' undeclared (first use in this function); did you mean 'ALARM_STATE_IDLE'? if (g_msg_alarm_plan.alarm_plan_num > ALARM_PLAN_SIZE) ^~~~~~~~~~~~~~~ ALARM_STATE_IDLE alarm_plan_ds.c:100:43: note: each undeclared identifier is reported only once for each function it appears in alarm_plan_ds.c:124:69: error: passing argument 2 of 'jso_to_string' makes pointer from integer without a cast [-Werror=int-conversion] jso_to_string(alarm_plan_term, g_msg_alarm_plan.alarm_plan_1[i], ALARM_PLAN_STR_MAX_LEN); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json.h:26, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/libds.h:7, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/slp_model.h:7, from alarm_plan_ds.c:7: /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json_api.h:40:49: note: expected 'char *' but argument is of type 'char' extern int jso_to_string(JSON_OBJPTR obj, char *str_buf, int len); ~~~~~~^~~~~~~ alarm_plan_ds.c:139:3: error: implicit declaration of function 'alarm_plan_reload' [-Werror=implicit-function-declaration] alarm_plan_reload(); ^~~~~~~~~~~~~~~~~ alarm_plan_ds.c: In function 'ds_cb_del_alarm_plan': alarm_plan_ds.c:180:49: error: passing argument 1 of 'memset' makes pointer from integer without a cast [-Werror=int-conversion] memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:58:14: note: expected 'void *' but argument is of type 'char' extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1)); ^~~~~~ alarm_plan_ds.c:218:40: error: passing argument 2 of 'jso_to_string' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] jso_to_string(alarm_plan_term, json_value_str, ALARM_PLAN_STR_MAX_LEN); ^~~~~~~~~~~~~~ In file included from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json.h:26, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/libds.h:7, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/slp_model.h:7, from alarm_plan_ds.c:7: /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/json/json_api.h:40:49: note: expected 'char *' but argument is of type 'const char *' extern int jso_to_string(JSON_OBJPTR obj, char *str_buf, int len); ~~~~~~^~~~~~~ alarm_plan_ds.c:221:71: error: passing argument 2 of 'strncmp' makes pointer from integer without a cast [-Werror=int-conversion] if (!strncmp(json_value_str, g_msg_alarm_plan.alarm_plan_1[j], strlen(json_value_str))) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:101:51: note: expected 'const char *' but argument is of type 'char' extern int strncmp (const char *__s1, const char *__s2, size_t __n) ~~~~~~~~~~~~^~~~ alarm_plan_ds.c:224:61: error: passing argument 1 of 'strlen' makes pointer from integer without a cast [-Werror=int-conversion] strlen(g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:247:35: note: expected 'const char *' but argument is of type 'char' extern size_t strlen (const char *__s) ~~~~~~~~~~~~^~~ alarm_plan_ds.c:223:54: error: passing argument 1 of 'strncpy' makes pointer from integer without a cast [-Werror=int-conversion] strncpy(g_msg_alarm_plan.alarm_plan_1[j], g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:86:14: note: expected 'char * restrict' but argument is of type 'char' extern char *strncpy (char *__restrict __dest, ^~~~~~~ alarm_plan_ds.c:223:88: error: passing argument 2 of 'strncpy' makes pointer from integer without a cast [-Werror=int-conversion] strncpy(g_msg_alarm_plan.alarm_plan_1[j], g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:86:14: note: expected 'const char * restrict' but argument is of type 'char' extern char *strncpy (char *__restrict __dest, ^~~~~~~ alarm_plan_ds.c:225:53: error: passing argument 1 of 'memset' makes pointer from integer without a cast [-Werror=int-conversion] memset(g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], 0, ALARM_PLAN_STR_MAX_LEN); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:58:14: note: expected 'void *' but argument is of type 'char' extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1)); ^~~~~~ alarm_plan_ds.c:244:3: error: implicit declaration of function 'msg_alarm_plan_reload'; did you mean 'msg_alarm_type_filter'? [-Werror=implicit-function-declaration] msg_alarm_plan_reload(); ^~~~~~~~~~~~~~~~~~~~~ msg_alarm_type_filter alarm_plan_ds.c: In function 'registe_ds_cb': alarm_plan_ds.c:268:94: error: passing argument 3 of 'ds_register_del_json' from incompatible pointer type [-Werror=incompatible-pointer-types] if (ERROR == ds_register_del_json(MSG_ALARM_PLAN_MODULE_NAME, MSG_ALARM_PLAN_TABLE_NAME, ds_cb_del_alarm_plan)) ^~~~~~~~~~~~~~~~~~~~ In file included from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/libds.h:12, from /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/slp_model.h:7, from alarm_plan_ds.c:7: /home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/usr/include/ds_model.h:252:87: note: expected 'DEL_JSON' {aka 'int (*)(struct _DS_HANDLE_CONTEXT *, struct json_object *, enum _BOOL)'} but argument is of type 'S32 (*)(struct _DS_HANDLE_CONTEXT *, U8, const char *, struct json_object *, BOOL)' {aka 'int (*)(struct _DS_HANDLE_CONTEXT *, unsigned char, const char *, struct json_object *, enum _BOOL)'} STATUS ds_register_del_json(const char *module_name, const char *table_name, DEL_JSON del_json); ~~~~~~~~~^~~~~~~~ alarm_plan_ds.c: In function 'alarm_plan_init': alarm_plan_ds.c:299:24: error: 'ALARM_PLAN_SIZE' undeclared (first use in this function); did you mean 'ALARM_STATE_IDLE'? for(int i = 0; i < ALARM_PLAN_SIZE; i++) ^~~~~~~~~~~~~~~ ALARM_STATE_IDLE alarm_plan_ds.c:301:45: error: passing argument 1 of 'memset' makes pointer from integer without a cast [-Werror=int-conversion] memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ In file included from alarm_plan_ds.c:3: /home/xyc/NVMP/sdk/soc/AX620Q/uclibc-toolchain/arm-AX620E-linux-uclibcgnueabihf/arm-AX620E-linux-uclibcgnueabihf/sysroot/usr/include/string.h:58:14: note: expected 'void *' but argument is of type 'char' extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1)); ^~~~~~ cc1: all warnings being treated as errors <builtin>: recipe for target 'alarm_plan_ds.o' failed make[5]: *** [alarm_plan_ds.o] Error 1 make[5]: Leaving directory '/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap/modules/msg_alarm' Makefile:32: recipe for target 'build_modules' failed make[4]: *** [build_modules] Error 2 make[4]: Leaving directory '/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap' Makefile:758: recipe for target '/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap/.built' failed make[3]: *** [/home/xyc/NVMP/nvmp/build_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/cap/.built] Error 2 make[3]: Leaving directory '/home/xyc/NVMP/nvmp/tp_package/cap' package/Makefile:105: recipe for target 'package/tp_package/cap/compile' failed make[2]: *** [package/tp_package/cap/compile] Error 2 make[2]: Leaving directory '/home/xyc/NVMP/nvmp' package/Makefile:101: recipe for target '/home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/stamp/.package_compile' failed make[1]: *** [/home/xyc/NVMP/nvmp/staging_dir/target-arm-AX620E-linux-uclibcgnueabihf-c668bv1/stamp/.package_compile] Error 2 make[1]: Leaving directory '/home/xyc/NVMP/nvmp' /home/xyc/NVMP/nvmp/include/toplevel.mk:210: recipe for target 'world' failed make: *** [world] Error 2
最新发布
08-19
<think>我们正在处理一个C语言项目中的编译错误。错误信息显示在编译alarm_plan_ds.c文件时出现了多个错误。我们需要分析这些错误并给出解决方案。 错误1:初始化问题 alarm_plan_ds.c:17:54: error: initialization of 'char' from 'void *' makes integer from pointer without a cast [-Werror=int-conversion] LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; ^~~~ 注意:这里在初始化一个结构体变量,结构体类型为MSG_ALARM_CHN1_PLAN,定义如下: typedef struct _MSG_ALARM_CHN1_PLAN { SWITCH enabled; char alarm_plan_1[5][ALARM_PLAN_STR_MAX_LEN + 1]; /* 0000-0000,000格式 */ S32 alarm_plan_num; }MSG_ALARM_CHN1_PLAN, *PTR_MSG_ALARM_PLAN; 错误原因:在初始化结构体时,对数组alarm_plan_1使用了NULL。但是,alarm_plan_1是一个二维字符数组,不能用一个指针(NULL)来初始化。应该用空字符串初始化或者用大括号嵌套初始化。 错误2:缺失大括号 alarm_plan_ds.c:17:46: error: missing braces around initializer [-Werror=missing-braces] LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; ^ 这个错误是因为初始化结构体时,对于数组的初始化没有使用大括号。应该按照数组的维度进行嵌套初始化。 错误3:隐式函数声明 多个错误:implicit declaration of function ... 例如: alarm_plan_ds.c:27:3: error: implicit declaration of function 'CAP_ERROR'; did you mean 'MC_ERROR'? alarm_plan_ds.c:139:3: error: implicit declaration of function 'alarm_plan_reload' alarm_plan_ds.c:244:3: error: implicit declaration of function 'msg_alarm_plan_reload' 这些错误说明在调用函数之前没有声明或包含相应的头文件。 错误4:类型不匹配 在多个地方,比如: jso_new_string(g_msg_alarm_plan.alarm_plan_1[i]) 这里jso_new_string期望一个char*,但g_msg_alarm_plan.alarm_plan_1[i]是一个字符数组(即char*类型),但错误提示是“makes pointer from integer without a cast”,这很奇怪,因为数组名就是指针。但是注意,错误信息说“passing argument 1 of 'jso_new_string' makes pointer from integer without a cast”,并且指出是char类型?实际上,在结构体中alarm_plan_1是一个二维数组,即char[5][17](因为ALARM_PLAN_STR_MAX_LEN为16,加1为17)。所以alarm_plan_1[i]是一个一维数组,在表达式中会退化为char*。所以这里不应该出错。但是错误提示是“从整数转换为指针”,这可能是由于之前的初始化错误导致g_msg_alarm_plan.alarm_plan_1[i]被错误地初始化为整数(因为用NULL初始化了数组?)。 然而,我们注意到错误1和2导致结构体初始化不正确,可能引发了后续一系列问题。 错误5:未声明的标识符 alarm_plan_ds.c:100:43: error: 'ALARM_PLAN_SIZE' undeclared 在代码中,我们看到了一个宏ALARM_PLAN_SIZE,但是在代码中并没有定义。根据上下文,这个宏应该表示报警排程的最大数量。在结构体中,alarm_plan_1数组的第一维是5,所以ALARM_PLAN_SIZE应该是5。但是代码中没有定义,所以需要定义或者用5代替。 错误6:函数参数类型不匹配 alarm_plan_ds.c:268:94: error: passing argument 3 of 'ds_register_del_json' from incompatible pointer type 函数ds_register_del_json期望的函数指针类型与提供的ds_cb_del_alarm_plan不匹配。需要检查ds_register_del_json的函数原型和ds_cb_del_alarm_plan的声明。 其他错误:很多错误都是由于第一个初始化错误引发的连锁反应,或者是由于未定义标识符、函数隐式声明等。 解决方案: 1. 修正结构体初始化: 原代码:LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; 应该改为:LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, {{0}}, 0}; 或者:LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, {0}, 0}; // 因为二维数组也可以用{0}初始化 但是注意,结构体中有二维数组,所以更规范的初始化是: LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = { .enabled = FALSE, .alarm_plan_1 = {{0}}, // 或者 {0} 也可以,因为二维数组在内存中是连续的 .alarm_plan_num = 0 }; 2. 添加缺失的宏定义: 在alarm_plan_ds.c中,添加: #define ALARM_PLAN_SIZE 5 // 因为结构体中alarm_plan_1的第一维是5 3. 包含必要的头文件: 在alarm_plan_ds.c中,添加包含头文件,以解决隐式函数声明的问题。 #include "cap_log.h" // 因为使用了CAP_ERROR, CAP_DEBUG等 #include "msg_alarm_plan.h" // 或者声明alarm_plan_reload和msg_alarm_plan_reload函数的头文件 注意:错误信息中提示CAP_ERROR未声明,而代码中使用了MSG_ALARM_ERROR宏,它又使用了CAP_ERROR。所以需要包含cap_log.h。 4. 修正函数指针类型不匹配: 查看ds_register_del_json的原型(在ds_model.h中): STATUS ds_register_del_json(const char *module_name, const char *table_name, DEL_JSON del_json); 而DEL_JSON类型可能是: typedef STATUS (*DEL_JSON)(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table); 但是我们的回调函数ds_cb_del_alarm_plan的签名是: S32 ds_cb_del_alarm_plan(struct _DS_HANDLE_CONTEXT *context, U8 method, const char* section_name, JSON_OBJPTR req_obj, BOOL is_table) 参数多了method和section_name。这可能是问题所在。需要检查ds_register_del_json要求的回调函数类型,并调整我们的函数签名。 但是,根据错误信息,ds_register_del_json期望的是: expected 'DEL_JSON' {aka 'int (*)(struct _DS_HANDLE_CONTEXT *, struct json_object *, enum _BOOL)'} 而我们提供的是: S32 (*)(struct _DS_HANDLE_CONTEXT *, U8, const char *, struct json_object *, BOOL) 所以,我们需要修改回调函数ds_cb_del_alarm_plan的签名,使其符合DEL_JSON类型。或者,如果函数要求不同,可能需要重新设计回调函数。 然而,观察其他注册函数:ds_register_get_json和ds_register_set_json,它们的回调函数都有额外的参数。所以这里可能是ds_register_del_json的版本问题?或者文档要求? 由于我们无法修改库,所以只能调整回调函数。但是,如果库函数要求的回调只有三个参数,而我们的函数有五个,那么就不能直接使用。需要检查ds_model.h中DEL_JSON的定义。 假设我们发现DEL_JSON的定义确实是: typedef STATUS (*DEL_JSON)(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table); 那么,我们需要将ds_cb_del_alarm_plan改为: STATUS ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table) 然后,在函数内部,我们需要从context中获取method和section_name?或者这个回调不需要这些信息? 但是,在代码中,ds_cb_del_alarm_plan使用了section_name和method,所以不能直接删除。因此,可能需要重新考虑设计,或者与库的接口保持一致。 另一种可能是,我们调用的ds_register_del_json函数版本不对?查看ds_model.h中的声明,确认DEL_JSON类型。 由于时间关系,我们暂时不深入,但错误必须解决。 5. 其他错误:在修正了上述主要错误后,一些由初始化错误引发的后续错误可能会消失。 由于错误较多,我们逐步修正: 步骤1:修正初始化 将g_msg_alarm_plan的初始化改为:{FALSE, {{0}}, 0} 或 {FALSE, {0}, 0}。 步骤2:定义ALARM_PLAN_SIZE 在alarm_plan_ds.c开头添加: #define ALARM_PLAN_SIZE 5 步骤3:包含头文件 添加: #include "cap_log.h" // 解决CAP_ERROR和CAP_DEBUG的声明 添加: #include "msg_alarm_plan.h" // 或者声明alarm_plan_reload和msg_alarm_plan_reload的头文件 步骤4:修正回调函数签名不匹配的问题 方案一:修改ds_cb_del_alarm_plan的签名,使其与DEL_JSON类型匹配(即去掉method和section_name参数,或者从context中获取)。 方案二:如果库函数允许传递额外的参数,那么可能需要使用适配器函数,但这里注册函数不允许。 我们查看ds_model.h中DEL_JSON的定义,假设为: typedef STATUS (*DEL_JSON)(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table); 那么,我们修改ds_cb_del_alarm_plan为: S32 ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table) 然后,在函数内部,我们需要获取section_name和method?但是原函数中使用了section_name和method,现在没有了,怎么办? 观察原函数中,section_name是从参数传入的,而context中可能包含这些信息?需要查看DS_HANDLE_CONTEXT结构体是否包含这些信息。 由于代码中没有提供DS_HANDLE_CONTEXT的定义,我们假设它包含这些信息。或者,我们可能发现实际上不需要section_name和method。 但是,在ds_cb_del_alarm_plan中,我们使用了section_name参数来打印错误,但并没有实际使用(除了打印)。而method参数也没有使用。所以我们可以删除这两个参数? 检查代码:在ds_cb_del_alarm_plan中,我们只使用了context、req_obj和is_table。但是,函数开头检查了section_name是否为NULL,然后打印错误。如果section_name在context中,我们可以从context获取。 但是,为了快速修复,我们可以暂时注释掉对section_name的检查?或者从context中获取section_name? 由于我们不知道context的结构,所以这里可能需要调整。但是,错误必须解决。 考虑到时间,我们按照库函数要求的参数个数修改回调函数,并去掉对section_name和method的使用(如果确实不需要)。 修改后的函数签名: S32 ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table) 然后,在函数内部,删除method和section_name参数,并修改相关代码: - 去掉method参数,因为用不到。 - section_name可以从context中获取?或者我们不需要。原函数中只用于错误打印,可以去掉。 修改后的函数开头: if (NULL == context || NULL == req_obj) // 去掉了section_name的检查 { MSG_ALARM_ERROR("ptr is null"); return ERROR; } 这样,函数就符合DEL_JSON类型了。 步骤5:在alarm_plan_init函数中,初始化数组时,循环次数为ALARM_PLAN_SIZE(即5),然后对每个元素进行memset。这里没有问题,因为我们已经定义了ALARM_PLAN_SIZE。 步骤6:修正其他函数调用: 在ds_cb_get_alarm_plan中,调用jso_new_string时传入的是g_msg_alarm_plan.alarm_plan_1[i],它现在是一个字符数组(即char*),所以应该没问题。但是之前因为初始化错误,导致数组被初始化为NULL(实际上被初始化为0,即空指针?),现在初始化正确了,所以这个错误应该消失。 步骤7:在ds_cb_set_alarm_plan中,对g_msg_alarm_plan.alarm_plan_1[i]的赋值,使用jso_to_string,这里第二个参数是g_msg_alarm_plan.alarm_plan_1[i],它是一个char数组,所以传递数组名(即指针)没有问题。同样,初始化修正后,这个错误应该消失。 步骤8:在ds_cb_del_alarm_plan中,我们修改了函数签名,然后需要修改函数内部:去掉对section_name和method的使用。同时,在调用jso_array_get_idx时,我们使用alarm_plan_array(即req_obj)?这里需要仔细检查。 由于修改较大,建议重新检查代码逻辑。 但是,由于错误太多,我们可能还需要处理其他问题。这里先按照上述步骤修改,然后重新编译。 注意:由于代码较长,以上只是针对部分错误的修改。实际中可能需要逐步调试。 由于无法直接运行,我们只能根据错误信息提供修改建议。 总结修改点: 1. 修改alarm_plan_ds.c中g_msg_alarm_plan的初始化方式。 2. 定义ALARM_PLAN_SIZE为5。 3. 包含cap_log.h头文件(或其他声明CAP_ERROR的头文件)。 4. 包含声明alarm_plan_reload和msg_alarm_plan_reload的头文件。 5. 修改ds_cb_del_alarm_plan函数的签名,并调整其内部代码。 由于修改内容较多,下面给出修改后的代码片段(仅修改部分): 在alarm_plan_ds.c的开头添加: #define ALARM_PLAN_SIZE 5 #include "cap_log.h" #include "msg_alarm_plan.h" // 或者包含声明这两个函数的头文件 修改g_msg_alarm_plan的初始化: LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, {{0}}, 0}; 修改ds_cb_del_alarm_plan函数: S32 ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT *context, JSON_OBJPTR req_obj, BOOL is_table) { S32 i = 0; S32 ret = OK; const char *json_value_str = NULL; if (NULL == context || NULL == req_obj) // 去掉了section_name { MSG_ALARM_ERROR("ptr is null"); return ERROR; } // 从内存中读取并存入g_msg_alarm_plan结构体中 if (0 == ds_read(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("read from ds shm fail."); return ERROR; } JSON_OBJPTR alarm_plan_array = jso_obj_get(req_obj, "alarm_plan_1"); JSON_OBJPTR alarm_plan_term = jso_new_string(""); if (!jso_is_array(alarm_plan_array)) { MSG_ALARM_ERROR("key-alarm_plan_1 get non-array"); return ERROR; } // 删的数量过多,清空plan数组 if (0 > (g_msg_alarm_plan.alarm_plan_num - jso_array_length(alarm_plan_array))) { for (i = 0; i < g_msg_alarm_plan.alarm_plan_num; i++ ) { memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); } MSG_ALARM_ERROR("delete too many plans."); return ERROR; } // 从json中获取enable配置值 json_value_str = jso_obj_get_string_origin(req_obj, "enabled"); if (NULL == json_value_str) { MSG_ALARM_ERROR("jso_obj_get_string_origin key-enable return NULL"); return ERROR; } if (!strcmp(json_value_str, "on")) { g_msg_alarm_plan.enabled = 1; } else if (!strcmp(json_value_str, "off")) { g_msg_alarm_plan.enabled = 0; } else { MSG_ALARM_ERROR("set wrong key-enable param"); return ERROR; } // 从json中获取要删除的plan项并删除,并更新alarm_plan_num的值 for (i = 0; i < jso_array_length(alarm_plan_array); i++) { alarm_plan_term = jso_array_get_idx(alarm_plan_array, i); // 注意:这里第一个参数应该是alarm_plan_array,而不是req_obj if (!jso_is_string(alarm_plan_term)) { MSG_ALARM_ERROR("key-alarm_plan_1[] get non-string"); return ERROR; } // 分配一个缓冲区来存储字符串 char temp_str[ALARM_PLAN_STR_MAX_LEN+1] = {0}; jso_to_string(alarm_plan_term, temp_str, ALARM_PLAN_STR_MAX_LEN); for (int j = 0; j < g_msg_alarm_plan.alarm_plan_num; j++) { if (!strncmp(temp_str, g_msg_alarm_plan.alarm_plan_1[j], strlen(temp_str))) { // 将最后一个元素复制到当前位置 strncpy(g_msg_alarm_plan.alarm_plan_1[j], g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], ALARM_PLAN_STR_MAX_LEN); memset(g_msg_alarm_plan.alarm_plan_1[g_msg_alarm_plan.alarm_plan_num - 1], 0, ALARM_PLAN_STR_MAX_LEN); g_msg_alarm_plan.alarm_plan_num--; break; } } } if (0 == ds_write(MSG_ALARM_CHN1_PLAN_PATH, &g_msg_alarm_plan, sizeof(MSG_ALARM_CHN1_PLAN))) { MSG_ALARM_ERROR("ds_write %s error", MSG_ALARM_CHN1_PLAN_PATH); return ERROR; } ret = ds_save_usr_cfg(); MSG_ALARM_DEBUG("ds_save_usr_cfg() ret[%d]", ret); /* 由于ds暂不支持listConfig的reload,所以这里手动调用 */ if (OK == ret) { msg_alarm_plan_reload(); // 注意:这里函数名应该是alarm_plan_reload还是msg_alarm_plan_reload?根据错误提示,之前是msg_alarm_plan_reload未声明,所以这里用msg_alarm_plan_reload } return OK; } 注意:在修改函数签名后,注册回调的地方不需要修改,因为函数名没变,只是参数变了,而注册时传递的函数指针现在匹配了。 6. 另外,在ds_cb_set_alarm_plan中,调用alarm_plan_reload(),而错误提示是隐式声明,所以我们在头文件中声明这个函数,或者包含它的头文件。同样,msg_alarm_plan_reload也需要声明。 由于无法确定这两个函数的具体位置,我们假设在msg_alarm_plan.h中声明。 7. 在ds_cb_del_alarm_plan中,我们修改了jso_array_get_idx的第一个参数,原来是req_obj,现在改为alarm_plan_array。因为req_obj是整个请求对象,而alarm_plan_array是数组对象。 8. 在ds_cb_del_alarm_plan中,我们使用了一个临时缓冲区temp_str来存储从json中取出的字符串,因为jso_to_string需要写入一个字符数组。 由于修改较多,请仔细检查。 最后,重新编译,看是否还有错误。 注意:以上修改是基于错误信息的推测,实际项目可能需要调整。</think>根据提供的代码和编译错误,问题主要出现在`alarm_plan_ds.c`文件中,涉及结构体初始化、函数声明、类型不匹配和未定义符号等问题。以下是关键问题及解决方案: ### 主要错误分析及修复方案 1. **结构体初始化错误** ```c // 错误代码 LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = {FALSE, NULL, 0}; ``` - **问题**:二维数组`alarm_plan_1`被初始化为`NULL`(指针),但实际是静态数组 - **修复**:使用空字符串初始化二维数组 ```c LOCAL MSG_ALARM_CHN1_PLAN g_msg_alarm_plan = { .enabled = FALSE, .alarm_plan_1 = {{0}}, // 初始化为空字符串 .alarm_plan_num = 0 }; ``` 2. **未定义宏`ALARM_PLAN_SIZE`** - **问题**:代码中使用了未定义的`ALARM_PLAN_SIZE` - **修复**:根据结构体定义添加宏(数组第一维大小是5) ```c #define ALARM_PLAN_SIZE 5 // 添加到头文件或文件顶部 ``` 3. **隐式函数声明** - **问题**:`CAP_ERROR`/`CAP_DEBUG`未声明 - **修复**:包含头文件 ```c #include "cap_log.h" // 添加在文件顶部 ``` 4. **JSON处理类型不匹配** ```c // 错误代码 jso_new_string(g_msg_alarm_plan.alarm_plan_1[i]) ``` - **问题**:`jso_new_string`需要`char*`但传入的是`char`类型元素 - **修复**:传递数组首地址 ```c jso_new_string(g_msg_alarm_plan.alarm_plan_1[i]) // 保持原样 // 实际有效,因alarm_plan_1[i]是char[17]类型,会退化为char* ``` 5. **函数签名不匹配** ```c // ds_register_del_json 期望的函数签名 typedef STATUS (*DEL_JSON)(DS_HANDLE_CONTEXT*, JSON_OBJPTR, BOOL); // 当前函数签名 S32 ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT*, U8, const char*, JSON_OBJPTR, BOOL) ``` - **修复**:修改回调函数签名 ```c S32 ds_cb_del_alarm_plan(DS_HANDLE_CONTEXT* context, JSON_OBJPTR req_obj, BOOL is_table) { // 移除method和section_name参数 // 从context获取section_name(若需要) } ``` 6. **未声明函数** - **问题**:`alarm_plan_reload`和`msg_alarm_plan_reload`未声明 - **修复**:添加函数声明 ```c // 在msg_alarm.h中添加 void alarm_plan_reload(void); void msg_alarm_plan_reload(void); ``` ### 其他关键修复点 - **字符串处理**:所有`memset`/`strncpy`调用需使用指针而非数组元素: ```c // 错误示例 memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ...); // 正确用法(保持原样,因数组元素是char[]) memset(g_msg_alarm_plan.alarm_plan_1[i], 0, ALARM_PLAN_STR_MAX_LEN); ``` - **常量丢失**:`jso_to_string`需要`char*`但传入`const char*`: ```c char buffer[ALARM_PLAN_STR_MAX_LEN]; jso_to_string(alarm_plan_term, buffer, ...); ``` ### 完整修复步骤 1. 在`slp_model.h`或专用头文件中定义: ```c #define ALARM_PLAN_SIZE 5 ``` 2. 修改`g_msg_alarm_plan`初始化方式 3. 包含`cap_log.h`头文件 4. 修正`ds_cb_del_alarm_plan`函数签名 5. 添加缺失函数声明 6. 确保所有字符串操作使用正确指针类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值