Program memory not increasing when including math.h library - c

I'm a bit of a newbie to the Atmel world. Once Upon a time I could write and compile C with Visual Studio but am a bit out of practice.
So I'm trying to get an understanding of memory usage in a microcontroller ATTINY1616. I opened Atmel studios, created a C executable project and chose the correct microcontroller. I build the project which has next to nothing in it and see that the program memory is 154 bytes. This is my baseline.
Now I tried to add the line #include <math.h> to see if my program memory usage would increase. It didn't. Then I tried adding float a = 2.000678f; inside the main. Still no increases after building the project. What am I misunderstanding here?
/*
* GccApplication2.c
*
* Created: 12/20/2018 9:21:43 PM
* Author : joely
*/
#include <avr/io.h>
#include <math.h>
int main(void)
{
float a = 2.000678f;
/* Replace with your application code */
while (1)
{
}
}

Header files typically only contain declarations of functions, not the definitions.
You're not using any of the functions declared in math.h, so the library they reside in isn't getting linked into your program. If you use one of them, for example float b = sin(a), then the contents of the math library is required and is linked in (assuming you pass -lm to gcc to do so).

So after asking some friends with microcontroller experience I found the solution.
In Atmel Studio you need to go to Project-->Application Properties--->Toolchain and Change optimization to none.
Then it recognizes my floats and stores them in program memory, and when atan() is used to perform a calc it also fills up the space with the same above code.

Related

use variables from a C generated file

I have generated a C file which contains some arrays with their size as here:
nor.c (generated file)
const float nor[] = {
-0.0972819, 0.906339, -0.4112, -0.056471, 0.340899, -0.938402, -0.284611, 0.269598, -0.919953, 0.04142, -0.149024, -0.987966, 0.12454, -0.702485, -0.700717, 0.0027959, -0.188166, -0.982133 };
const unsigned int nor_size= 18;
when I called this array from my main file as shown here:
extern float nor[nor_size];
I got some error: cannot use nor_size as a const
how to solve this?
thanks
how to solve this?
The best would be for the generator of the nor.c file to also generate a corresponding nor.h file
#ifndef NOR_INCLUDE_GUARD
#define NOR_INCLUDE_GUARD
extern const float nor[18];
extern const unsigned int nor_size;
#endif
main.c uses that .h file
// Rather than
// extern float nor[nor_size];
// Include
#include "nor.h"
Also recommend the generator of the nor.c fil to append an f suffix to each constant.
In your main.c remove extern float nor[nor_size]; then add
extern const float nor[];
extern const unsigned int nor_size;
and use them as appropriate. Indeed, nor_size might then be loaded (in processor registers at the machine code level) several times.
For more, read this C reference, and later some C standard like n1570 or better.
If you are allowed to compile all your C (both handwritten and generated) code with some recent GCC compiler (or cross-compiler), invoke it at least with -Wall -Wextra -g options.
don't forget to read the documentation of your C compiler!
You also need to understand what is your linker, and read its documentation. Maybe it could be GNU binutils.
You could use some static source code analyzer, like Clang static analyzer, or Frama-C, or Bismon. FYI, Bismon has 24604 lines of generated C code, and the Bigloo compiler has a lot of them too.
for Frama-C or Bismon, contact me by email to basile.starynkevitch#cea.fr and mention the URL of your question
Read also a good C programming book, like Modern C
In 2021, you could be interested by the DECODER project. It is strongly related to your question.
An interesting book describing a software which generates all the half-million lines of code of its C source (available here) is Pitrat's Artificial Beings: the Conscience of a Conscious Machine (ISBN 978-1848211018). You could enjoy reading that book.
See also this answer about generating C code.
You could also be interested by GNU bison. It is a free software parser generator, mostly written in C, and generates C code. My recommendation is to download its source code and take inspiration from it.
By experience, when you are generating C code, it is easier to improve the generator (so that the generated C code compiles cleanly without warnings) that to change the generated C code. But do document well your C code generator. Read about partial evaluation techniques.

Gathering test symbols into an array statically in C/C++

Short version of question
Is it possible to gather specific symbols in C into a single list/array into the executable statically at compile time, without relying on crt initialization (I frequently support embedded targets, and have limited support on dynamic memory).
EDIT: I'm 100% ok with this happening at link time and also ok with not having symbols cross library boundaries.
EDIT 2: I'm also OK with compiler specific answers if it's gcc or clang but would prefer cross platform if possible.
Longer version with more background
This has been a pain in my side for a while.
Right now I have a number of built-in self tests that I like to run in order.
I enforce the same calling convention on all functions and am manually gathering all the tests into an array statically.
// ThisLibrary_testlist.h
#define DECLARE_TEST(TESTNAME) void TESTNAME##_test(void * test_args)
DECLARE_TEST(test1);
DECLARE_TEST(test2);
DECLARE_TEST(test3);
// ThisLibrary_some_module.c
#include "ThisLibrary_testlist.h"
DECLARE_TEST(test1)
{
// ... do hood stuff here
}
// ThisLibrary_testarray.c
#include "ThisLibrary_testlist.h"
typedef void (*testfunc_t) (void*);
#define LIST_TEST(TESTNAME)
testfunc_t tests[] =
{
&LIST_TEST(test1),
&LIST_TEST(test2)
};
// now it's an array... you know what to do.
So far this has kept me alive but it's getting kind of ridiculous that I have to basically modify the code in 3 separate locations if I want to update a test.
Not to mention the absolute #ifdef nightmare that comes with conditionally compiled tests.
Is there a better way?
With a bit of scripting magic you could do the following: After compiling your source files (but before linking) you search the object files for symbols that match your test name pattern. See man nm how to obtain symbol names from object files (well, on Unix, that is - no idea about windows, sorry). Based on the list of object names found, you auto-create the file ThisLibrary_testarray.c, putting in all the extern declarations and then the function pointer table. After generation of this file, you compile it and finally link everything.
This way you only have to add new test functions to the source files. No need to maintain the header file ThisLibrary_testlist.h, but you have to make sure the test functions have external linkage, follow the naming pattern - and be sure no other symbol uses the naming pattern :-)

How to call dpois_raw C stats routine from R

I'm trying to figure out a way to call stats package's "dpois_raw" routine rather than the "dpois" wrapper using .Call .External or whatever means.
"dpois_raw" is not listed in the package environment (stats:::C_*) nor when I do getDLLRegisteredRoutines("stats") so I am probably out of luck, but I wonder whether someone R/C expert knows of a workaround.
The dpois_raw routine is provided by the Rmath.h header, and it doesn't appear to actually be exposed as part of the stats package (or otherwise); however, it is made available to C / C++ code through the Rmath.h header.
The simplest way to expose it would be with your own C / C++ code exposing that code, e.g. (code stub)
#include <R.h>
#include <Rmath.h>
SEXP my_dpois_raw(<...>) {
double result = dpois_raw(<...>);
return result;
}
This routine would then be callable from R with something like
.Call("my_dpois_raw", <...>)
See Hadley's r-pkgs section on using compiled code in R packages for some more information on including C / C++ code in an R package.

Interface between R and C libraries / BLAS / OS X

I'm writing some C programs (I'm quite a beginner in C), that I compile and call from R. In order to be as efficient as possible, I try to use as much as possible functions from Lapack and BLAS (which contain highly optimised routine to perform basic operations).
I compile my .c codes thanks to, classically:
system ('R CMD SHLIB blablabla.c')
Here is the "preamble" of my average .c code:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <R_ext/blas.h>
#include <R_ext/Lapack.h>
Here is my "dummy" problem: I need to compute the "argmin of a real vector", i.e., the index of the minimal component of the vector (in practice, for huge vectors and a lot of times, so that I really like to use an optimised routine, and not a basic "for" loop).
"Unfortunately", in "R_ext/blas.h", the function IDMIN does not appear ("R_ext/blas.h" only contains the function IDAMAX, that returns the index of the maximum absolute value component).
In R, such a task is easily achieved by "which.min()" (which is, I guess, based on an optimised code), so I guess that it should "somewhere" exists the C code (certainly based on a FORTRAN code) that achieves this task, and this is exactly what I need...
In other words: what library should I add to my ".c preamble" and what C function should I use to be able to use an "optimised which.min()" in my C code (that I compile and call from R) ?
Another question: On Mac OS X, how to add some C libraries to the existing C libraries of R (still, with the view to compile and use C from R, which is in my view very convenient) ?
Thanks.

What are those extra assembly codes put by compiler when compiling a C program for a microcontroller?

I wanted to write a piece of code in C for my Stellaris launchpad just to turn on the onboard LED by keeping the library usage to minimum. To my surprise, the compiled code was around 800 bytes in size. So to check what was put in to the compiled code by the compiler, I checked the assembly code using a dissambler. It had a lot of code which I didn't write the C code for. I would like to know what those codes are for and how did it enter the compiler setting. I am trying to learn how a compiler behaves and what behind-the-scenes things the compiler is doing. Please help me.
This is my C program:
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#define GPIOFBASE 0x40025000
#define GPIOCLK *((volatile unsigned long *)(0x400FE000 + 0x608))
#define FDIR *((volatile unsigned long *)(GPIOFBASE + 0x400))
#define FDEN *((volatile unsigned long *)(GPIOFBASE + 0x51C))
#define FDATA *((volatile unsigned long *)(GPIOFBASE + 0x3FF))
void main(void) {
ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
GPIOCLK |= (1<<5);
FDIR |= 0xE;
FDEN |= 0xE;
FDATA |= 0xE;
while (1);
}
The only API call I used was to set the Clock setting using a Onchip ROM library. Please check the dissambly code at this pastebin: (The main: is at 0x190.)
http://pastebin.com/wNNsBdtT
The additional code will be CPU initialisation and C runtime initialisation. The source code for this start-up is probably provided with your compiler. In GCC for example it is normally called crt0.s
Depending on your CPU and memory it will probably require some initialisation to set the correct clock frequency, memory timing etc. On top of that the C runtime requires static data initialisation and stack initialisation. If C++ is supported additional code is necessary to call the constructors of any static objects.
Cortex-M devices like Stellaris are designed to run C code with minimum overhead, and it is possible to essentially start C code from reset, however the default start-up state is often not what you want to run your application is since for example this is likley to run at a lower and less accurate clock frequency.
Added 06Dec2012:
Your start-up code is almost certainly provided by the CMSIS. The CMSIS folder will contain CoreSupport and DeviceSupport folders containing start-up code. You can copy this code (or the relevant parts of it) to your project, modify it as necessary and link it in place of the provided code. The CMSIS is frequently updated, so there is an argument for doing that in any case.
Your build log and/or map file are useful for determine which CMSIS components are linked.

Resources