35

Most micro controllers these days have part or manufacturer specific methods to protect the embedded firmware code. This is generally done by locking out the circuits that normally allow the code memory to be read out. (You'll have to look for part specific details in the data sheet or at the manufacturers web site in applicable application notes). Once ...


31

You can use global variables successfully, as long as you keep in mind @Phil's guidelines. However, here are some nice ways to avoid their issues without making the compiled code less compact. Use local static variables for persistent state that you only want to access inside one function. #include <stdint.h> void skipper() { static uint8_t ...


31

What is the motivation in using hardware description languages (HDL) such as Verilog and VHDL over programming languages like C or some Assembly? C and assembly are good languages for telling a CPU what to do. They describe actions to be done sequentially by a single state machine. HDLs are good languages for describing or defining an arbitrary collection ...


27

As often with such definitions, we agree in most cases, but there is no really firm boundary between what is firmware and what isn't. Firmware is stored permanently (except for some knowledgeable person who can change it ...) not intended to be changed (except ...) operates on the processor without the help of other software (except ... you get it?) As to ...


24

The reasons you would not want to use global variables in an 8-bit system are the same you would not want to use them in any other system: they make reasoning about the program's behavior difficult. Only bad programmers get hung up on rules like "don't use global variables". Good programmers understand the reason behind the rules, then treat the rules more ...


24

It is well-known bad practice to have a "super header" file like "globals.h" or "includes.h" etc, because in addition to globals being bad in the first place, this also creates a tight coupling dependency between every single, unrelated file in your project. Lets say you have a PWM driver and a RS-232 debug print module. You want to grab the RS-232 debug ...


22

I program small micro-controllers in C++, which achieves exactly what you want. What you call a module is a C++ class, it can contain data (either externally accessible or not) and functions (likewise). The constructor (a dedicated function) initilializes it. The constructor can take run-time parameters or (my favourite) compile-time (template) parameters. ...


22

The code you have posted is quite readable. C programmers are assumed to understand the meaning of commonly used operators and expressions. The bitwise operators in particular, in the context of embedded systems programming. They are however not required to understand the meaning of mysterious macros - I'll get back to that later. First of all, there are ...


20

Generally speaking the factory reset function you mention will restore any saved variable data information back to default values. It is not true that all embedded devices have this capability. Some do but not all. If you want your device to support a return to factory default firmware itself then your design has to incorporate a memory into the circuit to ...


16

I would not write every event to EEPROM. Most of the time you will have power, so keep the live count in RAM. The amount of energy it takes to save the live value from RAM to EEPROM is pretty minimal. Use a capacitor to store enough energy to run the micro long enough after power fail is detected to copy the live data into EEPROM, then shut down cleanly. ...


16

Yes, it's a good idea - the only downside is a bit of extra code size, and you have to decide what to do with the trap (emit a message on the serial port? turn on a "FAILED" light? Silently reboot? etc)


14

Firmware is program code that is stored in non-volatile memory, such as flash memory. The term is most often used in connection with embedded systems. It can be on the same chip as the processor, or on a separate device.


14

You may be asking about a software-only solution but if you are able to add a cheap IC to your board, you can use a 'Silicon Serial Number' chip. These are tiny ROM chips that each device contains a unique binary number. Examples are Maxim's DS2401 (1-wire bus) and DS28CM00 (I2C) which have a 48-bit unique number. The number is unique amongst the all the ...


14

Most production programmers are capable of inserting a unique serial number into the programmed memory, its a process normally called serialization. This is a grab of the Serialization screen from an old Dataman programmer.


14

Off the top of my head, two easy solutions come to mind. Have n lines attached to the GPIO of your microcontroller. Tie these high or low depending on your board version. This would give you \$2^n\$ board configuration options. This would use n pins on your microcontroller. Static current draw would be negligible. Have an input to the microcontroller's ADC ...


14

It would work to define a struct that you instantiate as the single global variable. Accesses on the form 'the_global.the_var' won't add run-time overhead and can clarify that it's indeed a global. As https://stackoverflow.com/questions/2868651/including-c-header-file-with-lots-of-global-variables mentions, it saves you from separate declarations and ...


13

There is no paradigm shift; in both cases a CPU is executing the software/firmware. Firmware and software are the same thing; the only distinction is in how it's stored. Software is typically stored on a mass-storage device (e.g., disk drive) and loaded into volatile memory (e.g., DRAM) before being executed. It's easy to change software, by simply ...


13

I think Michael's answer is enough for this question but I add these both link: Hacking the PIC 18F1320 and Everything they make, We can break! These both were very interesting to me.


13

I have a BS in Electrical Engineering and an MS in Computer Science. I have been doing embedded systems as a consultant/contractor for over 35 years,working for both small companies you've never heard of and large ones like Sony, DirecTv and Apple. For the smaller companies (typical number of employees: 25, number of other engineers: 0-4), I get involved ...


13

My informal rule is: If an interrupt is enabled, then you should have code that handles it. If you don't write code for an interrupt, disable it. If you can't disable it, write code for it. Even without that rule, though, the data sheet explicitly answers your question: If the user does not intend to take corrective action in the event of a trap ...


13

If you can't get rid of the globals, I'd say you should only pack them together in a struct if they are actually related. If not, then I'd keep them separate or in smaller structs. Also, I wouldn't like a globals.h file either. Keep them at the top of the source file where they most belong. This way when navigating through the code, you likely stay in the ...


11

For the first part of your question, about the motivations of using one or the other: there is a fundamental difference between C and HDLs (VHDL/Verilog). C is a software programming language (as assembly is), VHDL/Verilog are hardware description languages. They are not meant for the same purpose. C is translated into assembly code (in its binary form, i.e....


11

If you take the most common example of factory defaults, it's your PC's UEFI (BIOS). It is made with a flash chip and a volatile battery backup SRAM memory chip. The flash chip contains the program, and the SRAM contains the settings. On factory reset, the contents of the volatile sram are erased. On the next boot, it detects that the checksum of the ...


10

Here is a quick comparison of FLASH, EEPROM and SRAM on the AtMega328, the microcontroller in many of the current Arduino boards (excluding Due, Leonardo, older Arduinos and some other compatible boards). FLASH: 10,000 write/erase cycles. Access is fast, but slower than SRAM. Code accesses via PROGMEM. EEPROM: 100,000 write/erase cycles. Access is ...


10

Hassan's answer is not quite accurate. If you really want to read both inputs at the same time, you can do that so long as they both reside on the same port. uint8_t sample = PORTD.IN; uint8_t bit3 = (sample >> 3) & 1; uint8_t bit7 = (sample >> 7) & 1; Now you can be asured that bit3 and bit7 are from the same time sample. If you ...


10

Factory reset is whatever you want it to be. It depends on the application and device type. I usually do two things: Ensure that there is always a reliable way to enter the bootloader, so that even a partial/wrong firmware update can't brick the device. Have a way to reset the firmware settings in case the user changes something, a particular setting ...


10

Actually, it's not better, the only advantage is that you 'know' which are global. So you have all globals in one place, but still they are scattered around. C For each global: Find the initial file where it is created or used. Make it static in that file In case the global is used in many places, use it externally from other files (using the extern ...


10

If 256 buttons will be enough, you can use two MCP23017 (16 port I2C GPIO): the first one as 16 outputs, the second one as 16 inputs, of course with 16x16 matrix of buttons. If not enough, you can use three of them, or "borrow" additional three lines form MCU (so, it will make 16x19 = 304 buttons possible). As @jonk mentioned, if you want to detect multiple ...


9

Even a "regular" CPU with an OS must execute firmware...it's usually called the BIOS in a generic PC. The firmware for any CPU is just the software that is always available when the power is turned on, whether the CPU is connected to any peripheral devices (disk drives, USB, etc.) or not. If you have a full-blown OS then the firmware just figures out what ...


9

I'm not aware of any pre-made solutions but I'll describe how I went around it in one project. It's not totally 'unbrickable' but I'm not aware of it failing over thousands of upgrades. For this application a very low failure rate would still be cheaper than having to gain access to the units. The main application has three additional packet types added to ...


Only top voted, non community-wiki answers of a minimum length are eligible