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 ...


33

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 ...


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 ...


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

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 ...


21

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. ...


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

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 ...


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

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

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

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

I think both options are sort of correct, just looking at the microprocessor at different levels of abstraction. What you're referring to as your immutable binary would be the hardware itself, which is fairly limited in what it can do. Fetch instruction address 0x0000, decode instruction, fetch supplied address/register, execute, increment instruction ...


9

I have used a shift register with pins tied high and low to encode board revision before now, if you're already using SPI for something on your board it's trivial to read it. If you need to be able to change ID at run time then using jumpers rather than tying the inputs with traces would be a good idea.


8

Make sure that the Read Out Protection (ROP) byte is set to off. Open STVP, go to the OPTION BYTE tab, set ROP to off and write out (Ctrl + P). Then, go to the PROGRAM MEMORY tab again and you should be able to write your hex file.


8

The solution to the problem is relatively simple. You accumulate the pulse count to a regular RAM location. Then once each 10 minutes you the copy the current value of the RAM based counter to EEPROM. Using this strategy an EEPROM with a one million cycle count endurance will last about 19 years. For most products this is a good comparison to the expected ...


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