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
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/sdcc-user
>
>
------------------------------------------------------------------------------
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user