Tagged with picoos

Pico]OS μ-layer filesystem API

I have been using two different approaches to store files in my embedded projects. First is the excellent FatFs module from elm-chan.org, second is a simple solution for read-only files using file2c-generated string tables in flash memory.

Although both these solutions work OK for code that I have written myself, the non-standard API is a problem if I would like to integrate code from other projects. Third-party code typically relies on stdio or unix-style API for file access. My solution to this was to write a slim uosFile -layer, which provides:

  • Simple API that can be wrapped into newlib system calls
  • File descriptor management for various modules
  • Support for multiple, different file systems in same system mounted at directories I want
  • Routing of API calls to file system modules based on mount point.

microfileAPI contains functions like uosFileOpen, uosFileClose & uosFileRead. On platforms that use newlib as runtime library (like Arm environments for example), these are used inside _open, _close & _read system calls so they are usable from standard stdio functions. Platforms that use something else than newlib might required different steps to get the big picture working.

Library tries to be modular. Calls between layers are mostly done via structures containing C function pointers, which should make it easy to add for example new file systems: just provide a mount function and UosFile_I & UosFS_I structures. Same idea applies also to disk layer.

As most filesystem implementations require some kind of system to manage structures related to open files, library offers “bittab” structure with some related API calls & macros. A “bittab” is just a struct array of given size, but it contains also a bitmap table. Each bit in bitmap table tells if it’s associated slot in struct array is allocated or not. Access to bitmap is protected by mutex, so it is safe to use this also with multiple active tasks.

There is also a simple layer for using MMC/SD cards with Fat FS. The code is based on examples that are available from same elm-chan.org site as Fat FS itself. To use this layer, application needs to provide SPI methods for the chip that is being used. This is done by providing a UosMmcDisk structure with correct values in UosMmcSpi_I function pointers and calling uosAddDisk to register it. An example for such setup can be found in my python-test project (see test.c and mmcspi.c).

Reference manual for library is available here.

Pic32 port for Pico]OS

When I started toying with microcontrollers several years ago, I kind of ignored Microchip’s PIC family completely. I think it was 8-bit stuff only those days. Although having some history with 8-bit Z80 in my early years, my real job with 32/64-bit unix servers made me look for something “bigger”, which lead me to the LPC2000 series from Philips (NXP today).

But when NPX released some Arm Cortex-M0 chips in hobbyist-friendly DIP packages they made me look around what else might be available in similar packages. I knew about PIC32MX family from Microchip before, but wasn’t really interested in it, because I thought that Arm Cortex-M stuff would dominate the world (maybe it will, maybe not). But breadboarding is really nice during prototyping and PIC32MX chips in DIP packages have much more flash and ram than those offered by NXP. (more…)

New storage temperature monitoring

med_ek-tm4c1294xl_clp-top-no-shadow-low_resOld arm board I was using to monitor my storage temperature broke. As I didn’t have any similar boards in my piles any more, I decided that this would be a great opportunity to try something more modern instead. New board should be using a Cortex-M3/M4 CPU, have ethernet controller on board and a few GPIO pins for 1-wire interface. At the end I had two choices: either Olimex STM32-E407 or Texas instruments Tiva Connected Launchpad.

As I really liked TI’s stuff on MSP430 microcontrollers before I decided to try Tiva launchpad.(Olimex does’t offer TI Cortex-M4 boards currently)

I had earlier ported Pico]OS to Tiva Launchpad, but I still had some problems in getting simple blink-a-led stuff running. I finally found out that chip on this board requires different clock setup than the one on simpler launchpad (one must call SysCtlClockFreqSet instead of SysCtlClockSet & SysCtlClockGet). The basic uIP driver for ethernet was provided as an example with tivaware and it was very easy to adapt it from there into picoos-net library.

I refactored by existing sensor-web project quite heavily by moving all board-specific stuff into separate subdirectories, hoping that project wouldn’t look like a big mess after adding new board (it now supports old Olimex LPC-E2129 arm7 board, Tiva launchpad and unix for testing). As Tiva board has more RAM than old board, it was possible to allow more concurrent tcp/ip connections, which makes the web browser interface to work a lot better than with just 2 connections.

I put the board into plastic box today and moved it into storage room. Temperature trends from it are available here.


Wifi for picoos-net & uIP

Picoos-net library has been lacking support for Wifi networks and I have been trying to figure out how to implement it.

I would like to run the network stack on the microcontroller along with my application so I could keep on using APIs I’m familiar with. This rules out modules that have built-in tcp/ip networking. However, writing whole Wifi stack would be a huge task and resulting library might be too big for some microcontrollers I have been using. So this rules out cheap usb-stick style approach.

hlk-rm04Microchip has a nice Wifi module, but documentation for it is not publicly available and their own network stack is limited (by license) for use with their own microcontrollers only.

Broadcom seems to have nice modules also (Wiced) and they seem to provide some kind of SDK, which might make integration of modules easier.


BSD sockets for uIP / picoos-net

When I wrote the “native” picoos-net socket API I focused mostly on simplicity and efficiency to avoid adding too much weight to uIP. Although this layer has worked well for me, it is incompatible with BSD socket API available on many platforms. Incompatibility makes re-using code from other environments like lwIP or unix/linux (or even Texas Instruments CC3000 chip) difficult. Because I wanted to use some of my Pico]OS stuff with lwIP or CC3000 also, I decided to add a simple BSD socket layer to picoos-net library.

It contains currently following functions:

int net_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int net_bind(int s, const struct sockaddr *name, socklen_t namelen);
int net_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
int net_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
int net_close(int s);
int net_connect(int s, const struct sockaddr *name, socklen_t namelen);
int net_listen(int s, int backlog);
int net_recv(int s, void *mem, size_t len, int flags);
int net_send(int s, const void *dataptr, size_t size, int flags);
int net_socket(int domain, int type, int protocol);
int net_read(int s, void *mem, size_t len);
int net_write(int s, const void *dataptr, size_t size);

Library includes similar compatibility system like lwIP has for standard BSD socket api:

  • if NETCFG_COMPAT_SOCKETS is defined as 1 then defines for standard BSD socket functions are added to translate calls to net_* -functions, ie. accept() is defined as net_accept.
  • If NETCFG_POSIX_SOCKETS_IO_NAMES is defined as 1 then defines for read, write and close functions are also added.

setsockopt options are mostly ignored, however SO_RCVTIMEO can be used to set read timeout.