Difference between an Address and a register (MCU addresses) and related questions - pointers

I am getting a little bit deeper in exploring the STM32's MCU and I went bare metal. I am using an STM32F103C8T6 BluePill.
Just to make sure I'm fully understanding what is going on, what is the nature of the addresses of the MCU? I mean, for my board, the RCC boundary address is 0x4002 1000 - 0x4002 13FF and by creating a custom named pointer to this address and type casing this "0x40021000" to be treated as an actual address by the compiler, is this an address of an actual register?
I mean what I understood is that the MCU has 32bit registers, those registers have addresses, those addresses are the addresses of the registers and each 32bit register in the MCU has a unique address, a physical one! And therefore to manipulate a specific register we create a pointer to the address of that register and then dereferencing the pointer and change the register it is pointing to.
For example, the RCC address starts at "0x40021000" and this address is of the register 0x0000XX83 (where X is undefined as per the reference manual), Am I right? Do those registers actually have addresses in the MCU so they can be accessed and manipulated? If so, are those registers bits are just transistors where when setting a bit in that register to 1 the transistor turns on?
Also if what I understood was correct, does that mean that the Reset Values are the actual register values which have addresses (as in registers are analogous to variables e.g x,y, etc.. and there addresses are those in the reference manual as in RCC address = 0x40021000 and dereferencing this address gives us 0x0000XX83 ??
I know I might have confused you but this is the best I can explain!
Thank you in advance.

Addresses are addresses on the bus*. When the compiler generates an instruction for the processor to read an address (LDR) it asks the bus to fetch what is at that address. Similarly a write instruction (STR) tells the bus what the address is and what data it wants to put there.
At the other end of the bus could be anything, but in most cases it will be either memory or a memory-mapped peripheral register. This could have any number of bits, but the most you can access in one go is 32. This is because the width of the bus is 32-bits. The datasheet lists the address ranges used by each peripheral, and the reference manual says what purpose of each peripheral register is.
In your example the RCC is a peripheral, its address range is 0x40021000-0x400213FF. The first register in the RCC is RCC_CR, which has address offset 0x00, making its address equal to 0x40021000. 0x0000XX83 is the value of the RCC_CR register at boot.
There are another set of registers which instructions can access directly. These are the processor core registers. Because they are not accessed through the bus they do not have an address. Most of the processor core registers have 32-bits and that is why the STM32 is called a 32-bit microcontroller.
(*in a Harvard architecture part like the Cortex-M3 used in STM32F1 there are actually several buses sharing an address space but as a beginner I would suggest you can overlook that.)
In terms of transistors, each bit in a register is usually made of more than 1 transistor. Often 6 transistors are wired together to make a flip-flop which represents a single bit.

Related

why is the Program Address Register in 8051 connected to a 8-bit bus?

In this Diagram found in Wikipedia, both ROM and Program Address Register are connected to a 8-bit bus, but I thought in 8051, Internal Rom uses 16-bit adrress.
So why is the Program Address Register connected to a 8-bit bus?
Since we are not the ones who designed this architecture, we can only guess or think of reasons. If you actually want to know why, you need to find the ones who made the decision.
The 8051 multiplexes the lower address byte and the data on P0, and the upper byte of the address can go through P2. Because both bytes can be transferred at different times, an 8-bit bus suffices.
This design decision could be made to reduce silicon needs, in terms of transistors and wires. Silicon area was expensive that time.
There might be a history in the issue, too. The 8051 series followed the MCS48 (8021, 8022, 8048, etc) that had fewer address bits.
Think about the time this controller was designed, and the target market. External RAM or memory-mapped peripherals might only need 8 bits of address, just because it was enough, or too costly to use more.
Another reason might be over-simplification in the diagrams, that additionally may base one on the other. The program address register might use two 8-bit busses, each connected to one port driver block. And some "wise" guy simply put them together.
The Adress bus is not only connected there, the first 8 bits are common for address and data bus in port 0 of the microcontroller (That's why you see AD0 for the pins in pin diagram for port0, A - Address, D - Data. But in port 2 you find A0, only address), basically, an optimization to reduce the number of hardware connections, the remaining 8 bits i.e most significant bits of the address bus is in port 2 of the microcontroller so totally 8 + 8 = 16 bits.

Vector Table for Bootloader

Most, if not all, microcontrollers have a vector table for all the exceptions that are encountered when the program is running. I am quite confused as to whether the bootloader also has its own vector table for executing the reset handler?
I have written a bootloader that has been ported between a number of different embedded processors used within comms products (MSP430, AVR32, DSP56300). This loader had quite limited functional requirements
Hardware initialisation.
Validate the main code image using a checksum or cryptographic signature.
Transfer of control to the main application if the validation passes.
Provide a minimal command interface over a serial port to allow for firmware update.
Reentry point to allow the main application to trigger a new firmware load.
This transfer of operation between the two programmes held in non volatile memory on the same processor meant that I had to provide a re-direction of the interrupt functions between the two completely separate applications. The Interrupt table for the MSP430 is held in FLASH and so cannot be modified easily. It also holds the reset vector that must always point to the start of the bootloader code so erasing and rewriting this area runs the risk of completely bricking the unit.
The solution in this case was to have an interrupt service routine in the bootloader that redirected through a vector table located at a fixed location within the application memory space. Using this method added one indirect jump instruction to each interrupt handler resulting in a minimal extra processor load for each interrupt that is processed. The bootloader was written to not use any interrupts relying on polling the serial port status for all of the communications. If the bootloader needed to use interrupts then the vector table can be moved to RAM and initialised by the bootloader or application as required. (My processor did not have enough RAM to allow this)
There was a simple data structure at a fixed location in the main application code that contained entries for each possible interrupt/exception and the start address of the application code (you could consider this as the application code reset vector). As long as the application provided this data structure in flash and correctly populated it could be compiled and build completely separately as if it was the only application on the processor.
A bootloader is just a program there is no magic there, as with any other program if it needs a vector table the programmers create a vector table. Certainly if it needs to run from reset then it must conform to the hardware/processor rules for that. The processor nor any of the other logic has any way to know that that collection of bits, that collection of instructions is a bootloader or not. It just runs it.
I assume you are talking about the many, but not all, flavors/brands of microcontrollers that have bootloaders programmed at the factory?
Within an mcu there is a processor core with a memory bus. The many items in the chip, ram, flash, gpio, spi, timer, uart, adc, etc all live on that bus like having more than one house on a particular street. Each of these items on the processor bus have address decoders looking for their address on the bus to know when to take or provide data/information. The application flash and bootloader rom are no different, not special. As easy as it is to do in software it is as easy in hardware to have some sort of if-then-else that allows the application flash to answer the processor at the vector table addresses, that flag that drives the then or else cases can be an input pin to the part. Tie the pin high and hit the reset and the part boots from one memory, tie the pin low hit the reset and the part boots from the other. There are other solutions out there that are perhaps not driven by an input pin to the part but by the bootloader software.
Sometimes the processor core itself has a signal that the chip vendor drives however it wants, that within the processor core it does an if-then else, perhaps the then case is 0x00000000 is where it looks for the vector table, and the else case 0xFFFF0000.
At the end of the day though a bootloader is just another program, written by someone for this chip, no different than the program you write for the chip other than the fact that if it is a factory programmed rom bootloader then the programmer for that bootloader might have additional information/documentation for that part that we dont have. But being a bootloader is not magic it is just a program, a collection of instructions. our application can be a bootloader as well, with several possible different applicaitons based on what our bootloader finds, their bootloader can boot our bootloader which then chooses from several applications and runs one of them. All within one part...

j1939 custom module communication

I am in the middle of building a custom Canbus IO module based off an Atmega2560 chip. The module will have 10 high current outputs with pwm control and current feedback, 20 digital inputs, 5 analog inputs and 4 0-5v analog outputs. I've been working on figuring out the J1939 message structure I'll be using. These modules will be slave devices being controlled by a master ECU. Since more than one of these modules may be on the same network, I've added a CAN Address switch to each module so the user can select the CAN ID 1-255 of each unit. The plan was to have each module broadcast the state of all the digital inputs in a single CAN message. If I Select 0xFF00 as the PGN ID and then use the 8 bytes to represent the state in bit form for the status of the input for that particular module then how does the master know which module the message came from? Is the module address in the CANbus message?
I've been looking at the arduino CANBUS examples and it looks like you can filter based on PGN but I don't see anything to filter based on source address or destination address.
Can someone provide some clarification on how I might do this?
Yes, as doynax mentioned, the 8 least significant bits are always reserved for the source address of a node. If you will be placing this network on a vehicle's CAN bus, it is important to note that if you do not claim a source address on the vehicle bus, you may get a NAK from the main ECU whenever you try to place foreign information on the bus.
In order to prevent this issue, you may have to do an claim address procedure for each custom node on your network. This is where you send out PGN 60928 as a broadcast (destination address 0xFF) and every node on the network should respond on that PGN with their own source address (assuming all nodes comply to this specification, not all do). If a common source address is seen on the replies, then you know that it is not available.
See the following slideshow for more information starting on page 39
J1939

ble peripheral coded for exclusive central / master use

Being somewhat of a newbie I was wondering if there is a way to hard-code something on a peripheral that would only allow a single unique central/master to connect.....?
i.e. / eg
I have the ‘simple chat’ Arduino app on a RedBearLab Blend-Micro (which is for all intensive purposes the same as a Arduino Uno with a BLE shield) and I only want one single / unique phone to BE ABLE TO connect with it and therefore work with it.
My understanding is that the GAP handles security features during a BLE connection.
Therefore, is there some way to ‘code’ the peripheral device in / below one of the following includes:
spi.h ?
boards.h ?
EEPROM.h ?
RBL_nRF8001.h (or similar) ?
Other?
Didn't quite get an answer from Restricting the BLE peripheral device to connect to only one Master
OR
Am I stuck with EVERYTHING connecting but coding the peripheral in some other way in a GATT profile (I think) to ONLY do something with a predefined unique central/master (how/where to code?).
Many thanks for thoughts in advance
Being somewhat of a newbie I was wondering if there is a way to hard-code something on a peripheral that would only allow a single unique central/master to connect.....?
Theres the "Advertising Filter Policy" as specified in the Bluetooth Core V4.0 specification. Its a Byte in the Advertising Parameters as specified in Section 7.8.5 LE Set Advertising Parameters Command.
For example the value 0x02 reads Allow Scan Request from Any, Allow Connect Request from White List Only.
Then theres section 7.8.16 LE Add Device To White List Command.
That said, if your device confirms to the Bluetooth 4.0 specification, it should support these HCI commands. However there might be functions that simplify these procedures, wrapping those HCI commands for easier use. Check the Documentation of your device for such methods.
Good Luck!
I was asked to answer this question via email. It's been almost a year since I quit working on BLE. So I only answer this question based on my memories.
Basically #dominik has it right.
If the device is freshly new, it should advertise normally (without setting the whitelist only bit), then any central device could connect and bond. Once it is bonded, you should save this bonded flag and the bonded master's bd_addr to EEPROM. If the next time the master is lost, you will advertise with that white-list-only flag set. If a new central tries to connect, you could verify if its address is the same as your master.
I don't have the BLE spec at hand and I kind of forgot a lot about BLE already. Probably the spec says somewhere that if a central sees a peripheral device is broadcasting with white-list-only flag set, it wouldn't try to connect if it doesn't recognize that peripheral device. This saves both some effort.
But a master could always initiate a connection to your peripheral device regardless the white-list-only flag. So checking if the connecting central device's address is the same as your previously bonded master is the last resort.
[Update]
I used CSR1010 chips. I remembered that the BLE stack actually allows me to insert a list of bd_addr to the white-list data structure maintained by the stack. Then, with the white-list-only flag set, the lower-level stack layer will help you filter devices that are not in that white-list without your knowing.
However, you can always filter bd_addrs from your application code.

MODBUS auto address assignment

Does anyone know of a scheme whereby MODBUS addresses can be automatically set? In my situation I'll have a number of slaves power up and need some automatic way of assigning them addresses.
I know this is an old post, but I just came across this and thought I would give my answer just in case someone is attempting to do this now or in the future. If the goal is to assign a slave ID to a new slave (and you are developing the firmware for the slave devices), you can have the ID stored in a holding register that you can write a new ID to. This does require that:
You know the ID already. Maybe have all new slaves have a default ID, say ID = 1, so you know the ID beforehand.
You can only add one slave at a time and must change the ID before adding another slave to the network.
For example: Connect and power up the first slave device, which has a default ID of 1. Send a write command that will change the ID to 2 and send the master a response (using the slave ID of 1 in the response so it doesn’t timeout). Now the slave ID is 2. Next, add the next slave to the network, which it’s ID is 1. Now you have two slaves on the network with unique IDs. Just repeat as many of times that you need to.
Are you talking about SLAVE ID's? If so, that's just not going to happen... The SlaveID is vitally important for the Client to be able to address said slaves on the serial network. (RS485 serial network, presumably...).
So, there is no way to even send out a Modbus message and address it to SlaveID 1, and then somehow get that device to be SlaveID 1, because ALL of the devices would attempt to respond, in that case. Not to mention, there is NO method in Modbus to ASSIGN a Slave an ID... On the flip side of this...
Are you talking about performing some type of query to ask the slave devices which Modbus REGISTERS they have? Again, there is no Modbus way to do this, but with some code, you COULD query 40001, and if you get an error 2 back, then you know that register is not available. If you then loop through all of the registers, keeping track of which ones returned non-error, well--then you COULD do a form of "auto-configure", but... In all honesty? I would NOT recommend this, and I don't see a lot of value to even DOING this, because you not only have to know the REGISTER numbers, you have to know WHAT THE DATA IN THE REGISTER ACTUALLY MEANS!
What exactly are you trying to do anyway? Perhaps there is another way to accomplish this goal?
What you think you want: automatic Slave ID assignment in Modbus RTU.
What you actually want: constant, common Slave ID with Modbus TCP.
In a nutshell, all your Modbus Slave ID's get set to a fixed, common value and then you bridge them with a TCP stack that supports things like link-local addressing or DHCP. Then the TCP address assignment can be dynamically handled while preserving a constant SlaveID for each unit.
There are three broad options here depending on what hardware you already have:
There are commercial off-the-shelf devices (such as this) that can emulate TCP over RTU. I've not delved too deep into what they support and how well they work.
You could also add a whole ton of TCP to RTU bridges which will have built-in management for the TCP/IP layer and then use real Ethernet cabling. For a lot of devices, this could get expensive fast, but with Ethernet you have all sorts of bonus features like basically unlimited distance and improved CRCs. If you're looking to do this on the cheap, grab a dual-port Linux SBC (such as this or this) and throw mbusd (from here) on it.
If you have access to or are developing the firmware yourself, you could adapt something like uIP (simpler) or lwIP (faster) to communicate over RS-485 (UART). This would certainly be the cheapest option. Note that you should also have the ability to detect collisions on RS-485 to implement an IP stack correctly -- this involves echoing the receiver at all times and checking that the data-in and data-out match.

Resources