what types of codes are written in CMSIS files and peripheral drivers file. How can I distinguish them? any example would be more helpful. Thank you.
"CMSIS" is the Cortex Microcontroller Software Interface Standard. It's an ARM standard, so the code should be more or less portable between Cortex implementations.
Peripheral libraries generally are more vendor-specific, since there's no standard for how two different vendors will implement e.g. a timer or a UART block.
At least, that's my basic understanding from working (mostly) with ARMs in the STM32 family. However, I notice on that CMSIS page that the scope for CMSIS is actually larger:
CMSIS-Driver: defines generic peripheral driver interfaces for middleware making it reusable across supported devices. The API is RTOS independent and connects microcontroller peripherals with middleware that implements for example communication stacks, file systems, or graphic user interfaces.
That sounds like it'd do things that I associate with vendor-specific code, but perhaps not all vendors actually use CMSIS-Driver yet.
UPDATE: On the STM32:s I've worked with, GPIO is managed using only ST's peripheral library.
It's pretty easy, really:
Use RCC_AHB1PeriphClockCmd() to enable the GPIO peripheral's clock. There are many clocks so make sure you do it right. I think all the GPIO is on AHB1.
Initialize a variable of type GPIO_InitTypeDef by calling GPIO_StructInit() on it to get the defaults.
Set the settings you really want in your GPIO_InitTypeDef, overriding the defaults as needed.
Call GPIO_Init() on the proper port, also passing it the GPIO_InitTypeDef with your actual settings. This will poke registers in the peripheral.
Use calls like GPIO_SetBits(), GPIO_ReadInputDataBit() et cetera to actually use the GPIO pin.
CMSIS code are written for the ARM controller for different vendor like NXP (LPC series etc.) STM (STM32f4, stm32F1 ) basically the controller which has ARM architecture. this is portable software. this coding language is C/C++ most of the time but in some file assembly language is used. generally the assembly language are used in startup files.
In the peripheral driver the code are written in c/c++ language. peripheral driver are used to communications purposes.
I'm currently working on the LPC18xx controller, using the CMSIS driver, the CMSIS driver has code for all the peripherals, you can use the driver directly to implement your application
for example : if you want to read the data from the sensor connected via I2C.
you can directly used the I2C Cmsis driver to implement application. only thing you need to know this the hardware address to the sensor.
similarly you can use SPI driver, CMSIS also provide RTOS driver.
Related
I was wandering, why there are no implementations of the devices written in CMSIS-Driver?
I mean that I have few peripherals: LCD, temperature and pressure sensor, current meter etc. - all of them very popular used in arduino and learning sets.
Each of these devices uses some protocol to communicate with the uC. some are for i2C, some communicate by SPI, some by UART. I was wondering if there are drivers that handle those devices, and as a backend use CMSIS-Driver API.
I think that it is a decent api, and after all standard develop by ARM, so why I can not find any drivers using it?
For example when I was looking for s18b20 (temperature sensor for 1-wire), I was easily able to find driver for this device written in RUST language, but I was not able to find any implementation for C that would use CMSIS. (in this case compare to rust is quite solid, because Rust has nice embedded API, and you can easily use the driver on multiple targets, just like CMSIS-Driver is spouse to work)
I was able to find some projects using this peripheral, but they all operated on HAL that is different for every uC, so the implementation is not portable ( unlike RUST, and potentially CMSIS-Driver)
So my main questions are:
Why there are so little implementations based on CMSIS-Driver? Maybe there is some hidden implementation repository that I do not know about?
Am I missing something? Is the CMSIS-Driver not designed for the casual developers? Who is it designed for then ?
CMSIS is not concerned with external devices, it deals primarily with interface drivers for interfaces on the microcontroller die. So if you have an SPI device, you might use the CMSIS. SPI driver for that part, but it is then your responsibility as a developer to write the higher-level driver for the external device.
Higher-level software platforms such as ARM's embed, or ST's CubeMX use CMSIS interface drivers, and include drivers for common higher level devices. They tend to be for more complex devices related to networking, filesystems and displays. I would not expect much support for such trivially simple devices such as a temperature sensor.
I need to develop device libraries like uBlox, IMUs, BLE, ecc.. from scratch (almost). Is there any doc or tutorial that can help me?
Question is, how to write a device library using C/C++ (Arduino style if you want) given a datasheet and a platform like STM32 or other ARMs?
Thanks so much
I've tried to read device libraries from Arduino library and various Github, but I would like to have a guide/template to follow (general rules) to write proper device libraries from a given datasheet.
I'm not asking a full definitive guide, just where to start, docs, methods approach.
I've found this one below, but is very basic and quite lite for my targets.
http://blog.atollic.com/device-driver-development-the-ultimate-guide-for-embedded-system-developers
I don't think that you can actually write libraries for STM32 in Arduino style. Most Arduino libraries you can find in the wild promote ease of usage rather than performance. For example, a simple library designed for a specific sensor works well if reading the sensor and reporting the results via serial port is the only thing that firmware must do. When you work on more complex projects where uC has lots to do and satisfy some real time constraints, the general Arduino approach doesn't solve your problems.
The problem with STM32 library development is the complex connection between peripherals, DMA and interrupts. I code them in register level without using the Cube framework and I often find myself digging the reference manual for tables that shows the connections between DMA channels or things like timer master-slave relations. Some peripherals (timers mostly) work similar but each one of them has small differences. It makes development of a hardware library that fits all scenarios practically impossible.
The tasks you need to accomplish are also more complex in STM32 projects. For example, in one of my projects, I fool SPI with a dummy/fake DMA transfer triggered by a timer, so that it can generate periodic 8-pulse trains from its clock pin (data pins are unused). No library can provide you this kind of flexibility.
Still, I believe not all is lost. I think it may be possible to build an hardware abstraction layer (HAL, but not The HAL by ST). So, it's possible to create useful libraries if you can abstract them from the hardware. A USB library can be a good example for this approach, as the STM32 devices have ~3 different USB peripheral hardware variations and it makes sense to write a separate HAL for each one of them. The upper application layer however can be the same.
Maybe that was the reason why ST created Cube framework. But as you know, Cube relies on external code generation tools which are aware of the hardware of each device. So, some of the work can be avoided in runtime. You can't achieve the same result when you write your own libraries unless you also design a similar external code generation tool. And also, the code Cube generates is bloated in most cases. You trade development time for runtime performance and code space.
I assume you will be using a cross toolchain on some platform like Linux, and that the cross toolchain is compatible with some method to load object code on the target CPU. I also assume that you already have a working STM32 board that is documented well enough to figure out how the sensors will connect to the board or to the CPU.
First, you should define what your library is supposed to provide. This part is usually surprisingly difficult. It’s a bit hard to know what it can provide, without knowing a bit about what the hardware sensors are capable of providing. Some iteration on the requirements is expected.
You will need to have access to the documentation for the sensors, usually in the form of the manufacturer’s data sheets. Using the datasheet, and knowing how the device is connected to the target CPU/board, you will need to access the STM32 peripherals that comprise the interface to the sensors. Back to the datasheets, this time for the STM32, to see how to access its peripheral interfaces. That might be simple GPIO bits and bytes, or might be how to use built-in peripherals such as SPI or I2C.
The datasheets for the sensors will detail a bunch of registers, describing the meaning of each, including the meanings of each bit, or group of bits, in certain registers. You will write code in C that accesses the STM32 peripherals, and those peripherals will access the sensors across the electrical interface that is part of the STM32 board.
The workflow usually starts out by writing to a register or three to see if there is some identifiable effect. For example, if you are exercising a digital IO port, you might wire up an LED to see if you can turn it on or off, or a switch to see if you can correctly read its state. This establishes that your code can poke or peek at IO using register level access. There may be existing helper functions to do this work as part of the cross toolchain. Or you might have to develop your own, using pointer indirection to access memory mapped IO. Or there might be specially instructions needed that can only be accessed from inline assembler code. This answer is generic as I don’t know the specifics of the STM32 processor or its typical ecosystem.
Then you move on to more complex operations that might involve sequences of operations, like cycling a bit or two to effect some communication with the device. Or it might be as simple as finding the proper sequence of registers to access for operation of a SPI interface. Often, you will find small chunks of code are complete enough to be re-used by your driver; like how to read or write an individual byte. You can then make that a reusable function to simplify the rest of the work, like accessing certain registers in sequence and printing the contents of register that you read to see if they make sense. Ultimately, you will have two important pieces of information: and understanding of the low-level register accesses needed to create a formal driver, and an understanding of what components and capabilities make up the hardware (ie, you know how the device(s) work).
Now, throw away most of what you’ve done, and develop a formal spec. Use what you now know to include everything that can be useful. Use what you now know to develop a spec that includes an appropriate interface API that your application code can use. Rewrite the driver, armed with the knowledge of how are the pieces work, and taking advantage of the blank canvas afforded you by the fresh rewrite of the spec. Only reuse code that you are completely confident is optimal and appropriate to the format dictated by the spec. Write test code for all of the modules, and use the test code to actually test that the code works and that it conforms to the spec. Re-use the test code every time you modify anything it tests.
I wish to read the EUI64 address from an AT24MAC602 memory chip interfaced to an Atmega128rfa1 MCU over the Two wire interface. I tried to modify the I2C master drivers which are available for other platforms to suit my need. However, I wasn't able to carry out these modifications successfully as the program stopped responding as soon as the slave address was written to the twi bus with Write flag set. I failed to uncover the underlying reasons for the same.
As Contiki OS is quite popular, i thought someone might have already come up with contiki specific libraries for reading writing over TWI interface for Atmega128rfa1 MCU. If so, please provide pointers to the twi drivers or documentation for the same, or suggest factors that should be considered for developing such drivers. Thank you.
If you don't have any luck finding/creating a driver for the TWI peripheral, you might consider emulating it by configuring the SDA/SCL pins as general I/O and then implementing the TWI protocol yourself. If you're just doing a one-time read of a chip ID then speed probably isn't a big concern, so this could work if you get desperate. Google should throw up a few examples of emulated TWI.
Cheers...
I understand that it stands for Hardware Abstraction Layer but what exactly does it do ? Is it designed for high level languages like VB to communicate with the hardware ? What about the IN/OUT instructions do these instructions call into a HAL routine or do they communicate directly with the hardware's device driver via the I/O manager ?
Thanks in advance
I understand that it stands for Hardware Abstraction Layer but what exactly does it do ?
It's essentially the "non-portable" part of the NT kernel, provided as a seperate module so that NT could be ported to multiple processor architectures. Example: interrupt routing.
Is it designed for high level languages like VB to communicate with the hardware ?
No. It is meant as support routines for the NT kernel. If you are coding in user mode (as you would be as in high level languages like VB) you have no need to know it exists.
What about the IN/OUT instructions do these instructions call into a HAL routine or do they communicate directly with the hardware's device driver via the I/O manager ?
When you use the the in and out instructions, this is talking directly to the CPU. This is entirely unrelated to the NT kernel topics you are discussing. There is no HAL there. There is no NT I/O manager. These instructions are what the x86 instruction set provides for talking to devices through an I/O address.
The HAL is designed to 'abstract' details of the hardware away from the operating system (It is a kernel component).
It provides routines to kernel for dealing with machine specific instructions (afaik includes handling of things like AVX state preservation through a context switch) as well as other details such as interrupts (Google 'Interrupts IDT' (no quotes))
Note that the HAL does not fully sit below the kernel, as the kernel still talks directly to hardware in some places, however the HAL also depends on the kernel for many of its functions (as such they often come in matched 'sets')
http://support.microsoft.com/kb/99588
The HAL is like an isolation layer, it means that things on either side of the layer can change, and (theoretically) it will have no effect on the other side.
This means various different kinds of hardware can be below the HAL, and the software that calls through the HAL doesn't care.
I am working on an STM32f2xx processor eval board, with LIS3lv02dh accelerometer chipset.
I have been able able to program the accelerometer to wakeup the processor on interrupt based on the Threshold level change in accelerometer, but how do I register for events during wakeup.
How do I register an accelerometer sensor handler so that when an interrupt occurs, the application code is notified.
You need to read and understand the STM32f2xx User Reference Manual. You have no OS (I guess) and generic Google searches will not help you; the problem is very specific to the parts you are using.
The STM32F2xxx Standard Peripheral Library (downloadable from ST's site) contains numerous examples for all peripherals including I believe using wake-up sources.
If the accelerometer is included on the evaluation board, I would imagine that it includes example code or a support library that may help.