В этом случае указатели не нужно было хранить в памяти данных, поэтому я изменил их на временные в функции init (). Вместо сохранения указателей я решил создать таблицу menu_page ** для хранения указателей в памяти SRAM.
соответствующая информация в новом заголовке:
typedef enum {
//Run status flag for the game (Turn on/off):
GAME_STATUS,
//Holds possible parameters for solenoid control selection:
SOLENOID_PARAMETERS,
//Holds possible parameters for servo control selection:
SERVO_PARAMETERS,
//Holds possible parameters for motor control selection:
MOTOR_PARAMETERS,
//Holds possible parameters for difficulty:
DIFFICULTY_PARAMETERS,
GAME_SETTING_ELEMENTS = 5 // <-Has to be adjusted to number of elements in this enum!
}game_setting_data_index;
typedef enum {
//Pressing this option starts the game:
START_GAME,
//Menu for configuring which button to control solenoid:
SOLENOID_CONTROL,
// -||- which adc to control servo:
SERVO_CONTROL,
// -||- control motor:
MOTOR_CONTROL,
// Parent page for controller-configuration:
CONTROLLER_LAYOUT,
//More settings for the game:
SETTINGS_ADVANCED,
//Set difficulty:
SETTINGS_DIFFIULTY,
//Parent page for all settings, has previous pages as children:
MENU_SETTING,
MAIN_MENU,
MENU_PAGE_ELEMENTS = 9 //<--Has to be adjusted to number of elements in this enum!
}menu_page_data_index;
Новая функция инициализации:
void menu_init()
{
const volatile menu_page* MENU_PAGE_SRAM_BASE_OFFSET = 0x1C01;
const volatile menu_page* GAME_SETTING_SRAM_BASE_OFFSET = 0x1E01;
//The menu_pages will be stored right after the last menu_page_address in SRAM_memory:
menu_page* menu_page_address_offset = MENU_PAGE_SRAM_BASE_OFFSET;
game_setting* game_setting_address_offset = GAME_SETTING_SRAM_BASE_OFFSET;
game_setting* game_status = game_setting_address_offset;
game_setting_address_offset += 1;
game_status->parameter = &game_parameters_array[RUN_STATUS];
game_status->alternatives[0] = OFF;
game_status->alternatives[1] = ON;
game_status->alternatives_number = 2;
menu_page* start_game = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&start_game->title, "Start game");
start_game->submenu_pages[0] = NULL;
start_game->parent_menu_page = NULL;
start_game->submenu_pages_number = 0;
start_game->setting = &game_status;
game_setting* solenoid_param = game_setting_address_offset;
game_setting_address_offset += 1;
solenoid_param->parameter = &game_parameters_array[SOLENOID];
solenoid_param->alternatives[0] = X_POSITION;
solenoid_param->alternatives[1] = Y_POSITION;
solenoid_param->alternatives[2] = LEFT_SLIDER;
solenoid_param->alternatives[3] = RIGHT_SLIDER;
solenoid_param->alternatives_number = 4;
menu_page* solenoid_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&solenoid_control->title,"Solenoid");
solenoid_control->submenu_pages[0] = NULL;
solenoid_control->parent_menu_page = NULL;
solenoid_control->submenu_pages_number = 0;
solenoid_control->setting = &solenoid_param;
game_setting* servo_param = game_setting_address_offset;
game_setting_address_offset += 1;
servo_param->parameter = &game_parameters_array[SERVO];
servo_param->alternatives[0] = X_POSITION;
servo_param->alternatives[1] = Y_POSITION;
servo_param->alternatives[2] = LEFT_SLIDER;
servo_param->alternatives[3] = RIGHT_SLIDER;
servo_param->alternatives_number = 4;
menu_page* servo_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&servo_control->title, "Servo");
servo_control->submenu_pages[0] = NULL;
servo_control->parent_menu_page = NULL;
servo_control->submenu_pages_number = 0;
servo_control->setting = &servo_param;
game_setting* motor_param = game_setting_address_offset;
game_setting_address_offset += 1;
motor_param->parameter = &game_parameters_array[MOTOR];
motor_param->alternatives[0] = X_POSITION;
motor_param->alternatives[1] = Y_POSITION;
motor_param->alternatives[2] = LEFT_SLIDER;
motor_param->alternatives[3] = RIGHT_SLIDER;
menu_page* motor_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&motor_control->title, "Motor");
motor_control->submenu_pages[0] = NULL;
motor_control->parent_menu_page = NULL;
motor_control->submenu_pages_number = 0;
motor_control->setting = &motor_param;
#ifdef OLED_MENU_INIT_DEBUG
printf("Menu Title: %s\n", motor_control->title);
#endif
menu_page* controller_layout = menu_page_address_offset;
//printf("Controller_layout addr: , %d\n", (int)menu_page_address_offset);
menu_page_address_offset += 1;
strcpy(controller_layout->title, "Controller Layout");
controller_layout->submenu_pages[0] = motor_control;
printf("motor_control : %X\n", motor_control);
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control;
controller_layout->parent_menu_page = NULL;
controller_layout->submenu_pages_number = 3;
controller_layout->setting = NULL;
menu_page* settings_advanced = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_advanced->title, "Advanced Settings");
settings_advanced->submenu_pages[0] = NULL;
settings_advanced->parent_menu_page = NULL;
settings_advanced->submenu_pages_number = 0;
settings_advanced->setting = NULL;
game_setting* difficulty_param = game_setting_address_offset;
game_setting_address_offset += 1;
difficulty_param->parameter = &game_parameters_array[DIFFICULTY];
difficulty_param->alternatives[0] = DIFFICULTY_EASY;
difficulty_param->alternatives[1] = DIFFICULTY_NORMAL;
difficulty_param->alternatives[2] = DIFFICULTY_HARD;
difficulty_param->alternatives_number = 3;
menu_page* settings_difficulty = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_difficulty->title, "Difficulty");
settings_difficulty->submenu_pages[0] = NULL;
settings_difficulty->parent_menu_page = NULL;
settings_difficulty->submenu_pages_number = 0;
settings_difficulty->setting = &difficulty_param;
menu_page *menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(menu_setting->title, "Settings");
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
//printf("Child 1 before: %d, %d",menu_setting->submenu_pages[0], controller_layout);
menu_setting->parent_menu_page = NULL;
menu_setting->submenu_pages_number = 3;
menu_setting->setting = NULL;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
menu_page* main_menu = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(main_menu->title, "Main Menu");
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
main_menu->parent_menu_page = NULL;
main_menu->submenu_pages_number = 2;
main_menu->setting = NULL;
//menu_assign_parents(&main_menu);
printf("Offsets: menupage: %X, game_setting: %X\n", menu_page_address_offset, game_setting_address_offset);
printf("Bytes per page: %d, %d\n", sizeof(menu_page), ((int)menu_page_address_offset-0x1C01)/10);
//Create address table at end of menu_page entries:
menu_page_address_table = menu_page_address_offset;
//Create address table at end of game_setting entries:
game_setting_address_table = game_setting_address_offset;
/*Game settings and pages have been placed in the order
of the menu_page_data_index-enum, address-tables should
be updated accordingly: */
printf("Menu address table: \n");
for (int i; i < MENU_PAGE_ELEMENTS; i++)
{
menu_page_address_table[i] = MENU_PAGE_SRAM_BASE_OFFSET + i;
printf("%X ", menu_page_address_table[i]);
}
printf("\nGame setting address table: \n");
for (int i; i < GAME_SETTING_ELEMENTS; i++)
{
game_setting_address_table[i] = GAME_SETTING_SRAM_BASE_OFFSET + i;
printf("%X ", game_setting_address_table[i]);
}
printf("\n");
}
Инициализация каждого члена структуры кажется немного ненужной, вместо этого я попытаюсь создать функцию init для каждой структуры.