How to modify code in micro controller during mass production? - Page 1
Forum section: electronics / projects

author: Sai teja
author_rank: Regular Contributor
timestamp: April 18, 2019, 01:33:35 pm
content: Hello,In our application, we need to program a micro controller and a variable need to be changed for before uploading code in every micro controller.Is there any way to automate the process for uploading code in this situation?

author: DDunfield
author_rank: Regular Contributor
timestamp: April 18, 2019, 02:09:21 pm
content: Which microcontroller and how is it being programmed?Is the variable stored in the main code image? In a separate NVM area?Many mass programming environments have the ability to program an incrementing value on a per-unit basis.I've done a number of products which required special unit-specific values to be assigned and programmed into each unit (Serial#, mac-addresses etc.), and what I usually do is perform this assignment, program the firmware and any other permanent memories required in the test stage. The manufacturing test system takes "new" devices fresh from the production line, installs firmware, serial#s etc. then tests it to determine that it performing to specifications before releasing it as finished product.Dave

author: abraxa
author_rank: Frequent Contributor
timestamp: April 18, 2019, 02:13:14 pm
content: Is "we" a company? If so, then I'm kinda unhappy that companies can come here and ask for support.

author: DDunfield
author_rank: Regular Contributor
timestamp: April 18, 2019, 07:16:45 pm
content: Quote from: abraxa on April 18, 2019, 02:13:14 pmI dunno, from the "About Us" link at the top of every page:"This is a free and open forum, everyone is welcome, even commercial companies and people promoting their own products."I could see it being annoying if an engineer working on a company project was asking for significant "free" work/design, but this seems like a fairly simple question falling into the "how do I get started" category. Is this frowned upon if the asker is in a company? How about individuals contracting to a company?Do forum participants get unhappy if other participants share tips and tricks they gained through experience working at companies? Just wondering where the lines are?Dave (who sometimes does work for companies).

author: mariush
author_rank: Super Contributor
timestamp: April 18, 2019, 07:28:47 pm
content: You could start for example by compiling the code with a constant with an obvious value, like 0xAB , 0xBC, 0xCD, 0xDE ... then compile again with slightly different values ... all being the same, only those 4 bytes should be changed in the compiled code.Now you can make your own programmer ... make a gadget in which you upload the compiled code, and then add a button ... push the button and the programmer increments the value before sending the data to the microcontroller.Alternatively, you could have a predefined value that would normally be not expected in the eeprom or the flash area, for example 0xFFFFFFFF and if you start the micro with this value, the micro uses ADC to read a voltage or something from one or two pins. You could have a gadget with a bunch of resistors or a DAC ... insert into your pcb, start it up, wait 1s or so for the micro to update its internal value and then you can move on

author: ejeffrey
author_rank: Super Contributor
timestamp: April 18, 2019, 07:40:26 pm
content: Quote from: mariush on April 18, 2019, 07:28:47 pmThis is a pretty crude way to do this and has a number of failure modes. Instead, use objdump on the created elf binary to examine the symbol table and find out at what address your object resides.An even better approach is to do this is to reserve an area for the manufacturing data using the linker script, for instance at the top or bottom of flash memory. That way, you can force the address to be the same from build to build. If you do it properly reflashing the microcontroller with new program code won't change the reserved area.

author: Benta
author_rank: Super Contributor
timestamp: April 18, 2019, 07:41:28 pm
content: The highest level I'd do this is at linker level by including a variable file to be linked into the rest of the program.But this would still be tedious.The simplest solution is to write a small program to manipulate the hex file for the programmer: Modify the bytes that need modifying, calculate new checksums and do the programming. Downside is, that this can not be tracked in an easy way afterwards.Both approaches need you to reserve the variable storage at a fixed address.Edit: ejeffrey, it seems we both are in accordance at the same time

author: sokoloff
author_rank: Super Contributor
timestamp: April 18, 2019, 07:53:15 pm
content: An alternate approach is to use EEPROM (available on many microcontrollers), program the eeprom with the value(s) you want and read them at boot. I use this for a small volume product and have a programming method that burns a utility program that boots, connects over serial to get the EEPROM values to write, writes them, then the programmer burns the final program code.

author: DDunfield
author_rank: Regular Contributor
timestamp: April 18, 2019, 07:55:29 pm
content: A simpler way than having to search each compiled version for special values (or even just looking at the symbol map), is to put the special variable at a known location.An obvious place is at the "other end" of the flash/ROM than where the code resides, however this will make a lot of tools think your code is entirely the size of the device and therefore program the entire device, even if a significant portion of it is blank - depending on your programmer, this may mean slightly longer programming time, but it can be a separate (even write protected) area that is never touched again even during software updates (assuming you want it to be permanent).Another convenient place, especially for small unique permanent items (like serial numbers, mac addresses) is to reserve some space right after the vector table (or whatever other startup mechanism your particular CPU requires to be at a known location) in the startup code. That way it sits at a known address, and nothing special has to be done with the compiler, linker or other tools, the only thing you have to do is have your programmer insert the unique values at the fixed address(s) as it programs the image. As this is often in a boot loader of some sort, it also would not change with software updates (usually desirable). You do have to insure that any method you have to update your bootloader will preserve the unique data area.Dave

author: Benta
author_rank: Super Contributor
timestamp: April 18, 2019, 07:57:27 pm
content: Quote from: sokoloff on April 18, 2019, 07:53:15 pmor even simpler: program the MCU with the standard code and load the variables into EEPROM afterwards...

author: sokoloff
author_rank: Super Contributor
timestamp: April 18, 2019, 08:07:02 pm
content: I think I have 52 bytes of program code space available in my production code, so nowhere near enough for the serial serializing code.

author: ajb
author_rank: Super Contributor
timestamp: April 18, 2019, 08:24:40 pm
content: Another option is to instruct the MCU itself write the data, which works very well if you already have a test bench that talks to the MCU via UART or whatever for production testing. This could be the last page of flash if you have the space to spare, otherwise you could have the MCU rewrite an existing page, which would be a little more dicey, and you'd want a verification step for sure, but wouldn't consume any extra program space. Some MCUs also have EEPROM or specific configuration pages in flash that could also work.Really it's impossible to give a definitive answer given how unconstrained the question is. The best solution depends on the amount of data that must be stored, the MCU, the type of production infrastructure already in place, etc.

author: rstofer
author_rank: Super Contributor
timestamp: April 19, 2019, 12:14:49 am
content: In the linker memory map, it is common to block out high address areas of flash. You could load your uC with code to get the data from somewhere and put it in the dedicated block and then program your device with production code. Assuming you have broken out the UART. Your linker script should provide a variable containing the address and perhaps your startup code could have a short bit of code that returned the address to your main program. I would be hesitant to hardwire the address into the main code. Things move!Or, you can have a Makefile (or something) that generates the table information and then just use your regular programmer to put it where it belongs and then on a separate pass, write the production code. Or have the Makefile munge the main code with the table data (generated by the Makefile) before programming.Lots of ways to skin this cat.