Hi all, 

We use SDCC with our project and we encountered some problems with the
function pointer in struct which located in code segment.

The pointers point to the wrong address and sometimes the mcu resets or
cannot go on normally.

This is the test sample below, we test the function with/without parameters,
return values and called with/without asterisk, all of them cannot work.

Because of this problem, we had to put the struct in the data ram and waste
lots of data ram, this is a very bad choice to a limited resource device.

can anyone tell me why this happend, is it a bug of sdcc?

1. CODE SAMPLE1: we want to use code segment structure to hold function 
pointers.
   This can not work

#define NR_TEST_FUNCS 2
struct test_funcs {
 void (*non_one)(void);
 void (*non_two)(void);
 uint8_t (*ret_one)(void);
 uint8_t (*ret_two)(void);
 uint8_t (*par_one)(uint8_t p1);
 uint8_t (*par_two)(uint8_t p1, uint8_t p2);
};

struct test_funcs *test_funcs[NR_TEST_FUNCS];
uint8_t nr_test_funcs = 0;

void register_test_func(struct test_funcs *funcs)
{
 if (nr_test_funcs < NR_TEST_FUNCS-1) {
  test_funcs[nr_test_funcs] = funcs;
  nr_test_funcs++;
 }
}

void test_non_one(void)
{
 dbg_dump(1);
}

void test_non_two(void)
{
 dbg_dump(2);
}

uint8_t test_ret_one(void)
{
 return 3;
}

uint8_t test_ret_two(void)
{
 return 4;
}

uint8_t test_par_one(uint8_t p1)
{
 return p1;
}

uint8_t test_par_two(uint8_t p1, uint8_t p2)
{
 return p1+p2;
}

code struct test_funcs funcs1 = {
 test_non_one,
 test_non_two,
 test_ret_one,
 test_ret_two,
 test_par_one,
 test_par_two,
};

code struct test_funcs funcs2 = {
 test_non_one,
 test_non_two,
 test_ret_one,
 test_ret_two,
 test_par_one,
 test_par_two,
};

static void test_funcs_ptr(void)
{
 uint8_t i;
 register_test_func(&funcs1);
 register_test_func(&funcs2);

 for (i = 0; i < nr_test_funcs; i++) {
  (test_funcs[i]->non_one)();
  (test_funcs[i]->non_two)();
  (*(test_funcs[i]->non_one))();
  (*(test_funcs[i]->non_two))();
  dbg_dump((*(test_funcs[i]->ret_one))());
  dbg_dump((*(test_funcs[i]->ret_two))());
  dbg_dump((*(test_funcs[i]->par_one))(5));
  dbg_dump((*(test_funcs[i]->par_two))(5, 1));
 }
}

void main(void)
{
 main_debug(MAIN_DEBUG_INIT, 0);
 system_init();
 test_funcs_ptr();
 main_debug(MAIN_DEBUG_INIT, 1);

 while (1);
}

2. We has to pass function pointers and save them in the memory
   This can work.

typedef uint8_t usb_cid_t;
typedef uint8_t usb_iid_t;
typedef uint8_t usb_eid_t;
typedef uint8_t usb_addr_t;
typedef uint16_t usb_tsize_t;
typedef uint8_t usb_esize_t;

typedef void (*usb_io_cb)(void);
typedef usb_tsize_t (*usb_size_cb)(void);

typedef uint8_t hid_rid_t;
typedef void (*hid_poll_cb)(uint8_t endp);

struct hid_report {
 uint8_t duration;
 usb_tsize_t input_len;
 usb_tsize_t output_len;
 usb_io_cb input_data;
 usb_io_cb output_data;
 hid_poll_cb poll_intr;
 usb_size_cb config_len;
 usb_io_cb ctrl_data;
};


hid_rid_t hid_register_report(uint8_t duration,
         usb_tsize_t input_len,
         usb_tsize_t output_len,
         usb_io_cb input_data,
         usb_io_cb output_data,
         hid_poll_cb poll_intr,
         usb_size_cb config_len,
         usb_io_cb ctrl_data)
{
 hid_rid_t rid = hid_nr_reports;
 if (rid < NR_HID_REPORTS) {
  hid_reports[rid].input_data = input_data;
  hid_reports[rid].poll_intr = poll_intr;
  hid_reports[rid].output_data = output_data;
  hid_reports[rid].ctrl_data = ctrl_data;
  hid_reports[rid].config_len = config_len;
  hid_reports[rid].duration = duration;
  hid_reports[rid].input_len = input_len;
  hid_reports[rid].output_len = output_len;

  hid_rept_ctrls[rid].interval = 0;
  hid_rept_ctrls[rid].flags = 0;
  hid_nr_reports++;
 }
 return rid;
}

void kbd_hid_init(void)
{
 kbd_hid_rid = hid_register_report(HID_DURATION_NEVER,
       KBD_HID_INPUT_BYTES,
       KBD_HID_OUTPUT_BYTES,
       kbd_input_data,
       kbd_output_data,
       kbd_poll_intr,
       kbd_config_len,
       kbd_ctrl_data);
 kbd_capture_old = kbd_set_capture(kbd_handle_key_event);
}
------------------------------------------------------------------------------
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to