On 08/12/11 08:53, Bernard Fouché wrote: > Hi. > > I'd like to be get suggestions about suitable macro names for bit band > operations on the Cortex-M3. > > Since this is a MCU option, they should be defined per MCU. > > Actually working on the LPC17XX, I have defined: > > //============================================================================= > // LPC17XX supports CORTEX-M3 bit banding option > #define CYGHWR_HAL_LPC17XX_BITBAND_SRAM_PHY 0x20000000 // > to 0x200FFFFF (1 meg) > #define CYGHWR_HAL_LPC17XX_BITBAND_SRAM_BB 0x22000000 > // Convert SRAM address > #define CYGHWR_HAL_LPC17XX_BITBAND_SRAM(address,bit)\ > ((CYGHWR_HAL_LPC17XX_BITBAND_SRAM_BB +\ > (address-CYGHWR_HAL_LPC17XX_BITBAND_SRAM_PHY)*32 +\ > (bit*4))) > > #define CYGHWR_HAL_LPC17XX_BITBAND_PERI_PHY 0x40000000 // > to 0x400FFFFF > #define CYGHWR_HAL_LPC17XX_BITBAND_PERI_BB 0x42000000 > // Convert PERIPHERAL address > #define CYGHWR_HAL_LPC17XX_BITBAND_PERI(address,bit)\ > ((CYGHWR_HAL_LPC17XX_BITBAND_PERI_BB +\ > (address-CYGHWR_HAL_LPC17XX_BITBAND_PERI_PHY)*32 +\ > (bit*4))) > > Use case: > > // add channel to pool > *(volatile cyg_uint32 > *)CYGHWR_HAL_LPC17XX_BITBAND_PERI(ADC_CR,1<<chan->channel)=1; > > Another possibility would be to provide higher level macros for bit > set/test/read-modify-write operations and have these macros to use bit > band if the targets support them. However bit band operations will > probably be used only in driver code specific to a MCU familly and the > driver designer may prefer to explicitly states when a bit band > operation is used. > > Since I'll provide some drivers in the next weeks, it would be nice if > these drivers already use macro names acceptable for eCos maintainers.
[ I intended this to be a short response, but it seems to have turned into an essay. I apologise for the length, I didn't have time to make it shorter. ] I looked at the bit-banding support in the Cortex-M architecture when I originally started the architecture port. I also considered adding some defines and macros to make use of it. In the end I decided not to for several reasons: It is at odds with the common way of doing device access in eCos by using the HAL_[READ|WRITE]_UINT* macros. These make all accesses to device registers very explicit, and the order of access clear. Allowing register accesses to look like assignments means that they can get lost or overlooked. The macros also mean that the accesses are correctly sized and the necessary attributes, such as volatile, are applied. Most eCos drivers use these macros, and over time a number of idioms have been established which make such drivers easier to read and modify. We do have a few drivers that use the deprecated approach of mapping a struct over the registers, and these are harder to read and work on. The example you show above looks to me long and rather messy. So your suggestion of wrapping these accesses in macros would have to be adopted. This approach answers some of the issues raised above. The issue of portability is important. You suggest replacing the bit banding macros on platforms that don't have it with work-alike macros. This means that these macros would need to do individual read-modify-write cycles on such targets, which are much more expensive. One of the common idioms for updating a register is to read it, set and clear a number of bits in the local copy, maybe over a substantial piece of code, and write it back at the end. It would be much less efficient to do this bit-by-bit. And there is the possibility of putting the device into an inconsistent state by changing individual bits that the final write-back commit does not. Another idiom is used to test status registers, These are usually read into a local copy and then single or groups of bits can be tested. There are usually several such tests sequentially, and having a copy of the status register in a CPU register makes this fast and efficient. In my experience, the number of times we need to explicitly set or clear a single bit in a register is relatively rare. Testing single bits is slightly more frequent, but I don't see bit banding saving very much there; runtime calculation of the banding address might even make it more expensive. Bit banding also doesn't really work for multi-bit fields, which have to be updated in the traditional manner. Our current register definitions tend to be in terms of bit masks, while the bit banding macros would need bit offsets. The masks are still needed for traditional register access, and offset versions would have to be added for the banding macros. This raises problems of divergence in the definitions, and the prospect of using the wrong version of the definition. We could have defined bit set/test macros long ago but decided not to for many of the above reasons. In fact, I seem to recall making a conscious decision early in eCos' life to not define such macros to actively discourage their use. The same thinking led me to not defining such macros for bit banding. You mention that you are writing drivers for the LPC1XXX family. These are a good example to use. Most of the devices on these parts are shared with the LPC2XXX family. We should be sharing drivers between these families. In the public repository, the lpc1766stk target already uses the LPC2XXX wallclock, serial and ethernet drivers; in eCosPro we additionally share the SPI, I2C, flash and watchdog drivers. Your example seems to be for an ADC driver, however, there is already an LPC2XXX ADC driver that should probably be adapted to work for the LPC1XXX. Adding bit banding support to these drivers would render the LPC2XXX versions less efficient. I also expect that if a new LPC1XXX driver were written using bit banding macros, then it would get rewritten to use the traditional method once it was ported to the LPC2XXX family. I can imagine that there are situations where bit banding is useful. For example high speed signalling on GPIO lines, or doing certain classes of encryption or compression in on-chip RAM; but those would all need very application specific code. I find it difficult to see that it will be any significant advantage to handling the control and status registers of conventional devices. In general, the small advantages that bit banding gives doesn't seem worth the loss of portability, readability and simplicity. Of course you can do what you want in writing device drivers. You can even propose a set of bit banding macros to go into the HAL headers for specialized use. However, I remain unconvinced that they should be used for writing device drivers. -- Nick Garnett eCos Kernel Architect eCosCentric Limited http://www.eCosCentric.com The eCos experts Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No: 4422071 -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss