2014-04-27 03:04 PM
Hi everyone,
I'm trying to understand how registers and memory really works in a microcontroller and how to access data in registers using C Now I can access any address in the memory and I can write any data to it Now can I access a single bit in the memory without ORing or ANDing the register's value with some other value I watched a video on youtube that explains how to do so in TI kit and it says that there's a register called GPIO_PORTF_DATA_BITS_R which access each single bit in the memory and it says also that the CPU can access each bit with a single data bus and a single address bus .. so that I can modify a single bit's value without using AND or OR and without any side effects on the other bits in the same register .. is this true .. and if so how can I do this with stm32f4-discovery kit another point .. I know that there's some thing that's called bit-field and it can be used in a structure to reduce the space in memory it uses .. how can this really happen for example, in this code <b>struct example2 { int isMemoryAllocated : 1; int isObjectAllocated : 1; }; int main(void) { struct example2 obj; obj.isMemoryAllocated = 1; return 0;
} </b> how can this really happen in hardware and why don't I use char data type which is 1 byte instead of using bit-fields?? the last point which is not clear for me is the use of volatile I know that volatile key word when used with a variable it tells the compiler that this variable can change without the control of the code in an unexpected way .. how can this happen .. I read that this could happen in three cases including -Interrupt handler and -memory-mapped registers ... HOW? I hope someone to explain this in a very simple way cause I've read so much about it but I don't really understand it clearly sorry for bothering but I'm really trying to deeply understand this stuff .. thanks a lot2014-04-27 04:18 PM
volatile is used in cases where the variable can change outside of the normal flow of code, and is important for the optimizer, because it might otherwise read a memory variable into a register and leave it there, assuming it doesn't change.
If you have a SysTick interrupt incrementing a counter, say TickCount++, and your regular code is waiting for this to change, it needs to keep re-reading the value in each loop iteration. For hardware you need to understand that the peripherals operate autonomously, status bits in their internal registers may change at any time, and without the processor knowing about it. For example the USARTx->SR flagging TXE or RXNE, or the TIMx->SR flagging CC1, CC2, Update events. Again if your are spinning in a loop waiting for these bits to change, you really don't want the optimizer to discard the code because it assumes the test needs to be done only once. Remember one of the jobs of the optimizer is to recognize and fold reads performed on the same memory variable, or to use internal processor registers in place of memory.2014-04-27 05:29 PM
I'm sorry sir if I'm bothering but I'm trying hard to understand this concept as clear as crystal cause I think it's essential in my embedded career
I wrote two snippets of code and checked out there assembly equivalent<b>
//the first snippetint volatile a = 1;
a++ //its assembly equivalentMOV R0,#1
STR R0,[SP]LDR R0,[SP]
;here it reloads the value from the stack and not taking the register valueADDS R0,R0,#1
STR R0,[SP] //the second snippetint b = 1;
b++; //its assembly equivalentMOVS R0,#1
ADDS R0,R0,#1 </b>For hardware you need to understand that the peripherals operate autonomously, status bits in their internal registers may change at any time,
and without the processor knowing about it.
HOW?? so how manage this operation?? I think that the processor is responsible for every thingFor example the USARTx->SR flagging TXE or RXNE
OK, when I implemented USART peripheral I was directly checking the memory position to know if the flag is set or reset, like in this snippet of code <b>while(!(USART1->SR & (1<<5)));
return ((int)(USART1->DR & 0xFF)); </b> now where should I use volatile ??? Note that this peripheral driver worked so fine I hope you don't fed up with me .. Thanks a lot sir2014-04-28 12:00 AM
now where should I use volatile ???
Note that this peripheral driver worked so fine
Look at the definition of those peripheral struct in stm32xxx.h (name depending on your MCU core), like USART. The struct members are already defined as volatile. Another example are variables accessed in interrupt handlers and (if using an OS) in theads.
2014-04-28 10:27 AM
''and if so how can I do this with stm32f4-discovery kit ''
Did you RTFRM0090? GPIO chapter is 19 pages long. 7th line, quoting: ''Bit set and reset register (GPIOx_BSRR) for bitwise write access to GPIOx_ODR''2014-04-28 11:08 AM
HOW?? so how manage this operation?? I think that the processor is responsible for every thing
Well, because the peripheral represent a huge chunk of synchronous logic that's designed to perform it's function outside of the CPU. The access you have at the CPU, is a small window into what is happening in the background. There are likely millions of logic gates you can't even see. The CPU is designed to load and execute instructions one at a time, it does not know how serial ports work, or how screen displays function. Think of the it like a bakery, you, in the CPU interact with shop workers who will take your order, and bring you bread and cakes from a display case, and take your money. Mean while in the background is a large factory, or kitchen, with lots of other workers unrelated to the shop staff, who busily make dough and feed it into an oven, and put the finished goods on racks to send into the shop. If you like car analogies, think of the CPU as the dealer showroom, and the PERIPHERAL as the car production factory. The staff have very different roles and are not interchangeable. See if you can find some books on Computer Architecture and Design, it might help if you think about it as separate components, instead of the System-On-a-Chip (SoC) where your idea of a CPU might be a bit blurred.Hennessy/Patterson
? Not sure I have a current one, and they were a bit MIPS leaning, but might make a good start.