I am trying to build a simple logic analyzer with TM4c123 but anytime when I use the function ROM_.... it appears to be an error( implicit of function ROM_..) Anyone knows why?
for example:
ROM_FPUEnable();
ROM_FPULazyStackingEnable();
// run from crystal, 80 MHz
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
// enable peripherals
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// set UART pins
GPIOPinConfigure(0x00000001);
GPIOPinConfigure(0x00000401);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
// init PORTB
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIO_PORTB_DIR_R = 0x00;
GPIO_PORTB_DEN_R = 0xff;
// configure uart
ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
All of the function ROM are errors, why? I already include rom.h and rom_map.h
You probably didn't defined your target device.
Try to add something like -DTARGET_IS_TM4C123_RB1 to your Makefile.
This define is necessary in order for the ROM_* symbols be defined.
You are using a combination of driverlib (tivaware) and direct register modification (DRM). Use one or the other, preferably driverlib.
You should actually be using the MAP_ calls instead of ROM_. ROM_ is deprecated but still usable for testing. Don't put ROM_ in production code. I know the examples still use ROM_.
You are missing the header file for ROM anyways. If you want to use ROM_, you need to include driverlib/rom.h. That's why it's complaining about the implicit function call. Any call to a ROM_somethingsomethingdarkside() is not defined. You will also need to include stdint and stdbool, as driverlib uses those c99 types. To use the map calls, you'll need to include driverlib/rom_map.h
You may also need to include driverlib/gpio.h, driverlib/sysctrl.h. Not sure on that. I've never mixed things like you have done, and I always debug using the compiled in driverlib first, then prefixed the driverlib calls with MAP_ after I know things are working. I haven't ever gone back to remove my includes for the compiled in driverlib libraries. The toolchain seems to be smart enough to not compile them in after I stop calling them anyways. Now I kinda want to try that though.
To be clear, ROM_ or MAP_ is calling driverlib calls out of the on chip ROM.
I suspect that you are not sure what the code you are using really is and what it does by the way you're mixing DRM and driverlib libraries. I HIGHLY suggest you take the time to go through the online workshop for the Tiva C. It's a series of short videos and labs that will clear up all of this. I went intentionally neurotically slow and it took me a weekend. You can do it in a day, and it'll be a day well spent. It'll save you that many times over. It's out of date slightly as far as code composer goes, but it's still useable. I have all my students go through it before they start work on this platform.
http://processors.wiki.ti.com/index.php/Getting_Started_with_the_TIVA™_C_Series_TM4C123G_LaunchPad
Edit: yes, and as vitor points out, you also need that define as well.
I would reccommend using "driverlib/gpio.h" and "driverlib/sysctl.h"
for the Pin configuration with TM4C devices
Related
I have a static "init" variable to run a function once on startup, (RTOS) but it seems to initialize to a random value. If I remove the static tag, everything works great. (Except for the obvious issue of it running the init function every pass.) Could anyone give more insight as to why this isn't working or perhaps a better way to achieve this?
Example code:
void ManageStructures()
{
// Variable declarations/definitions
static uint8_t StructInitialized;
// Have also tried "static uint8_t StructInitialized = 0", neither worked
// Function prototypes
void InitStruct();
if (!StructInitialized)
{
StructInitialized= 1;
InitStruct();
}
Test = StructInitialized;
edit: I apologize for the lack of information. This is for a company and I am trying to stay within the bounds of our public information policy. The MCU is a STM32F7 series using the "Ac6 STM32 MCU GCC" toolchain. I am not well versed in compiler operations so it may take me longer to find answers to the compiler or makefile related questions.
edit: It has become clear that this is an issue with the compiler or linker scripts and not my code. That being said, it has also become abundantly clear that I need to learn more about toolchains, linker scripts, and compilers in general before getting to the root of this issue. I'll return to this question once I have become familiar enough to give valuable feedback or answer it myself. Thank you everyone for the feedback and direction!
It is common that embedded systems run with a "minimal startup" code, meaning that they never initialize .bss or .data during start-up. Meaning that if you write something like static int foo = 42;, the code will compile but the variable will never be set.
This isn't standard C compilant, so usually upon project creation you get an option from the IDE to have a "minimal" or "standard" startup.
This likely lies in the so-called "CRT" (C run-time) delivered with your tool chain and not in the RTOS. If you single step your program from where it actually starts (the reset vector) rather than from where main() starts, you'll be able to see exactly what the CRT does and doesn't.
Unfortunately debuggers often use a "dumbed-down mode", since embedded systems programmers are by default assumed to be completely incompetent nowadays. Meaning that they silently insert a breakpoint at main() and run until that point. You might have to "un-dumb" your debugger in order to debug the CRT.
I'm writing a small operating system for microcontrollers in C (not C++, so I can't use templates). It makes heavy use of some gcc features, one of the most important being the removal of unused code. The OS doesn't load anything at runtime; the user's program and the OS source are compiled together to form a single binary.
This design allows gcc to include only the OS functions that the program actually uses. So if the program never uses i2c or USB, support for those won't be included in the binary.
The problem is when I want to include optional support for those features without introducing a dependency. For example, a debug console should provide functions to debug i2c if it's being used, but including the debug console shouldn't also pull in i2c if the program isn't using it.
The methods that come to mind to achieve this aren't ideal:
Have the user explicitly enable the modules they need (using #define), and use #if to only include support for them in the debug console if enabled. I don't like this method, because currently the user doesn't have to do this, and I'd prefer to keep it that way.
Have the modules register function pointers with the debug module at startup. This isn't ideal, because it adds some runtime overhead and means the debug code is split up over several files.
Do the same as above, but using weak symbols instead of pointers. But I'm still not sure how to actually accomplish this.
Do a compile-time test in the debug code, like:
if(i2cInit is used) {
debugShowi2cStatus();
}
The last method seems ideal, but is it possible?
This seems like an interesting problem. Here's an idea, although it's not perfect:
Two-pass compile.
What you can do is first, compile the program with a flag like FINDING_DEPENDENCIES=1. Surround all the dependency checks with #ifs for this (I'm assuming you're not as concerned about adding extra ifs there.)
Then, when the compile is done (without any optional features), use nm or similar to detect the usage of functions/features in the program (such as i2cInit), and format this information into a .h file.
#ifndef FINDING_DEPENDENCIES
#include "dependency_info.h"
#endif
Now the optional dependencies are known.
This still doesn't seem like a perfect solution, but ultimately, it's mostly a chicken-and-the-egg problem. When compiling, the compiler doesn't know what symbols are going to be gc'd out. You basically need to get this information from the linker stage and feed it back to the compilation stage.
Theoretically, this might not increase build times much, especially if you used a temp file for the generated h, and then only replaced it if it was different. You'd need to use different object dirs, though.
Also this might help (pre-strip, of course):
How can I view function names and parameters contained in an ELF file?
Just bought an MSP430 launchpad
Been reading through stuff, but I'm unable to learn from all those verbose sources how to stick my C program inside the micro controller. They're not objective (I've started with the manuals that came within, then following hundreds of links on texas website. They are poorly informative).
TO BEAR IN MIND:
I'm a student;
My professor isn't of much help;
I'm completely new to this hardware stuff. Kind of new on C programming too... we can say a year of practice;
I consider the KISS principle a good practice: My teacher accomplishes a firework of LEDs with a .c file, a makefile, and a make.exe that I don't have the least idea of what is and how works.
Below, my steps taken so far: (They did NOT work. That's the reason I'm asking here. I would appreciate a very objective procedure/corrections at first, and later, the brainstorm)
Downloaded mspgcc-20120406-p20120911
Installed that on Code::Blocks, using Settings > Compiler - Toolchain Executables tab
(I've tried Energia, but doesn't seem like a very orthodox .c editor. And I love codeblocks, or devcpp, or, as a third option, notepad++, or even Eclipse)
I've also tried CodeComposerStudio. After downloading packages and starting a full project answering neverending questions, I still don't know how to flash the code.
I even made a simple program to blink a led:
#include <stdio.h>
#include <msp430f5529.h>
#include <msp430.h>
void ConfigureCpu(void)
{
WDTCTL = 0x5a80;
// ACLK = 32768 Hz
// MCLK = 16000000 Hz
// SMCLK = 16000000 Hz
DCOCTL = 0x74;
BCSCTL1 = 0x0F;
BCSCTL2 = 0x88;
BCSCTL3 = 0x84;
P4DIR = 0xff;
}
void delayms(t)
{
int i, x;
for(i=0;i<=t;i++)
for(x=0;x<16000;x++);
}
int main()
{
ConfigureCpu();
while(1)
{
P4OUT=0x42; //0100 0010 = 0x42
delayms(1000);
P4OUT=0x00;
delayms(1000);
}
}
It doesn't work for two reasons:
'DCOCTL' undeclared (first use in this function)|
And if I comment those registers, I get the following:
cannot open linker script file memory.x||No such file or directory|
.
L:\MSP\ is my directory for everything related to this journey
Example:
L:\MSP\GCC
L:\MSP\Flasher\
L:\MSP\Programs //my .c are stored here
(Code::Blocks is installed on the root of C:)
I would like someone to tell me what I need to learn (step by step, if possible, from the very beginning, to the very end - from choosing tools, to uploading to the controller)
The flyer in the box describes what to do.
Go to www.ti.com/launchpad and download either Code Composer Studio 4 or the IAR Embedded Workbench trial.
The TI page also holds all other information that you might need.
Looking at msp430f5529.h file on my system, it seems like this chip doesn't have those registers or they aren't in the header. The code just sets the register to a magic number with no explanation, comment, or calculation, so it's hard to figure out what the purpose is. (It's probably trying to configure clocks.)
Second, you'll probably need that linker file for your chip so the compiler (linker stage) can set up correct memory addresses.
The code actually looks like a blinky, but meant for a different chip or compiler. It would probably work but you'd need to change the parts that are different (port it) for your setup. It would be educational, but perhaps not what you want to spend your time on.
To solve both problems, I'd start by getting a project meant for the particular chip/board you have. Build that and see if it works. Then you know your compiler and the project work. You can go on to modify it for your application.
I am using the STM32 HAL Library for a micro controller project. In the ADC section I found the following code:
uint32_t WaitLoopIndex = 0;
/...
.../
/* Delay for ADC stabilization time. */
/* Delay fixed to worst case: maximum CPU frequency */
while(WaitLoopIndex < ADC_STAB_DELAY_CPU_CYCLES)
{
WaitLoopIndex++;
}
It is my understanding that this code will most likely get optimized away since WaitLoopIndex isn't used anywhere else in the function and is not declared volatile, right?
Technically yes, though from my experiences with compilers for embedded targets, that loop will not get optimised out. If you think about it, having a pointless loop is not really a construct you are going to see in a program unless the programmer does it on purpose, so I doubt many compilers bothers to optimise for it.
The fact that you have to make assumptions about how it might be optimised though means it most certainly is a bug, and one of the worst types at that. More than likely ST wanted to only use C in their library, so did this instead of the inline assembler delay that they should have used. But since the problem they are trying to solve is heavily platform dependent, an annoying platform/compiler dependent solution is unavoidable, and all they have done here is try to hide that dependency.
Declaring the variable volatile will help, but you still really have no idea how long that loop is taking to execute without making assumptions about how the compiler is building it. This is still very bad practice, though if they added an assert reminding you to check the delay manually that might be passable.
This depends on the compiler and the optimization level. To confirm the result, just enter debug mode and check the disassembly code of the piece of code.
I'm working on an embedded C project that depends on some external HW. I wish to stub out the code accessing these parts, so I can simulate the system without using any HW. Until now I have used some macros but this forces me to change a little on my production code, which I would like to avoid.
Example:
stub.h
#ifdef _STUB_HW
#define STUB_HW(name) Stub_##name
#else /*_STUB_HW*/
#define STUB_HW(name) name
#endif /*_STUB_HW*/
my_hw.c
WORD STUB_HW(clear_RX_TX)()
{ /* clear my rx/tx buffer on target HW */ }
test_my_hw.c
#ifdef _STUB_HW
WORD clear_RX_TX()
{ /* simulate clear rx/tx buffer on target HW */ }
With this code I can turn on/off the stubbing with the preprocessor tag _STUB_HW
Is there a way to acomplish this without having to change my prod code, and avoiding a lot of ifdefs. And I won't mix prod and test code in the same file if I can avoid it. I don't care how the test code looks as long as I can keep as much as possible out of the production code.
Edit:
Would be nice if it was posible to select/rename functions without replacing the whole file. Like take all functions starting on nRF_## and giving then a new name and then inserting test_nRF_## to nRF_## if it is posible
I just make two files ActualDriver.c and StubDriver.c containing exactly the same function names. By making two builds linking the production code against the different objects there is no naming conflicts. This way the production code contains no testing or conditional code.
As Gerhard said, use a common header file "driver.h" and separate hardware layer implementation files containing the actual and stubbed functions.
In eclipse, I have two targets and I "exclude from build" the driver.c file that is not to be used and make sure the proper one is included in the build. Eclipse then generates the makefile at build time.
Another issue to point out is to ensure you are defining fixed size integers so your code behaves the same from an overflow perspective. (Although from your code sample I can see you are doing that.)
I agree with the above. The standard solution to this is to define an opaque abstracted set of function calls that are the "driver" to the hw, and then call that in the main program. Then provide two different driver implementations, one for hw, one for sw. The sw variant will simulate the IO effect of the hw in some appropriate way.
Note that if the goal is at a lower level, i.e., writing code where each hardware access is to be simulated rather than entire functions, it might be a bit tricker. But here, different "write_to_memory" and "read_from_memory" functions (or macros, if speed on target is essential) could be defined.
There is no need in either case to change the names of functions, just have two different batch files, make files, or IDE build targets (depending on what tools you are using).
Finally, in many cases a better technical solution is to go for a full-blown target system simulator, such as Qemu, Simics, SystemC, CoWare, VaST, or similar. This lets you run the same code all the time, and instead you build a model of the hardware that works like the actual hardware from the perspective of the software. It does take a much larger up-front investment, but for many projects it is well worth the effort. It basically gets rid of the nasty issue of having different builds for target and host, and makes sure you always use your cross-compiler with deployment build options. Note that many embedded compiler suites come with some basic such simulation ability built in.