
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone. I'm working on M52259demokit, CW 7.2.1 and MQX 3.6.1.
I have to manipulate some strings: I have a main string, called "buffer", which contains several numbers (double and integers) separated by "S". I need to split the above string into these numbers and save them to variables.
First trial was:
result = sscanf (buffer, "%fS%fS%fS%fS%dS%dS%dS%dS%dS%dS%dSC%d", &LONG, &LAT, &AZ_b, &H_b, &dd, &mm, &yy, &hr, &min, &sec, &TZ, &chksum);
where I tried all the format for double, %.10f, %lf etc.. this sscanf returns always 0. I'm also using the directive
#define MQX_INCLUDE_FLOATING_POINT_IO 1
in user_config.h. Are there any limitation in sscanf? Maybe too many arguments?
The second trial was:
strcpy (LONG_string, strtok (buffer, "SC"));
that should be repeated for every substring I want to save. But I get the following link errors:
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_n'
from address 0x00036B40 in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_n'
from address 0x00036B2E in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_s@0'
from address 0x00036B42 in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_s@0'
from address 0x00036B36 in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_s@0'
from address 0x00036B30 in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_s@0'
from address 0x00036AC8 in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link Error : Illegal 16-bit small data area relative reference to symbol '_@LOCAL@strtok__FPcPCc@strtok_s@0'
from address 0x00036A9E in section '.text' of file 'libc.a string.o '.
This type of reference has a range from 4294934528 to 32767 bytes.
Project: MQX_ARCH.mcp, Target: Int Flash Debug
Link failed.
Any suggestions?
Thank you,
Marco
Solved! Go to Solution.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Marco,
I played around with your issue and now can read in your string, parse it, and get the variables into the right locations.
What I discovered is the sscanf() with the #define MQX_INCLUDE_FLOATING_POINT_IO 1 in the user_config.h, uses double for the string conversion. So when I originally created a buffer using a float then passed the buffer to sscanf it returned wrong conversion. But when I used double for the formatting of the buffer it works.
I started with the simple hello project in mqx/examples and have included the source file for your reference.
Hopefully this helps.
Regards,
David

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, I found out that the problem is in the float/double formatter in sscanf. If I decide to scan a string with only integer formatter I get the right result. So, which is the right formatter save double precision variables from a string?
Regards,
Marco

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Finally I found the real cause of all those problems. It is the linker file that I modified to have my non volatile section of ram (nvram). You can see it in the code below. If I restore the original linker file those string function work fine.
MEMORY{## intflash (RX): ORIGIN = 0x00000000, LENGTH = 0x00080000## sram (RW): ORIGIN = 0x20000000, LENGTH = 0x00010000 vectorrom (RX): ORIGIN = 0x00000000, LENGTH = 0x00000400 cfmprotrom (RX): ORIGIN = 0x00000400, LENGTH = 0x00000020 rom (RX): ORIGIN = 0x00000420, LENGTH = 0x0007FBE0 # Code + Const data ram (RW): ORIGIN = 0x20000000, LENGTH = 0x00010000 # SRAM - RW data# relocate (RWX): ORIGIN = 0x20003F00, LENGTH = 0x0000C100 # kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap) end_of_kd (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000 # Boot stack reused by MQX Kernel data bstack (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200 # Boot stack end_bstack (RW): ORIGIN = 0x2000FBFF, LENGTH = 0x00000000}KEEP_SECTION { .vectors_rom, .vectors_ram, .cfmconfig }SECTIONS{ ___INTERNAL_SRAM_BASE = 0x20000000; ___INTERNAL_SRAM_SIZE = 0x00010000; ___INTERNAL_FLASH_BASE = 0x00000000; ___INTERNAL_FLASH_SIZE = 0x00080000; ___IPSBAR = 0x40000000; # Peripherals/FlexCAN ___VECTOR_TABLE_START = 0x20000000; # Runtime vector table in sram # MQX link time configurations ___DEFAULT_PROCESSOR_NUMBER = 1; ___DEFAULT_INTERRUPT_STACK_SIZE = 1024; ___KERNEL_DATA_VERIFY_ENABLE = 0; # Test SDRAM read/write # Flashx configurations ___FLASHX_SECT_SIZE = 0x1000; .vectors : { ___VECTOR_TABLE_ROM_START = .; # Runtime vector table in sram *(.vectors_rom) . = ALIGN (0x4); } > vectorrom .cfmprotect : { *(.cfmconfig) . = ALIGN (0x4); } > cfmprotrom .main_application : { *(KERNEL) *(S_BOOT) *(IPSUM) *(.text) *(.init) *(.fini) *(.eini) *(.ctors) *(.dtors) .= ALIGN(0x4); *(.rodata) .= ALIGN(0x4); *(.rdata) . = ALIGN(0x4); *(.exception) . = ALIGN(0x4); __exception_table_start__ = .; EXCEPTION __exception_table_end__ = .; ___sinit__ = .; STATICINIT .= ALIGN(0x4); __COPY_OF_DATA = .; } > rom .main_application_data : AT(__COPY_OF_DATA) { . = ALIGN(0x10000); ___VECTOR_TABLE_RAM_START = .; # Runtime vector table in sram *(.vectors_ram) . = ALIGN(512); __BDT_BASE = .; *(.usb_bdt) __BDT_END = .; __START_DATA = .; *(.data) __END_DATA = .; __START_DATA = .; *(.my_zone) __END_DATA = .; . = ALIGN(0x4); __SDA_BASE = .; __SDA_BASE_ = __SDA_BASE; } > ram .main_application_bss : { __START_SBSS = .; *(.sbss) *(SCOMMON) __END_SBSS = .; __START_BSS = .; *(.bss) *(COMMON) __END_BSS = .; } >> ram .nvram : { __START_MYRAM = .; *(.nvram) __END_MYRAM = .; } >> ram .kernel_data : #AT(ADDR(.main_application_bss) + SIZEOF(.main_application_bss)) { ___KERNEL_DATA_START = ALIGN(0x10); } .end_of_kernel_data : { ___KERNEL_DATA_END = .; } > end_of_kd .boot_stack : { _stack_end = .; } > bstack .end_of_boot_stack : { _stack_addr = .; __SP_INIT = .; ___BOOT_STACK_ADDRESS = .; } > end_bstack # Locate the ROM copy table into ROM after the initialized data _romp_at = __COPY_OF_DATA + SIZEOF(.main_application_data); .romp : AT (_romp_at) { __S_romp = _romp_at; WRITEW(__COPY_OF_DATA); #ROM start address WRITEW(ADDR(.main_application_data)); #RAM start address WRITEW(SIZEOF(.main_application_data)); #size WRITEW(0); WRITEW(0); WRITEW(0); } _flashx_start = __COPY_OF_DATA + SIZEOF(.main_application_data) + SIZEOF(.romp); # flashx working area spans across the whole rest of Flash memory ___FLASHX_START_ADDR = (_flashx_start + 0xfff) / 0x1000 * 0x1000; ___FLASHX_END_ADDR = ___INTERNAL_FLASH_BASE + ___INTERNAL_FLASH_SIZE;}/* EOF */
Any suggestion on how to solve the problems?
Regards,
Marco


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Marco,
I played around with your issue and now can read in your string, parse it, and get the variables into the right locations.
What I discovered is the sscanf() with the #define MQX_INCLUDE_FLOATING_POINT_IO 1 in the user_config.h, uses double for the string conversion. So when I originally created a buffer using a float then passed the buffer to sscanf it returned wrong conversion. But when I used double for the formatting of the buffer it works.
I started with the simple hello project in mqx/examples and have included the source file for your reference.
Hopefully this helps.
Regards,
David

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Davids, the problem was already solved. There were bad lines in my linker file.
Anyway I may be reading a useful information in your post. You're saying that if MQX_INCLUDE_FLOATING_POINT_IO is defined as 0, sscanf accepts only float variables as arguments, wasting obviously much less memory than the case in which double precision is used. Have I understood right?


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Marco,
What I've seen on the code base is that if you want to use floating point format the code #define MQX_INCLUDE_FLOATING_POINT_IO 1 must be in the user_config.h.
If the #define is 0 or not included, then the code base doesn't support the floating point (more correctly the double format).
So it is a binary decision....if wanting floating point formating you must define your variable as "double". The code base just does not support the "float" option.
You can review the code in mqx/source/fio/io_scanl.c source file.
Regards,
David

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, the problem was this subsection
__START_DATA = .; *(.my_zone) __END_DATA = .;
in section .main_application_data.
