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.
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
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
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
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
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?
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
Ok, the problem was this subsection
__START_DATA = .; *(.my_zone) __END_DATA = .;
in section .main_application_data.