Modbus Bootloader?

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I searched around cause I know I've seen this discussion before. Now I have an application where I could use the help.

How do you allocate the RAM used by the boot loader in the application? Can the bootloader call a function in the application or can the application call a function in the bootloader.

I have written a bootloader before where whole control is in one place and then transfered to the other. But as for linking in "toolbox" type functions already present in protected flash space I'm not sure how to proceed.

I'm planning to use the file transfer capabilities of modbus to update the application flash.

Is it possible to use the unused interrupt vectors as a jump table?

official AVR Consultant
www.veruslogic.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Usually the bootloader runs first at startup and decides whether it needs to do something or whether it should run the application- it might use a magic value stored in a location in eeprom for this. Therefore the two applications are mutually exclusive. Say our application is happily running and we get a request to load new code - our app must stop and hand over to the bootloader. We might write a magic number to a eeprom location and force a watchdog reboot. Thus our bootloader is now in control. Once the bootloader is finished, we write another magic value to an eeprom location to tell it to run the application and then forces a watchdog reset. New application runs.

As such the application can't call the bootloader directly - the bootloader would most likely overwrite the current application and then what would you return to?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm assuming you want to be able to call existing functionality in the bootloader code rather than link it again into the application.

I've been toying with doing something similar to create full functionality GDB support so that applications don't have to link in a bunch of GDB stub/monitor code but instead call code that's up in the bootloader. Also, in my case it allows the GDB stub code in the bootloader to modify the application FLASH space for single stepping.

I'm looking at using unused bootloader interrupt vectors just as you mentioned.

It should be possible to write a kind of bootloader trap type function that an application can use to call directly into functions in side the bootloader.

The bootloader code won't care, and won't even know the difference.

There are several ways to do the lookup and jump.
Some of it will depend on how the fuses are set
i.e. can you read the FLASH from application
to read the bootloader vector? If not, you will have to actually call to to the vector location in the bootloader and let the vector jump to the bootloader function.

I don't think its that difficult but if you have more than a few functions you may have to share multiple functions on the same bootloader interrupt vector.
Then it will start to get a bit messy as you'll have to pass in a function code to the vector function that
then calls the proper bootloader function and that may involve using varargs. But still doable.

I haven't thought it all through yet but it doesn't seem that bad.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I am trying to install boot loader on ATmega88PA, as I can download code (.hex file) over I2C bus (because I have communication with main processor over I2C bus).

Do you know where can I find source code for the boot loader which download code over I2C bus?

P.S. I have one code, but for downloading .hex file over USART, but I don't have enough time to modulate that code to be compatible with I2C.

Thank you very much,
Stevan Marinkovic

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I too am using the ATMega88PA. There are only two functions that I call - ModBusInit() and ModBusHandleCom(). The biggest problem is that there is so much RAM allocated for modbus receive buffer and holding registers. I don't know how to tell my compiler (codevision) that a particular block of RAM is reserved for something else and to place all new variables outside that block.

After updating the application flash, it will be running from the reset vector and not returning to something that moved.

Maybe the better way would be to put the main loop in the bootloader and then jump to the application's main loop from there. Then there is only one hook needed into the non-blocking application main loop. The modbus module uses polled interrupts so the interrupt vectors are not required - just the reset vector.

I guess if I can't share all the modbus protocol handling stuff, then I'll have to duplicate it. There are 11 devices on the bus, so the protocol will have to be adhered to.

I guess I could use the @ location in a header file that will absolutely locate the holding registers so that the application can share them.

official AVR Consultant
www.veruslogic.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow--I started quoting this and that and the other and finally realized I'd be quoting the whole thing. I've done quite a bit of Modbus RTU, and the "symptoms" that you described just don't seem to fit.

-- Are you doing Modbus master or slave?

-- Why would 11 (or 4 or 17 or whatever) devices on the Modbus have any bearing on memory usage?

-- Is this serial port (RTU or ASCII), or a new-fangled "TCP" or other?

-- What "module" are you talking about?

A full-blown ModbusRTU slave with full functionality takes about 1/2 the flash space of a Mega88. Most of the time the functionality can be limited, to about half that.

A master can be much smaller, as it only needs what it needs. Sometimes only a couple of functions.

A full frame is technically 256+a few bytes. The Mega88 with 1K is nice in that respect 'cause that doesn't cripple you. The "registers" are essentially "free"--they are pieces of info that your app needs to store anyway. (Well, some might be widened to 16 bits, but basically no big deal.)

As I recall, I only have a few calls at the main() level also. But there are a lot of "call back" functions, and >>that<< is how the "free" register storage occurs. The call-back functions know that 1000-1999 are in EEPROM, 2000-2222 are in SRAM, a write to 9999 causes an AVR reset, etc. etc.

How I'd do all that polled? I have no idea. One timer is constantly counting idle time (but there are ways around that except in the strictest of systems) and kicks the Modbus "state" based on time. I have interrupt-driven TX and RX. As the protocol is inherently half-duplex, I share the 256+ byte buffer between RX and TX.

I've got an app with twin Modbus RTU slaves that can run full-tilt-boogie at 115kbps all day long without a hiccup or any noticeable impact on the (7.37MHz) AVR's app operation. One channel is to the display module that is a master, the other is to a monitoring/controlling PC if that connection is made.

I'm either missing something, or just can't relate.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Slave modbus RTU. I'm only running at 19200. I poll the flags because the very important timer interrupt can not afford any latency. I use timer 2 with the two output compare modules for the 1.5 and 3.5 timers. I don't have a full blown modbus implementation. I don't have all the debug stuff implimented.

The reason for the 11 device comment was that I have to adhere to modbus protocol for sending data in the system. I can't change to some binary or hex file download for the loader.

This really isn't a modbus question that I have. Nor is it a boot loader question. This is more a question of how to tell your compiler that something else is going to use a block of RAM and to start putting variables after your reserved area.

official AVR Consultant
www.veruslogic.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found the solution in the help file. The answer is in the Advanced tab of the C Compiler Project configuration.

This lets you select the location and limits where the compiler uses RAM. It also lets you suppress interrupt vectors, or generate your own.

Now, I have to upgrade my version to get this feature.

official AVR Consultant
www.veruslogic.com