- 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