- Embedded Software Engineer @ National Instruments
- Work on the USRP
- Very small team, focus on open-source
- Try to work upstream first (U-Boot, Kernel, ...)
Also find slides at http://mfischer.github.io/fosdem17-slides
/** * List of enabled tasks in the priority order * * The first one has the lowest priority. * * For each task, use the macro TASK(n, r, d, s) where : * 'n' in the name of the task * 'r' in the main routine of the task * 'd' in an opaque parameter passed to the routine at startup * 's' is the stack size in bytes; must be a multiple of 8 */ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(CHARGER, charger_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
static void power_lid_change(void) { task_wake(TASK_ID_CHIPSET); } DECLARE_HOOK(HOOK_LID_CHANGE, power_lid_change, HOOK_PRIO_DEFAULT);
hook_notify(HOOK_LID_CHANGE);
static int cc_pwm_duty(int argc, char *argv) { /* parse, act, etc */ return EC_RES_SUCCESS; } DECLARE_CONSOLE_COMMAND(pwmduty, cc_pwm_duty, "[channel [| -1=disable] | [raw ]]", "Get/set PWM duty cycles ");
struct ec_host_request { uint8_t struct_version; uint8_t checksum; uint16_t command; uint8_t command_version; uint8_t reserved; uint16_t data_len; } __packed;On I2C gets wrapped to do v3 structs over v2:
struct ec_i2c_host_request { uint8_t command_protocol; struct ec_host_request; } __packed;
int temp_sensor_command_get_info(struct host_cmd_handler_args *args) { const struct ec_params_temp_sensor_get_info *p = args->params; struct ec_response_temp_sensor_get_info *r = args->response; int id = p->id; if (id >= TEMP_SENSOR_COUNT) return EC_RES_ERROR; strzcpy(r->sensor_name, temp_sensors[id].name, sizeof(r->sensor_name)); r->sensor_type = temp_sensors[id].type; args->response_size = sizeof(*r); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_TEMP_SENSOR_GET_INFO, temp_sensor_command_get_info, EC_VER_MASK(0));
GPIO(WP_L, PIN(B, 4), GPIO_INPUT) [...] GPIO(BAT_LED_RED, PIN(B, 11), GPIO_OUT_HIGH) [...] GPIO(EC_INT_L, PIN(B, 9), GPIO_OUT_LOW)API calls: gpio_get_level() / gpio_set_level()
GPIO_INT(SPI1_NSS, PIN(A, 4), GPIO_INT_BOTH, spi_event) GPIO_INT(AC_PRESENT, PIN(C, 6), GPIO_INT_BOTH | GPIO_PULL_UP, extpower_interrupt) GPIO_INT(SUSPEND_L, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt)
ALTERNATE(PIN_MASK(A, 0x00f0), 0, MODULE_SPI, 0) ALTERNATE(PIN_MASK(A, 0x0600), 1, MODULE_UART, 0) ALTERNATE(PIN_MASK(B, 0x00c0), 1, MODULE_I2C, 0)
UNIMPLEMENTED(WP_L) UNIMPLEMENTED(LED_BAT)
case POWER_S0: if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown || !(power_get_signals() & IN_SUSPEND_DEASSERTED)) return POWER_S0S3; [...] if (power_wait_signals_timeout(IN_PGOOD_AP | IN_PGOOD_SYS, PGOOD_AP_DEBOUNCE_TIMEOUT) == EC_ERROR_TIMEOUT) return POWER_S0S3;
&i2c0 { ec: embedded-controller@1e { reg = <0x1e>; compatible = "google,chromium-ec-i2c"; interrupts = <14 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpio0>; wakeup-source; }; };
&spi0 { ec: embedded-controller@0 { reg = <0x0>; compatible = "google,cros-ec-spi"; interrupts = <14 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpio0>; wakeup-source; }; };
[mfischer@chromebook]$ tree /sys/class/chromeos/cros_ec /sys/class/chromeos/cros_ec |-- dev |-- device -> ../../../cros-ec-ctl.0.auto |-- flashinfo |-- lightbar |-- power | |-- autosuspend_delay_ms | |-- control | |-- runtime_active_time | |-- runtime_status | `-- runtime_suspended_time |-- reboot |-- subsystem -> ../../../../../../../../../class/chromeos |-- uevent |-- vbc `-- version
Get in touch