Posted  by 

Zephyr USB Devices Driver

  1. Zephyr Usb Devices Driver Downloads
  2. Zephyr Usb Devices Driver Download
  3. Zephyr USB Devices Driver
  4. Zephyr Usb Devices Drivers


One of the major benefits of using Greybus is, as mentioned, the ability to reuse existing Linux device drivers to access remote devices. We can now use the opt3001 ambient light sensor in Linux to interface with a remote opt3001 device on a cc1352rsensortag over the network. First, find out which i2c device is associated with Greybus. . USB DesignWare device controller driver. The driver implements the low. level control routines to deal directly with the hardware. The Zephyr device model provides a consistent device model for configuring the drivers that are part of a system. The device model is responsible for initializing all the drivers configured into the system. Each type of driver (UART, SPI, I2C) is supported by a generic type API. Rewrites or adaptations of Zephyr's network protocol support stacks (such as MQTT, HTTP, CoAP and LWM2M, etc.) to support TLS via a setsockopt API. Standard C Memory Allocation: Built-in support was added for malloc, free, calloc, realloc, and reallocarray. The size of the memory pool which backs these allocations is determined.

This sample app demonstrates use of a USB Mass Storage driver by the Zephyrproject. This very simple driver enumerates a board with either RAM or FLASHinto an USB disk. This sample can be found undersamples/subsys/usb/mass in the Zephyr project tree.


This project requires a USB device driver, and either 16KiB of RAM or a FLASHdevice.

Building and Running¶

This sample can be built for multiple boards, some generic and somecustomized through configurations found insamples/subsys/usb/mass/boards in the Zephyr projecttree.

Generic Example¶

The selection between a RAM-based or a FLASH-based disk can be selectedusing the overlay-ram-disk.conf or the overlay-flash-disk.confoverlays. In this example we will build the sample with a RAM-baseddisk:

After you have built and flashed the sample app image to your board, plug theboard into a host device, for example, a PC running Linux.The board will be detected as shown by the Linux journalctl command:

The disk contains a simple README.TXT file with the following content:

Files can be added or removed like with a simple USB disk, of course withinthe 16KiB limit.

nrf52840dk_nrf52840 Example¶

This board configures to use the external 64 MiBi QSPI flash chip with a64 KiBy littlefs partition compatible with the one produced by thelittlefs File System Sample Application.

After you have built and flashed the sample app image to your board,connect the board’s two USB connectors (debug and nRF USB) to a hostrunning a littlefs-FUSE-capable operating system. The output to theconsole will look something like this (file system contents will bedifferent):

For information on mounting littlefs file system on Linux or FreeBSDsystems refer to the “littlefs Usage” section below.

adafruit_feather_nrf52840 Example¶

This board configures to use the external 16 MiBi QSPI flash chip with a2 MiBy FAT partition.

After you have built and flashed the sample app image to your board,connect the board’s USB connector to a host capable of mounting FATdrives. The output to the console will look something like this(file system contents will be different):

On most operating systems the drive will be automatically mounted.

littlefs Usage¶

While a FAT-based file system can be mounted by many systems automatically,mounting the littlefs file system on a Linux or FreeBSD system can beaccomplished using the littlefs-FUSE utility.

First determine the local device name from the system log, e.g.:

This shows that the block device associated with the USB drive is/dev/sdd:

This can be mounted as a file system with the following commands:

which produces this output:

lfs is a mount command and you should take care to unmount thedevice before removing the USB drive:

littlefs parameter selection¶

Be aware that the parameters passed to lfs in the exampleabove must exactly match the corresponding parameters used toinitialize the file system. The required parameters can be observedfrom the Zephyr mount log messages:

  • --read_size corresponds to the rd size and is 16;

  • --prog_size corresponds to the pr size and is 16;

  • --block_size comes from 0x1000-byteblocks and is 4096 (0x1000);

  • --block_count comes from 160x1000-byteblocks and is 16;

  • --cache_size comes from the ca size and is 64;

  • --lookahead_size comes from the la size and is 32

If any of the parameters are inconsistent between the Zephyr and Linuxspecification the file system will not mount correctly.

Zephyr OS: Adding the Atmel SAM4S Xplained

by Justin Watson 2016 Sept. 30

This is an article on adding the Atmel SAM4S Xplained board to the ZephyrOperating System. We will start with the boardcode and continue with the SoC code. Then we will look at building andinstalling the binary file “zephyr.bin”. It is recommended to have the datasheet, schematic and docs available for reference as they will be neededextensively. One of the goals is to show how to figure out what your board andSoC need in order to be added to the Zephyr OS.

  • Atmel SAM4S Xplained

First we collect all the information on the AtmelSAM4S16C and theboard Get the datasheet for the SAM4S16C. Also open up the OnlineUser Guide and theboard files. We nextcreate the board directory “atmel_sam4s_xpld” inside the directory<z/boards/>. Then we will copy the files from the directory<z/boards/arduino_due/> into the new directory <z/boards/atmel_sam4s_xpld/>.We then modify the file name for the file “arduino_due_defconfig” to“atmel_sam4s_xpld_defconfig. Then we start the modifications for our boardwith the file “atmel_sam4s_xpld_defconfig”. Now each section is a file thatwe copied from the SAM3.


We need to update all part references from SAM3 to SAM4, and all chip referencesof SAM3XAE to SAM4S16.


No change needed.


In the file “Kconfig.board” we will change the config “BOARD_ARDUINO_DUE” toBOARD_ATMEL_SAM4S_XPLD. We will also change the prompt for the bool value to“Atmel SAM4S Xplained”. The depends statement need to be updated to the SoC onthe SAM4S XPLD. This chip/soc configuration doesn’t exist yet in<z/arch/arm/soc/>. It will after we finish with the board configuration. Thechip on the SAM4S Xplained is the SAM4S16. So we change the “depends” statementto “SOC_ATMEL_SAM4S16”.


In this file we need to change the “if” statement board variable to match theboard variable we created in the file “Kconfig.board”. Change it toBOARD_ATMEL_SAM4S_XPLD. Also change the option “default” from“arduino_due” to “atmel_sam4s_xpld”.


The file “Makefile” requires no changes.


This file adds a function to the OS that sets up some pin configurationsspecific to the board. Our chip only has 3 PIOs named, A, B, and C. So allreferences in this file that have to do with D should be removed.

If you look at section 31.6.24 of the SAM4S data sheet you can see that thischip has 4 possible settings instead of 2. The SAM4S has A, B, C, and D, whilethe SAM3S only has A and B. Section 11.2 of the SAM4S data sheet has a table ofwhat the A, B, C, and D functions do for the different pins. The __PIOm (m isA, B, C, etc.) structures come from the file <z/arch/arm/soc/atmel_sam3/>,which defines a bunch of helpful structures. We will be making our own similarfile inside the directory <z/arch/arm/soc/atmel_sam4/> in the SoC section ofthis article.

Now just after all the defaults have been read we will modify the code to whatthe board has the pins connected too. We read all the settings so we have acopy. Then we modify our copy and then push the changes back.

Side question: Why do we do this instead of just changing the pins directly?

The JTAG pins are the first pin setup we come to. The code is setting the JTAGpins to 0 on the control (enable) register. On the table in 11.2 you see thatthe system setting for those pins is TDI, TDO, etc. We disable the PeripheralMux on those pins so that those pins are in the system setting. PB2 and PB3 aretied to J1 and J4 so they will be easily accessible for UART to a TTL to USBdevice. Remove the sections for the I2C and the ADC pins. We don’t need them forour board.

Side question: Why do these pins get setup in the board file and not theapplication file or not as a driver?

The Zephyr OS uses the term SoC to refer to the chip. I use the word chip andSoC interchangably throughout this file. Both terms refer to the actual chip andonly the chip. The terms do not refer to the board or the architecture.

I copied the directory <atmel_sam3/> in <z/arch/arm/soc/>. Then I renamed thenew copy to atmel_sam4.


Let’s start with the file Kconfig. Change all the parts in the file that say SAM3to SAM4.

The configuration SOC_ATMEL_SAM4_EXT_SLCK is for setting the clock to anexternal clock. The possible clock options for our chip the SAM4S16 are insection 28 of the SAM4S data sheet. The data sheet states that there are twoPLLs, PLLA and PLLB. Copy the PLLA config blocks and rename the copy toPLLB.


IRQ stands for interrupt request. The two words can be used interchangably.Configure the number of interrupt request priority bits. In section 12.8 of theSAM4S data sheet there is a bullet point that says the UIRQs have a programmablepriority from 0 to 15. The numbers 0 to 15 would require 4 bits, so set thenumber of priority bits to 4. Set the number of IRQs to 35 based on the table inthe SAM4S data sheet on page 196.

Zephyr Usb Devices Driver Downloads

Now we need to modify the configuration settingSYS_CLOCK_HW_CYCLES_PER_SEC. First we must determine how the 84 MHz wasfound on the Arduino Due. Then we can follow the same process to determine theclock for the Atmel SAM4S. The config SOC_ATMEL_SAM3_PLLA_MULA is set to0x06 and the SOC_ATMEL_SAM3_PLLA_DIVA is set to 0x01. In section 27.6.1 wefind the same equation in “help” section of the configuration. The equation is(MAINCK * (MULA + 1) / DIVA). The Arduino Due schematic shows a 12 MHz clockconnected to Xin and Xout. Solving that equation with the settings above we get:

This means the default settigns for MULA and DIVA in this PLL equation result inthe SYS_CLOCK_HW_CYCLES_PER_SEC value. Now doing the same analysis for theSAM4S Xplained board we can find the value we should set ourSYS_CLOCK_HW_CYCLES_PER_SEC to. The SAM4S Xplained board also has a 12 MHzconnected to Xin and Xout. The SAM4S has 2 PLLs though. This can be seen inFigure 29-2 page 517 of the SAM4S data sheet. We should also note that the clocksystem on both processors have a prescaler for the master clock (section 28.3,page 527, SAM4S data sheet). There is no Zephyr OS configuration for the masterclock prescaler so it is left at it default of 1. The master clock prescaler isconfigured in the file “soc.c”. We can verify that it is at its default value bylooking at the code in the section with the comment “Setup Prescaler”.

Remove the I2C block because we don’t need it to get the board running. We canadd it back in later. Remove the configuration setting GPIO_ATMEL_SAM4_PORTDbecause there is no PORT D on the SAM4S.


Change the processor name to 4S16 from 3X8E on the lines for “config” and“bool.” Then in the setting “select” we must change the CPU_CORTEX_M3 toCPU_CORTEX_M4 because the SAM4S16 processor is a Cortex M4. This can beverified by looking in the data sheet section 12. Changing this to M4 might alsorequire adding more information to the architecture code for the M4. We can lookinto this later by looking for where CPU_CORTEX_M3 is defined and used. Nextchange SOC_ATMEL_SAM3 to SOC_ATMEL_SAM4. The next select statement is forSYS_POWER_LOW_POWER_STATE_SUPPORTED. We need to look for the place thatthis is defined and used. We also need to check the data sheet to see if it issupported.


This file includes <z/arch/arm/cortex_m/script/linker.ld>. This includedfile “linker.ld” uses definitions to describe where code and text should go.Since we have been changing definitions to match our processor from theSAM3X8E our settings will be used and this ensures that we have thecorrect definitions defined.


We will leave this file alone because we aren’t adding any new source files.

File soc.c

This file will require a lot of changes. It will also help us understand how alot of the settings in the other files are used. We may end up changing some ofthem in this section. Otherwise, these changes will not make sense. All sectionsof the code need to be compared between the data sheets for the SAM3 and SAM4.

Let’s start with the first “config” block CONFIG_SOC_ATMEL_SAM4_EXT_SLCK.Our chip has this same setup as the SAM3, so we will leave the block in. We alsohave this in our kernel configuration file Kconfig. This code allows the SlowClock to be set to use an external clock. We find that the Supply ControllerSUPC allows this in the SAM3 so we will check the same section of the SAM4 datasheet. The Supply Controller Control Register has similar bits. We must alsocheck the Supply Controller structure’s start address. On the SAM3 it can beseen that the supply controller start address is 0x400E1A10. This is verified bylooking at the Supply Controller Control Register’s address in the data sheetand table 16.5.2. The control register is offset 0 so the control register marksthe beginning of the SUPC registers. By investigating the same section of theSAM4 data sheet, which is now section 18. We see that in table 18-2 the SupplyController Control Register is offset 0 and thus marks the beginning of theSupply Controller structure defined in the file soc.h. The Supply ControllerControl Register on the SAM4 is at address 0x400E1410. So change thatSUPC_ADDR in our SAM4 file soc.h.

The next block to look at is the config blockCONFIG_SOC_ATMEL_SAM3_EXT_MAINCK. Here we will do the same process with thelast “config” block and ensure we have the correct addresses and a similarregister structure as the SAM3. The PMC is Power Management Controller section

  1. There we see Table 29-3 shows offset 0 is the System Clock Enable Register.The System Clock Enable Register is located at address 0x400E0400. Update thefile soc.h with the new address.

Now we are at the part of the file that sets up PLLA as the master clock. Weshould continue to use this because it is already there and tested with the SAM3.At this point there is no good reason to not use PLLA and the defaultconfiguration settings. This whole block uses the PMC so we know we have theregister addresses correct because we set them up earlier while modifying thisfile. You should read the section on changing clocks to improve yourunderstanding of what this code is doing.

Next is the function “atmel_sam3_init”. Change the name to “atmel_sam4_init”.First thing we see that we can configure is the use ofCONFIG_FLASH_BASE_ADDRESS we did this in the Kconfig file so follow the sameprocess.

Next is the setup of the flash controller. Go to the SAM4 data sheet section 20on the “Enhanced Embedded Flash Controller EEFC.” There we can look up what the“fm” register is. There is one addressfor bank 0 and one for bank 1. We need to check these in our soc.h file andupdate them if they are different than the SAM3. They aren’t different so noupdate is needed. This code is changing the flash wait state. We shouldleave this alone since we are matching clocks and the Zephyr team probably didsome checking against a real Arudino Due. EEFC information is in section 20.5.1page 371 of the SAM4S data sheet.

Now we come to a handful of SCB functions. SCB stands for System Control Block.In the SAM4 data sheet the System Control Block is found in section 12.9. Givethis a read sometime so you are more familiar with what those functions aredoing at boot.

Next we see the call to the clock_init function we modified earlier. We canleave this alone because we already checked it.

Next we see the watchdog setup, which just disables the watchdog. We need toupdate it’s address if it different than the SAM3. Steps to do that are similarto those above for other register addresses. The Watchdog Timer is in section 17of the SAM4 data sheet.

We will finish this file by updating the call to “atmel_sam3_init” to“atmel_sam4_init.”

File soc.h

First we see the “#ifndef” and “#define”. Change those to SAM4 from SAM3.

Zephyr Usb Devices Driver Download

Next we see the IRQ numbers. The IRQ information can be found in section 11Peripherals in table 11-1. Compare them and add those IRQs that don’t exist inthe table and modify those that have a different number from the number in theSAM3. For example there are now two UARTs.

Now we can update the PID definitions. First copy and pase the IRQs and changethe name IRQ to PID. Now go to section 29.17. of the SAM4 data sheet. Noticethere are two peripheral clock enable registers, 0 and 1. We only needdefinitions for those PIDs listed in either of those registers.

Next is the PMC address, which we alrady set when updating the file soc.c.

We also notice that there is only a definition for PLLA in the soc.h file. Weneed to copy this PLL code block and change the variable names accordingly forPLLB.

Zephyr USB Devices Driver

Now we have the UART to update. There are also now two UARTs. We saw this whenmaking the IRQ definitions. UART table of registers is in Table 35-4 page 768.First register is the Control Register. Control Register for UART0 is located at0x400E0600 and the address for UART1 is 0x400E0800. Update the UART section inthe file soc.h.

We already updated the EEFC when we updated the soc.c file.

The Peripheral DMA Controller is next for verification and is in chapter 27.These read as if they are part of the Peripheral Transter Control Registerbased on the name on page 27.6.9.

PIO Controllers are next for verification. PIO is in chapter 31 and the table is31-5 on page 585. Offset 0 is the PIO Enable Register. Looking at the PIO enableregister we can see there is only PIOA, PIOB, and PIOC. The rest can be removed.

The SUPC address was updated in the “soc.c” file.

The Two-wire Interface TWI is in section 34. Offset 0 is the control register.Looking at the control register we see the address for TWI0 and TWI1. Updatetheir definitions.

The Watchdog Timer WDT address was updated in the “soc.c” file.

Below that are where the addresses are applied to the structures that providean easier interface. We can remove the PIOD, PIOE, and PIOF structures. Wewill leave the rest because they do exist and are used in the soc.c file.


This file contains a bunch of structures that make it easier and more organizedwhen working with the SOC registers. I went through each of these and verifiedthat their offsets are correct. I suggest you do the same. We have alreadyglanced at the chapter and table for all the registers listed in the“soc_registers.h” file.

Take a look at the file <z/arch/arm/defconfig>. We have several settings set to“yes” by default that we may need to create a driver for. We should also take alook at the “defconfig” file in our “atmel_sam4s_xpld” directory for otheroptions with a “yes” as their setting. Specifically we should look at theoptions that we haven’t seen used in any of the files in the board’s directoryor the SoC’s directory. In that file we see:

Here are the configuration options again with the file we saw them used in.

Of these we have not seen the following in any files we have worked on.

So where are they used? Using ack (a grep like tool) we can search for thestring in the Zephyr OS directories. Let’s first look at CORTEX_M_SYSTICK. Itis used in the file <z/drivers/timer/Makefile>. The Makefile adds the file“cortex_m_systick.o” if this option is a yes. Let’s look at that file. It lookslike it implements a driver for the Cortex-M systick device. That sounds like itworks for Cortex-M3 (SAM3) and Cortex-M4 (SAM4). This driver “provides thestandard kernel ‘system clock driver’ interfaces (cortex_m_systick.c).” Wheredoes the register address get configured for the __scs.systick? It looks like itshould be defined in scs.c under <z/arch/arm/cortex_m>. This file states thatthe linker places __scs at 0xe000e000. Luckily both the SAM3 and SAM4 have thesame register addresses for the systick. So we will leave this for now unlessthere is an error the first time we try to bring the board up.

Next setting we will look at is CONFIG_CONSOLE. The Kconfig item CONSOLE isused and defined in the file <z/drivers/console/Kconfig>. The config optionCONSOLE allows us to select CONSOLE_UART_CONSOLE in the kernel configurationsystem. It doesn’t do anything else. Looking at the other settings in this filewe see the option UART_CONSOLE_ON_DEV_NAME. It is currently set to“UART_0”. We need to change this to “UART_1” because our available UART is thesecond UART with the label UART1 in the data sheet. So lets add this line to our“atmel_sam4s_xpld_defconfig” file with the value “UART_1”.

In a later paragraph we will see that we will be updating the serial driver forour board and SoC to match the value of the CONFIG_UART_CONSOLE_ON_DEV_NAMEvariable.

Let’s take a look at CONFIG_UART_CONSOLE. Searching for CONFIG_UART_CONSOLEshows that it is used in the file <z/drivers/console/Makefile>. It adds the“uart_console.o” to the list of build items. Looking at the source comments,the file “uart_console.c” looks to be a generic console handler over UART. Wedo not need to make any changes or another version to have it work with the SAM4.

Let’s consider the next option CONFIG_SERIAL. This option can be found in thefile <z/drivers/serial/Kconfig>. At the bottom of the file we see Kconfig filesfor multiple SoCs. Take a look at the file “Kconfig.atmel_sam3.” This filedefines many variables that will get used in the source. Read this file and takea note on what they do. We need to make a new file for the Atmel SAM4 we areworking on. We also need to add this file to the Kconfig file in the directory<z/drivers/serial>. In the new file “Kconfig.atmel_sam4” Change all the wordsthat say SAM3 to SAM4. Also review section 35, UART of the SAM4 data sheet.Update the “help” block on the menuconfig “UART_ATMEL_SAM4”. We now have 2UARTs. Both UARTs only have Tx and Rx pins, no flow control capabilities. Alsonote the UART_ATMEL_SAM4_CLK_FREQ config option. We set this in<z/arch/arm/soc/Kconfig.defconfig>. We also need to update the variableUART_ATMEL_SAM4_NAME to match what we set for the config optionCONFIG_UART_CONSOLE_ON_DEV_NAME. The value should be “UART_1” instead of“UART_0”.

Now we will look at the file “uart_atmel_sam3.c.” We need to make a copy ofthe file “uart_atmel_sam3.c” and call it “uart_atmel_sam4.c.” Renameeverything that is “SAM3” to “SAM4.” Recall that in<z/arch/arm/soc/atmel_sam4/soc.h> we updated our UART_ADDR variable. We madea definition for UART0 and UART1 and set the appropriate address. Find theUART_ADDR in the uart_atmel_sam4.c file and update it to UART1_ADDR. UART1are the available UART pins on the J1 header of the board. We need to updateparts of the function “uart_sam4_init”. We need to change the PMC so thatUART1 clock is enabled. We also need to make sure the PIO is disabled for ourUART pins, and then we need to make sure our MUX is set for Peripheral A.

Also update the Makefile. Copy the line that adds the object file“uart_atmel_sam3.o.” Change it to SAM4.

Now we have adderssed all the configuration options in arduino_due_defconfigfile. We should be good to go with compiling.

We are going to compile one of the sample application for our board. Let’s usethe hello-world application at <z/samples/hello_world/microkernel>. Open upthe Getting Started Guide, and look at the section “Building a SampleApplication.” It has the steps to build an application. Follow the steps inthis document. There is a paragraph that says “The above invocation of makewill build the hello_world sample application using the default settingsdefined in the application’s Makefile.” We need to run the command:

To remove old code that might be there we must use the following command tocompile:

Zephyr Usb Devices Drivers

Specifically the command make clean clears out all the old build files. Thecommand time measures how long the build takes and outputs it at the end.

Now we have a file called “zephyr.elf” and “zephyr.bin”. We need to get one ofthem on the hardware. The available connections on the board are the USB debugport and the JTAG port. We can find on theAtmel Online User Guide that the debug USB port is J-LinkOB. Looking through the site[] we find the software page and we find the J-Link OB page. It is assumed that since that second microcontroller was implementingJ-Link that we just need the software to use it in Linux. Download the J-LinkLinux “.tgz” or “.deb” and install J-Link. We should install the “.deb” becausethat will also install the udev rules. Open up the document with the name“UM08001_JLink.pdf.” The file is in the directory<JLink_Linux_V610c_x86_64/Doc/> of the J-Link download. We now go tosection 5.1 and read about connecting to a device and the proper steps. Once wehave JLinkExe running then go to section 6. Then we go to section 6.4.5 J-LinkCommander and read. These are the minimum commands required to connect an loadour file “zephyr.bin” to the device:

ELF format filesare the default output from building any program with gcc. If we did not have a“.bin” file for JLinkExe we would have to create one using the program“objcopy”. The program “objcopy” takes an ELF and can create several differentother files from it. We would need to change the file into an Intel Hex filebecause that is what J-Link expects. We will use the program “objcopy”, whichcomes with the GNU binutils package. Here is an example of turning the“zephyr.elf” file into a “zephyr.bin” file for J-Link.

Now we need to hook up a USB to UART on our board. We will grab our TTL to USBdevice and connect the TX pin on the RX pin on the board. We will also connectthe RX pin from the TTL to USB device to the RX pin on the board. We candetermine which pins and header those are on the board by looking at theschematic. The section SAM4S Xplained I/O Expansion Header J1shows that pins 3 and 4 are what we are looking for. At this point we should seeour program output on our serial device. That would confirm we added the AtmelSAM4S Xplained as a board to the Zephyr OS.


To view all the code changes that were made in this article go to the project ”zephyr_atmel_sam4s_xpld”.There is only one branch called “atmel_sam4s_xpld”. Look at the commits madeby me Sept. 24 to Oct. 2.