5.3.1.2.2. sys_cfg, configuring devices

The resources (GPIOs, DMA, etc.) reconfiguration request is done by the sys_cfg() syscall family.

5.3.1.2.2.1. sys_cfg(CFG_GPIO_SET)

GPIOs are not directly mapped in the task’s memory. As a consequence, setting the GPIO output value is done using a syscall. The GPIO must be registered as output for the syscall to succeed. Only the GPIO kref is needed by this syscall, see the sys_init(INIT_DEVACCESS) explanations about kref for further details.

Setting an output GPIO is done with the following API:

e_syscall_ret sys_cfg(CFG_GPIO_SET, uint8_t gpioref, uint8_t value);

The value set is the third argument.

Important

The GPIO to set must have been previously declared as output in the initialization phase.

5.3.1.2.2.2. sys_cfg(CFG_GPIO_GET)

Getting a GPIO value for a GPIO configured in input mode is done using a syscall. Only the GPIO kref is needed by this syscall, see the sys_init(INIT_DEVACCESS) explanations about kref for further details.

Getting an input value of a GPIO is done with the following API:

e_syscall_ret sys_cfg(CFG_GPIO_GET, uint8_t gpioref, uint8_t *val);

The value read is put in the third argument.

Important

The GPIO queried must have been previously declared as input in the initialization phase.

5.3.1.2.2.3. sys_cfg(CFG_GPIO_UNLOCK_EXTI)

Note

Synchronous syscall, executable in ISR mode

There are times when external interrupts may:
  • Arise only one time and need to be muted voluntarily for a given amount of time
  • Be unstable and generate uncontrolled bursts, when the external IP is not clean and has hardware bugs

For these two cases, the EwoK kernel supports a specific GPIO configuration which allows, when an EXTI interrupt is configured, to choose whether:

  • The EXTI line is masked at handler time, by the kernel. The user ISR will be executed but there will be no more EXTI interrupts pending on the interrupt line
  • The EXTI line is not masked, and the EXTI is only acknowledged. The EXTI source can continue to emit other interrupts and the userspace ISR handler will be executed for each of them

The choice is done using the exti_lock field of the gpio structure, using either:

  • GPIO_EXTI_UNLOCKED value: the EXTI line is not masked and will continue to arise when the external HW IP emits events
  • GPIO_EXTI_LOCKED value: the EXTI line is masked once the interrupt has been scheduled for beeing serviced. The userspace task needs to unmask it voluntarily using the apropriate syscall. No other EXTI will be received without unmasking.

Unmasking a given EXTI interrupt is done using the sys_cfg(CFG_GPIO_UNLOCK_EXTI) syscall. This syscall has the following API:

e_syscall_ret sys_cfg(CFG_GPIO_EXTI_UNLOCK, uint8_t gpioref);

The gpioref parameter is the kref identifier of the GPIO, like the one used in the other GPIO manipulation syscalls. Unlocking the EXTI line is a synchronous syscall.

5.3.1.2.2.4. sys_cfg(CFG_DMA_RECONF)

Note

Synchronous syscall, executable in ISR mode

DMA operations are performed by EwoK microkernel on the behalf of userspace tasks. After completion of a DMA transfert the DMA channel is disable until it is either reloaded or reconfigurated. For allowing the user to change the input/output buffers of a DMA channel, it is permittd to reconfigure part of the DMA channel information.

Only some fields of the dma_t can be reconfigured :

  • ISR handlers address
  • Input buffer address (for memory to peripheral mode)
  • Output buffer address (for peripheral to memory mode)
  • Buffer size
  • DMA mode (direct, FIFO or circular)
  • DMA priority

Reconfiguring a part of a DMA stream is done with the following API:

e_syscall_ret sys_cfg(CFG_DMA_RECONF, dma_t*dma, dma_reconf_mask_t
reconfmask);

The mask parameter allows the user to specify which field(s) need(s) to be reconfigured.

As these fields are a part of the dma_t structure (see Ewok kernel API technical reference documentation), the syscall requires this entire structure.

Hint

The easiest way to use this syscall is to keep the dma_t structure used during the initialization phase and to update it during the nominal phase

Important

The DMA that needs to be reconfigured must have been previously declared in the initialization phase.

5.3.1.2.2.5. sys_cfg(CFG_DMA_RELOAD)

Note

Synchronous syscall, executable in ISR mode

When a DMA tranfert is finished, the corresponding DMA channel is disable until it is either reloaded or reconfigurated. A reload can be performed when the DMA controller is requested to redo exactly the same action, without any modification of the DMA channel properties. Reloading a DMA channel is faster than reconfiguring it. The kernel only needs to identify the DMA controller and stream, and does not need a whole DMA structure. The task can then use only the id field of the dma_t structure.

Reloading a DMA stream is done with the following API:

e_syscall_ret sys_cfg(CFG_DMA_RELOAD, uint32_t dma_id);

Important

The DMA that needs to be reloaded must have been previously declared in the initialization phase.

5.3.1.2.2.6. sys_cfg(CFG_DMA_DISABLE)

Note

Synchronous syscall, executable in ISR mode

It is possible to disable a DMA stream. In this case, the DMA channel is stopped and can be re-enabled by calling one of sys_cfg(CFG_DMA_RELOAD) or sys_cfg(CFG_DMA_RECONF) syscalls.

This is useful for DMA streams in circular mode, as they never stop unless the software asks them to.

Disabling a DMA stream is done with the following API:

e_syscall_ret sys_cfg(CFG_DMA_DISABLE, uint32_t dma_id);

Important

The DMA that needs to be disabled must have been previously declared in the initialization phase.

5.3.1.2.2.7. sys_cfg(CFG_DEV_MAP)

Note

Synchronous syscall, executable only in main thread mode

Ewok Microkernel allows a task to map only a restricted number of devices at a time. Voluntary mapped devices permit to map, configure and unmap in a task more than the maximum number of concurrently mapped devices. It also allows us to avoid mapping devices whose concurrent mapping is dangerous (e.g. concatenated mappings).

It is possible to declare a device as voluntary mapped (field map_mode of the device_t structure. This field can be set to the following values:

  • DEV_MAP_AUTO
  • DEV_MAP_VOLUNTARY

When using DEV_MAP_AUTO, the device is automatically mapped in the task address space when finishing the initialization phase, and is kept mapped until the end of the task life-cycle.

When using DEV_MAP_VOLUNTARY, the device is not mapped by the kernel and the task has to map the device itself (later in the life-cycle). In that case, the device is mapped using this very syscall.

Mapping a device is done using the device id, hosted in the id field of the device_t structure, which is set by the kernel at registration time.

Mapping a device is done with the following API:

e_syscall_ret sys_cfg(CFG_DEV_MAP, uint8_t dev_id);

Important

Declaring a voluntary mapped device requires a specific permission: PERM_RES_MEM_DMAP

Note

Mapping a device requires a call to the scheduler, in order to reconfigure the MPU, this action is costly

5.3.1.2.2.8. sys_cfg(CFG_DEV_UNMAP)

Note

Synchronous syscall, executable only in main thread mode

When using DEV_MAP_VOLUNTARY, a previously voluntary mapped device can be unmapped by the task. Unmapping a device frees the corresponding MPU slot, this is useful e.g. when the task requires more than the maximum number of concurrently devices.

Important

While the device is configured, device’s ISR still maps the device, even if it is unmapped from the main thread

Important

Unmapping a device does not mean disabling it, the hardware device still works and emits IRQs that are handled by the task’s registered ISR. It is the task’s responsibility to properly disable the device before unammping it if necessary

Note

Unmapping a device requires a call to the scheduler, in order to reconfigure the MPU, this action is costly

Unmapping a device is done using the device id, stored in the id field of the device_t structure, which is set by the kernel at registration time.

Unmapping a device is done with the following API:

e_syscall_ret sys_cfg(CFG_DEV_UNMAP, uint8_t dev_id);

5.3.1.2.2.9. sys_cfg(CFG_DEV_RELEASE)

Note

Synchronous syscall, executable only in main thread mode

A task may want to revoke its accesses to a given device. This can be done by requesting the kernel to release the device using its device descriptor. The device is then fully deactivated (including associated RCC clock and interrupts) and fully removed from the task’s context.

Warning

This action cannot be undone. The device is released until reboot

A released device shall never be allocated by another task. This can only happen if the device is released by a given task before another task has finished its initialization phase.

Danger

You should not interleave nominal and initializing phases between tasks to avoid potential unwanted device reallocation. Take care to synchronize init sequences correctly. The kernel does not clear the device registers at release time

Releasing a device is done with the following API:

e_syscall_ret sys_cfg(CFG_DEV_RELEASE, uint8_t dev_id);