Hi,

It looks like you think you've found a bug. Posting it in the user mailing
list might get you a quick answer. But if not, it is bound to be
forgotten. Bugs should be reported in the bug tracker system. Please
repost.

Maarten

> 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
>
>


------------------------------------------------------------------------------
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to